summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Naganov <mnaganov@google.com>2019-11-26 18:56:21 -0800
committerMikhail Naganov <mnaganov@google.com>2019-12-04 10:41:23 -0800
commite6111852bc79d903848c72c353be7bde0e1e95f2 (patch)
treebd3ff51f967d2f266cdb0deff0941eff360815f7
parentb0a0799f56c176bf6782f0a370cc3d9054adb55d (diff)
downloadplatform_hardware_interfaces-e6111852bc79d903848c72c353be7bde0e1e95f2.tar.gz
platform_hardware_interfaces-e6111852bc79d903848c72c353be7bde0e1e95f2.tar.bz2
platform_hardware_interfaces-e6111852bc79d903848c72c353be7bde0e1e95f2.zip
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
-rw-r--r--audio/common/all-versions/test/utility/include/utility/ValidateXml.h7
-rw-r--r--audio/common/all-versions/test/utility/src/ValidateXml.cpp63
-rw-r--r--audio/core/4.0/vts/functional/Android.bp1
-rw-r--r--audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp26
-rw-r--r--audio/core/4.0/vts/functional/AudioPolicyConfiguration.h22
-rw-r--r--audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp29
-rw-r--r--audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp7
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 91adfc12c8..4abd3fa8e1 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 1a906d668b..126873d6f0 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 e3b376ca88..48a98b1feb 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 0000000000..254c018e37
--- /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 0000000000..13a62ed730
--- /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 71d91db360..308a4b51d1 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;
@@ -348,8 +350,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},
@@ -369,10 +392,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});
}
@@ -515,6 +540,10 @@ TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
doc::test("Make sure getMicrophones always succeeds");
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 a64513fc81..7d929ce560 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);
}