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:
Treehugger Robot
2019-12-11 21:40:41 +00:00
committed by Gerrit Code Review
7 changed files with 148 additions and 17 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -18,6 +18,7 @@ cc_test {
name: "VtsHalAudioV4_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"AudioPolicyConfiguration.cpp",
"AudioPrimaryHidlHalTest.cpp",
"ValidateAudioConfiguration.cpp"
],

View 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;
}

View 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();

View File

@@ -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

View File

@@ -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);
}