diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2019-12-11 21:40:41 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-12-11 21:40:41 +0000 |
commit | 356c36b96d0851c24b3f02a9496051f027eff916 (patch) | |
tree | 65954c8548e88f3c0292f973cc04b0cbfcb26d67 | |
parent | 1ed70316c5f420876e120e1e40b93e268dcff12f (diff) | |
parent | e6111852bc79d903848c72c353be7bde0e1e95f2 (diff) | |
download | android_hardware_interfaces-356c36b96d0851c24b3f02a9496051f027eff916.tar.gz android_hardware_interfaces-356c36b96d0851c24b3f02a9496051f027eff916.tar.bz2 android_hardware_interfaces-356c36b96d0851c24b3f02a9496051f027eff916.zip |
Merge "DO NOT MERGE: Audio HAL: do not test input stream if no Built-in mic on primary" into pie-vts-dev
7 files changed, 143 insertions, 12 deletions
diff --git a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h index 91adfc12c..4abd3fa8e 100644 --- a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h +++ b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h @@ -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 diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp index 1a906d668..126873d6f 100644 --- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp +++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp @@ -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 diff --git a/audio/core/4.0/vts/functional/Android.bp b/audio/core/4.0/vts/functional/Android.bp index e3b376ca8..48a98b1fe 100644 --- a/audio/core/4.0/vts/functional/Android.bp +++ b/audio/core/4.0/vts/functional/Android.bp @@ -18,6 +18,7 @@ cc_test { name: "VtsHalAudioV4_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ + "AudioPolicyConfiguration.cpp", "AudioPrimaryHidlHalTest.cpp", "ValidateAudioConfiguration.cpp" ], diff --git a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp new file mode 100644 index 000000000..254c018e3 --- /dev/null +++ b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp @@ -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; +} diff --git a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h new file mode 100644 index 000000000..13a62ed73 --- /dev/null +++ b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h @@ -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(); diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp index 545d6c097..8e05beb1d 100644 --- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp @@ -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 diff --git a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp index a64513fc8..7d929ce56 100644 --- a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp +++ b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp @@ -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); } |