Merge changes from topic "policy-xml-vts"
* changes:
Audio VTS: Reset HAL after setConnectionState
Audio HAL: do not test input stream if no Built-in mic on primary
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 41b3841..e7c1e58 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -16,6 +16,17 @@
#include "AudioPrimaryHidlHalTest.h"
+static void waitForDeviceDestruction() {
+ // FIXME: there is no way to know when the remote IDevice is being destroyed
+ // Binder does not support testing if an object is alive, thus
+ // wait for 100ms to let the binder destruction propagates and
+ // the remote device has the time to be destroyed.
+ // flushCommand makes sure all local command are sent, thus should reduce
+ // the latency between local and remote destruction.
+ IPCThreadState::self()->flushCommands();
+ usleep(100);
+}
+
TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
doc::test("Calling openDevice(\"primary\") should return the primary device.");
{
@@ -29,14 +40,7 @@
ASSERT_TRUE(primaryDevice.isOk());
ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
} // Destroy local IDevice proxy
- // FIXME: there is no way to know when the remote IDevice is being destroyed
- // Binder does not support testing if an object is alive, thus
- // wait for 100ms to let the binder destruction propagates and
- // the remote device has the time to be destroyed.
- // flushCommand makes sure all local command are sent, thus should reduce
- // the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
- usleep(100);
+ waitForDeviceDestruction();
}
//////////////////////////////////////////////////////////////////////////////
@@ -133,11 +137,17 @@
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
doc::partialTest("setConnectedState is not supported");
- return;
+ break; // other deviceType might be supported
}
ASSERT_OK(ret);
}
}
+
+ // Because there is no way of knowing if the devices were connected before
+ // calling setConnectedState, there is no way to restore the HAL to its
+ // initial state. To workaround this, destroy the HAL at the end of this test.
+ device.clear();
+ waitForDeviceDestruction();
}
static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 366a03e..519e359 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -17,13 +17,12 @@
cc_defaults {
name: "VtsHalAudioTargetTest_defaults",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: [
- "ValidateAudioConfiguration.cpp"
- ],
static_libs: [
"android.hardware.audio.common.test.utility",
+ "libaudiopolicycomponents",
"libicuuc",
"libicuuc_stubdata",
+ "libmedia_helper",
"libxml2",
],
shared_libs: [
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index fd061da..24f4238 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -40,6 +40,8 @@
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+
+#include <Serializer.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
@@ -50,6 +52,7 @@
#include "utility/EnvironmentTearDown.h"
#include "utility/PrettyPrintAudioTypes.h"
#include "utility/ReturnIn.h"
+#include "utility/ValidateXml.h"
/** Provide version specific functions that are used in the generic tests */
#if MAJOR_VERSION == 2
@@ -64,7 +67,12 @@
using std::to_string;
using std::vector;
+using ::android::AudioPolicyConfig;
+using ::android::HwModule;
+using ::android::NO_INIT;
+using ::android::OK;
using ::android::sp;
+using ::android::status_t;
using ::android::hardware::EventFlag;
using ::android::hardware::hidl_bitfield;
using ::android::hardware::hidl_enum_range;
@@ -120,6 +128,10 @@
static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////// Environment /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
class AudioHidlTestEnvironment : public ::Environment {
public:
virtual void registerTestServices() override { registerTestService<IDevicesFactory>(); }
@@ -135,11 +147,103 @@
};
//////////////////////////////////////////////////////////////////////////////
+////////////////////////// Audio policy configuration ////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+static const std::vector<const char*> kConfigLocations = {"/odm/etc", "/vendor/etc", "/system/etc"};
+static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
+
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+TEST(CheckConfig, audioPolicyConfigurationValidation) {
+ RecordProperty("description",
+ "Verify that the audio policy configuration file "
+ "is valid according to the schema");
+
+ const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
+ EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName, kConfigLocations, xsd);
+}
+
+struct PolicyConfigData {
+ android::HwModuleCollection hwModules;
+ android::DeviceVector availableOutputDevices;
+ android::DeviceVector availableInputDevices;
+ sp<android::DeviceDescriptor> defaultOutputDevice;
+ android::VolumeCurvesCollection volumes;
+};
+
+class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
+ public:
+ PolicyConfig()
+ : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
+ defaultOutputDevice, &volumes) {
+ for (const char* location : kConfigLocations) {
+ std::string path = std::string(location) + '/' + kConfigFileName;
+ if (access(path.c_str(), F_OK) == 0) {
+ mFilePath = path;
+ break;
+ }
+ }
+ mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
+ if (mStatus == OK) {
+ mPrimaryModule = getHwModules().getModuleFromName("primary");
+ }
+ }
+ status_t getStatus() const { return mStatus; }
+ std::string getError() const {
+ if (mFilePath.empty()) {
+ return std::string{"Could not find "} + kConfigFileName +
+ " file in: " + testing::PrintToString(kConfigLocations);
+ } else {
+ return "Invalid config file: " + mFilePath;
+ }
+ }
+ const std::string& getFilePath() const { return mFilePath; }
+ sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
+
+ private:
+ status_t mStatus = NO_INIT;
+ std::string mFilePath;
+ sp<HwModule> mPrimaryModule = nullptr;
+};
+
+// Cached policy config after parsing for faster test startup
+const PolicyConfig& getCachedPolicyConfig() {
+ static std::unique_ptr<PolicyConfig> policyConfig = [] {
+ auto config = std::make_unique<PolicyConfig>();
+ environment->registerTearDown([] { policyConfig.reset(); });
+ return config;
+ }();
+ return *policyConfig;
+}
+
+class AudioPolicyConfigTest : public HidlTest {
+ public:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
+
+ auto& policyConfig = getCachedPolicyConfig();
+ ASSERT_EQ(0, policyConfig.getStatus()) << policyConfig.getError();
+
+ mPrimaryConfig = policyConfig.getPrimaryModule();
+ ASSERT_TRUE(mPrimaryConfig) << "Could not find primary module in configuration file: "
+ << policyConfig.getFilePath();
+ }
+ sp<const HwModule> mPrimaryConfig = nullptr;
+};
+
+TEST_F(AudioPolicyConfigTest, LoadAudioPolicyXMLConfiguration) {
+ doc::test("Test parsing audio_policy_configuration.xml (called in SetUp)");
+}
+
+//////////////////////////////////////////////////////////////////////////////
////////////////////// getService audio_devices_factory //////////////////////
//////////////////////////////////////////////////////////////////////////////
// Test all audio devices
-class AudioHidlTest : public HidlTest {
+class AudioHidlTest : public AudioPolicyConfigTest {
public:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
@@ -346,6 +450,20 @@
class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
public:
+ // for retro compatibility only test the primary device IN_BUILTIN_MIC
+ // FIXME: in the next audio HAL version, test all available devices
+ static bool primaryHasMic() {
+ auto& policyConfig = getCachedPolicyConfig();
+ if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
+ return true; // Could not get the information, run all tests
+ }
+ auto getMic = [](auto& devs) { return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}); };
+ auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
+ auto availableMic = getMic(policyConfig.getAvailableInputDevices());
+
+ return primaryMic != nullptr && primaryMic->equals(availableMic);
+ }
+
// Cache result ?
static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
@@ -365,10 +483,12 @@
}
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});
}
diff --git a/audio/core/all-versions/vts/functional/ValidateAudioConfiguration.cpp b/audio/core/all-versions/vts/functional/ValidateAudioConfiguration.cpp
deleted file mode 100644
index 5b6f378..0000000
--- a/audio/core/all-versions/vts/functional/ValidateAudioConfiguration.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 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 <unistd.h>
-#include <string>
-
-#include "utility/ValidateXml.h"
-
-// Stringify the argument.
-#define QUOTE(x) #x
-#define STRINGIFY(x) QUOTE(x)
-
-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"};
- const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
- EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations, xsd);
-}