mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 21:37:44 +00:00
Merge "DO NOT MERGE: Audio HAL: do not test input stream if no Built-in mic on primary" into pie-vts-dev
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,6 +135,28 @@ struct Libxml2Global {
|
||||
return ::testing::AssertionSuccess();
|
||||
}
|
||||
|
||||
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> 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;
|
||||
}
|
||||
auto result = validateXml("xmlFilePath", xsdFilePathExpr, xmlFilePath.c_str(), xsdFilePath);
|
||||
if (!result) {
|
||||
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,
|
||||
@@ -136,20 +164,8 @@ template <bool atLeastOneRequired>
|
||||
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());
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
@@ -18,6 +18,7 @@ cc_test {
|
||||
name: "VtsHalAudioV4_0TargetTest",
|
||||
defaults: ["VtsHalTargetTestDefaults"],
|
||||
srcs: [
|
||||
"AudioPolicyConfiguration.cpp",
|
||||
"AudioPrimaryHidlHalTest.cpp",
|
||||
"ValidateAudioConfiguration.cpp"
|
||||
],
|
||||
|
||||
26
audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp
Normal file
26
audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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
audio/core/4.0/vts/functional/AudioPolicyConfiguration.h
Normal file
22
audio/core/4.0/vts/functional/AudioPolicyConfiguration.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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();
|
||||
@@ -45,12 +45,14 @@
|
||||
|
||||
#include <common/all-versions/VersionUtils.h>
|
||||
|
||||
#include "AudioPolicyConfiguration.h"
|
||||
#include "utility/AssertOk.h"
|
||||
#include "utility/Documentation.h"
|
||||
#include "utility/EnvironmentTearDown.h"
|
||||
#define AUDIO_HAL_VERSION V4_0
|
||||
#include "utility/PrettyPrintAudioTypes.h"
|
||||
#include "utility/ReturnIn.h"
|
||||
#include "utility/ValidateXml.h"
|
||||
|
||||
using std::initializer_list;
|
||||
using std::string;
|
||||
@@ -377,8 +379,29 @@ TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
|
||||
/////////// TODO: move to the beginning of the file for easier update ////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void hasDeviceTypeInModule(
|
||||
const std::string& module, const std::string& device, bool* result) {
|
||||
const std::vector<std::string> configs = findValidXmlFiles(
|
||||
"", kAudioPolicyConfigurationXml, getApmConfigLocations(),
|
||||
kAudioPolicyConfigurationXsd);
|
||||
*result = true; // If could not get the information, run all tests
|
||||
ASSERT_EQ(1U, configs.size());
|
||||
std::string query = "/audioPolicyConfiguration/modules/module[@name=\"" + module + "\"]" +
|
||||
"/devicePorts/devicePort[@type=\"" + device + "\"]";
|
||||
ASSERT_NO_FATAL_FAILURE(isNonEmptyXpath(configs[0].c_str(), query.c_str(), result));
|
||||
}
|
||||
|
||||
class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
|
||||
public:
|
||||
static bool primaryHasMic() {
|
||||
static const bool hasMic = []() {
|
||||
bool result;
|
||||
hasDeviceTypeInModule("primary", "AUDIO_DEVICE_IN_BUILTIN_MIC", &result);
|
||||
return result;
|
||||
}();
|
||||
return hasMic;
|
||||
}
|
||||
|
||||
// Cache result ?
|
||||
static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
|
||||
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
|
||||
@@ -398,10 +421,12 @@ class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
|
||||
}
|
||||
|
||||
static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
|
||||
if (!primaryHasMic()) return {};
|
||||
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
|
||||
{AudioFormat::PCM_16_BIT});
|
||||
}
|
||||
static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
|
||||
if (!primaryHasMic()) return {};
|
||||
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
|
||||
{AudioFormat::PCM_16_BIT});
|
||||
}
|
||||
@@ -548,6 +573,10 @@ TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
|
||||
SKIP_IF_NO_DEVICE;
|
||||
hidl_vec<MicrophoneInfo> microphones;
|
||||
ASSERT_OK(device->getMicrophones(returnIn(res, microphones)));
|
||||
if (res == Result::NOT_SUPPORTED) {
|
||||
doc::partialTest("getMicrophones is not supported");
|
||||
return;
|
||||
}
|
||||
ASSERT_OK(res);
|
||||
if (microphones.size() > 0) {
|
||||
// When there is microphone on the phone, try to open an input stream
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
#include <string>
|
||||
|
||||
#include "utility/ValidateXml.h"
|
||||
#include "AudioPolicyConfiguration.h"
|
||||
|
||||
TEST(CheckConfig, audioPolicyConfigurationValidation) {
|
||||
RecordProperty("description",
|
||||
"Verify that the audio policy configuration file "
|
||||
"is valid according to the schema");
|
||||
|
||||
std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"};
|
||||
EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations,
|
||||
"/data/local/tmp/audio_policy_configuration_V4_0.xsd");
|
||||
EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(
|
||||
kAudioPolicyConfigurationXml, getApmConfigLocations(),
|
||||
kAudioPolicyConfigurationXsd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user