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

Commit e6111852 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

DO NOT MERGE: Audio HAL: do not test input stream if no Built-in mic on primary

The test used to always test input stream, assuming that all devices had
built-in device on the primary Module. Nevertheless, although uncommon,
the mic could be on any module or even not exist.

This patch makes sure that the input stream tests are only run if there
is a Built-in mic on the primary module.

This patch also fixes GetMicrophonesTest to accept NOT_SUPPORTED
result.

This patch is specific for Android P. Later versions already have
these fixes.

Bug: 114303641
Test: atest VtsHalAudioV4_0TargetTest
      on device with a built-in mic and on a device w/o

Change-Id: I7289724e5a73c1ffd09ca990f681844bdc8f6b3e
parent b0a0799f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -34,6 +34,10 @@ namespace utility {
::testing::AssertionResult validateXml(const char* xmlFilePathExpr, const char* xsdFilePathExpr,
                                       const char* xmlFilePath, const char* xsdFilePath);

std::vector<std::string> findValidXmlFiles(const char* xsdFilePathExpr,
        const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath,
        std::vector<std::string>* errors = nullptr);

/** Helper gtest ASSERT to test XML validity against an XSD. */
#define ASSERT_VALID_XML(xmlFilePath, xsdFilePath)                                      \
    ASSERT_PRED_FORMAT2(::android::hardware::audio::common::test::utility::validateXml, \
@@ -78,6 +82,9 @@ template <bool atLeastOneRequired = true>
        ::android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>, \
        xmlFileName, xmlFileLocations, xsdFilePath)

::testing::AssertionResult isNonEmptyXpath(
        const char* xmlFilePath, const char* xpathQuery, bool* result);

}  // namespace utility
}  // namespace test
}  // namespace common
+54 −9
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <libxml/xmlschemastypes.h>
#define LIBXML_XINCLUDE_ENABLED
#include <libxml/xinclude.h>
#define LIBXML_XPATH_ENABLED
#include <libxml/xpath.h>

#include <memory>
#include <string>
@@ -47,6 +49,10 @@ template <>
constexpr auto xmlDeleter<xmlSchemaParserCtxt> = xmlSchemaFreeParserCtxt;
template <>
constexpr auto xmlDeleter<xmlSchemaValidCtxt> = xmlSchemaFreeValidCtxt;
template <>
constexpr auto xmlDeleter<xmlXPathContext> = xmlXPathFreeContext;
template <>
constexpr auto xmlDeleter<xmlXPathObject> = xmlXPathFreeObject;

/** @return a unique_ptr with the correct deleter for the libxml2 object. */
template <class T>
@@ -129,27 +135,37 @@ struct Libxml2Global {
    return ::testing::AssertionSuccess();
}

template <bool atLeastOneRequired>
::testing::AssertionResult validateXmlMultipleLocations(
    const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
    const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath) {
std::vector<std::string> findValidXmlFiles(
    const char* xsdFilePathExpr,
    const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath,
    std::vector<std::string>* errors) {
    using namespace std::string_literals;

    std::vector<std::string> errors;
    std::vector<std::string> foundFiles;

    for (const char* location : xmlFileLocations) {
        std::string xmlFilePath = location + "/"s + xmlFileName;
        if (access(xmlFilePath.c_str(), F_OK) != 0) {
            // If the file does not exist ignore this location and fallback on the next one
            continue;
        }
        foundFiles.push_back("    " + xmlFilePath + '\n');
        auto result = validateXml("xmlFilePath", xsdFilePathExpr, xmlFilePath.c_str(), xsdFilePath);
        if (!result) {
            errors.push_back(result.message());
            if (errors != nullptr) errors->push_back(result.message());
        } else {
            foundFiles.push_back(xmlFilePath);
        }
    }
    return foundFiles;
}

template <bool atLeastOneRequired>
::testing::AssertionResult validateXmlMultipleLocations(
    const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr,
    const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath) {
    using namespace std::string_literals;

    std::vector<std::string> errors;
    std::vector<std::string> foundFiles = findValidXmlFiles(
            xsdFilePathExpr, xmlFileName, xmlFileLocations, xsdFilePath, &errors);

    if (atLeastOneRequired && foundFiles.empty()) {
        errors.push_back("No xml file found in provided locations.\n");
@@ -175,6 +191,35 @@ template ::testing::AssertionResult validateXmlMultipleLocations<false>(const ch
                                                                        std::vector<const char*>,
                                                                        const char*);

::testing::AssertionResult isNonEmptyXpath(
        const char* xmlFilePath, const char* xpathQuery, bool* result) {
    Libxml2Global libxml2;

    auto context = [&]() {
        return std::string() + "  In: " + xmlFilePath + "\nLibxml2 errors:\n" + libxml2.getErrors();
    };

    auto doc = make_xmlUnique(xmlReadFile(xmlFilePath, nullptr, 0));
    if (doc == nullptr) {
        return ::testing::AssertionFailure() << "Failed to parse xml\n" << context();
    }
    if (xmlXIncludeProcess(doc.get()) == -1) {
        return ::testing::AssertionFailure() << "Failed to resolve xincludes in xml\n" << context();
    }
    auto xpathCtxt = make_xmlUnique(xmlXPathNewContext(doc.get()));
    if (xpathCtxt == nullptr) {
        return ::testing::AssertionFailure() << "Failed to create xpath context\n" << context();
    }
    auto xpathObj = make_xmlUnique(xmlXPathEvalExpression(BAD_CAST xpathQuery, xpathCtxt.get()));
    if (xpathObj == nullptr) {
        return ::testing::AssertionFailure() <<
                "Failed to evaluate xpath: \'" << xpathQuery << "\'\n" << context();
    }
    auto nodeSet = xpathObj.get()->nodesetval;
    *result = nodeSet ? nodeSet->nodeNr != 0 : false;
    return ::testing::AssertionSuccess();
}

}  // namespace utility
}  // namespace test
}  // namespace common
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ cc_test {
    name: "VtsHalAudioV4_0TargetTest",
    defaults: ["VtsHalTargetTestDefaults"],
    srcs: [
        "AudioPolicyConfiguration.cpp",
        "AudioPrimaryHidlHalTest.cpp",
        "ValidateAudioConfiguration.cpp"
    ],
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "AudioPolicyConfiguration.h"

const char* kAudioPolicyConfigurationXml = "audio_policy_configuration.xml";
const char* kAudioPolicyConfigurationXsd =
        "/data/local/tmp/audio_policy_configuration_V4_0.xsd";

const std::vector<const char*>& getApmConfigLocations() {
    static const std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"};
    return locations;
}
+22 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>

extern const char* kAudioPolicyConfigurationXml;
extern const char* kAudioPolicyConfigurationXsd;

const std::vector<const char*>& getApmConfigLocations();
Loading