audiopolicy: engine: Add VTS for engine configurable configuration

This CL adds VTS test for engine PFW configuration files (Skipped
for default engine, the check is performed by reading the
audio_policy_configuration file AND parameter-framework top configuration
file)

AllSchemas.xsd is made by manual inclusion from all other
xsd files. It is used for API files generation.

Test: build & run vts --module VtsHalAudioPolicyV1_0Target
      atest VtsHalAudioPolicyV1_0TargetTest
Bug: 141989952

Change-Id: I62730caadafdcb5ebb3083d683625424864afe97
Merged-In: I62730caadafdcb5ebb3083d683625424864afe97
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp
index f668a25..b50e501 100644
--- a/audio/policy/1.0/vts/functional/Android.bp
+++ b/audio/policy/1.0/vts/functional/Android.bp
@@ -5,15 +5,31 @@
         "ValidateEngineConfiguration.cpp",
     ],
     static_libs: [
-        "android.hardware.audio.common.test.utility",
         "libxml2",
         "liblog",
+        "libmedia_helper",
+        "libaudiopolicyengine_config",
+        "libaudiopolicycomponents",
+        "libaudiopolicyengineconfigurable_pfwwrapper",
+        "android.hardware.audio.common.test.utility",
+        "libparameter",
+        "libpfw_utility",
+        "libremote-processor",
+        "libutils",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libbase",
+    ],
+    shared_libs: [
+        "libaudiofoundation",
     ],
     // Use test_config for vts-core suite.
     // TODO(b/146104851): Add auto-gen rules and remove it.
     test_config: "VtsHalAudioPolicyV1_0TargetTest.xml",
     cflags: [
         "-DXSD_DIR=\"/data/local/tmp\"",
+        "-DXSD_PFW_DIR=\"/data/local/tmp/Schemas\"",
         "-Wall",
         "-Werror",
         "-Wno-unused-function",
@@ -22,6 +38,18 @@
     ],
     data: [
         ":audio_policy_engine_conf_V1_0",
+        ":audio_policy_engine_configurable_configuration_V1_0",
+        ":audio_policy_engine_configurable_configuration_ComponentLibrary_V1_0",
+        ":audio_policy_engine_configurable_configuration_ComponentTypeSet_V1_0",
+        ":audio_policy_engine_configurable_configuration_ConfigurableDomain_V1_0",
+        ":audio_policy_engine_configurable_configuration_ConfigurableDomains_V1_0",
+        ":audio_policy_engine_configurable_configuration_FileIncluder_V1_0",
+        ":audio_policy_engine_configurable_configuration_Parameter_V1_0",
+        ":audio_policy_engine_configurable_configuration_ParameterFrameworkConfiguration_V1_0",
+        ":audio_policy_engine_configurable_configuration_ParameterSettings_V1_0",
+        ":audio_policy_engine_configurable_configuration_Subsystem_V1_0",
+        ":audio_policy_engine_configurable_configuration_SystemClass_V1_0",
+        ":audio_policy_engine_configurable_configuration_W3cXmlAttributes_V1_0",
     ],
     gtest: true,
     test_suites: [
diff --git a/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp b/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
index 1eb39f9..a0aaa6e 100644
--- a/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
+++ b/audio/policy/1.0/vts/functional/ValidateEngineConfiguration.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <EngineConfig.h>
+#include <ParameterManagerWrapper.h>
+
 #include <gtest/gtest.h>
 
 #include <unistd.h>
@@ -25,6 +28,11 @@
 static const std::string schema =
         std::string(XSD_DIR) + "/audio_policy_engine_configuration_V1_0.xsd";
 
+static const std::string configurableSchemas =
+        std::string(XSD_DIR) + "/audio_policy_engine_configurable_configuration_V1_0.xsd";
+static const std::string configurableConfig =
+        "parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
+
 /**
  * @brief TEST to ensure the audio policy engine configuration file is validating schemas.
  * Note: this configuration file is not mandatory, an hardcoded fallback is provided, so
@@ -36,3 +44,70 @@
                    "is valid according to the schemas");
     EXPECT_VALID_XML_MULTIPLE_LOCATIONS(config.c_str(), locations, schema.c_str());
 }
+
+/**
+ * @brief deviceUsesConfigurableEngine checks if the configuration file for
+ * the engine presents on the device AND
+ * for the configurable engine (aka Parameter-Framework top configuration file) presents.
+ */
+static bool deviceUsesConfigurableEngine() {
+    return android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>(
+                   "", "", "", config.c_str(), locations, schema.c_str()) &&
+           android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>(
+                   "", "", "", configurableConfig.c_str(), locations, configurableSchemas.c_str());
+}
+
+TEST(ValidateConfiguration, audioPolicyEngineConfigurable) {
+    if (!deviceUsesConfigurableEngine()) {
+        GTEST_SKIP() << "Device using legacy engine without parameter-framework, n-op.";
+    }
+    RecordProperty("description",
+                   "Verify that the audio policy engine PFW configuration files "
+                   "are valid according to the schemas");
+
+    auto testAudioPolicyEnginePfw = [&](bool validateSchema, const std::string& schemasUri) {
+        auto result = android::engineConfig::parse();
+
+        ASSERT_NE(nullptr, result.parsedConfig)
+                << "failed to parse audio policy engine configuration";
+
+        ASSERT_EQ(result.nbSkippedElement, 0) << "skipped %zu elements " << result.nbSkippedElement;
+
+        std::unique_ptr<android::audio_policy::ParameterManagerWrapper> policyParameterMgr(
+                new android::audio_policy::ParameterManagerWrapper(validateSchema, schemasUri));
+        ASSERT_NE(nullptr, policyParameterMgr) << "failed to create Audio Policy Engine PFW";
+
+        // Load the criterion types and criteria
+        for (auto& criterion : result.parsedConfig->criteria) {
+            android::engineConfig::CriterionType criterionType;
+            for (auto& configCriterionType : result.parsedConfig->criterionTypes) {
+                if (configCriterionType.name == criterion.typeName) {
+                    criterionType = configCriterionType;
+                    break;
+                }
+            }
+            ASSERT_FALSE(criterionType.name.empty())
+                    << "Invalid criterion type for " << criterion.name.c_str();
+            policyParameterMgr->addCriterion(criterion.name, criterionType.isInclusive,
+                                             criterionType.valuePairs,
+                                             criterion.defaultLiteralValue);
+        }
+        ASSERT_EQ(0, result.nbSkippedElement) << "failed to parse Audio Policy Engine PFW criteria";
+
+        // If the PFW cannot validate, it will not start
+        std::string error;
+        auto status = policyParameterMgr->start(error);
+        ASSERT_EQ(status, android::NO_ERROR)
+                << "failed to " << (validateSchema ? "validate" : "start")
+                << " Audio Policy Engine PFW: " << error;
+
+        ASSERT_TRUE(policyParameterMgr->isStarted());
+    };
+
+    // First round for sanity to ensure we can launch the Audio Policy Engine PFW without
+    // schema validation successfully, otherwise it is not forth going on running validation...
+    testAudioPolicyEnginePfw(false, {});
+
+    // If second round fails, it means parameter-framework cannot validate schema
+    testAudioPolicyEnginePfw(true, {XSD_PFW_DIR});
+}
diff --git a/audio/policy/1.0/vts/functional/VtsHalAudioPolicyV1_0TargetTest.xml b/audio/policy/1.0/vts/functional/VtsHalAudioPolicyV1_0TargetTest.xml
index 4318e92..68b390f 100644
--- a/audio/policy/1.0/vts/functional/VtsHalAudioPolicyV1_0TargetTest.xml
+++ b/audio/policy/1.0/vts/functional/VtsHalAudioPolicyV1_0TargetTest.xml
@@ -27,6 +27,18 @@
     <option name="cleanup" value="true" />
     <option name="push" value="VtsHalAudioPolicyV1_0TargetTest->/data/local/tmp/VtsHalAudioPolicyV1_0TargetTest" />
     <option name="push" value="audio_policy_engine_conf_V1_0.xsd->/data/local/tmp/audio_policy_engine_configuration_V1_0.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_V1_0.xsd->/data/local/tmp/audio_policy_engine_configurable_configuration_V1_0.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ComponentLibrary_V1_0.xsd->/data/local/tmp/Schemas/ComponentLibrary.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ComponentTypeSet_V1_0.xsd->/data/local/tmp/Schemas/ComponentTypeSet.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ConfigurableDomain_V1_0.xsd->/data/local/tmp/Schemas/ConfigurableDomain.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ConfigurableDomains_V1_0.xsd->/data/local/tmp/Schemas/ConfigurableDomains.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_FileIncluder_V1_0.xsd->/data/local/tmp/Schemas/FileIncluder.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_Parameter_V1_0.xsd->/data/local/tmp/Schemas/Parameter.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ParameterFrameworkConfiguration_V1_0.xsd->/data/local/tmp/Schemas/ParameterFrameworkConfiguration.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_ParameterSettings_V1_0.xsd->/data/local/tmp/Schemas/ParameterSettings.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_Subsystem_V1_0.xsd->/data/local/tmp/Schemas/Subsystem.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_SystemClass_V1_0.xsd->/data/local/tmp/Schemas/SystemClass.xsd" />
+    <option name="push" value="audio_policy_engine_configurable_configuration_W3cXmlAttributes_V1_0.xsd->/data/local/tmp/Schemas/W3cXmlAttributes.xsd" />
   </target_preparer>
 
   <test class="com.android.tradefed.testtype.GTest" >