mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "Audio : Add OpenInputMultipleTimes VTS for r_submix" into main
This commit is contained in:
@@ -4174,58 +4174,32 @@ template <typename Stream>
|
|||||||
class WithRemoteSubmix {
|
class WithRemoteSubmix {
|
||||||
public:
|
public:
|
||||||
WithRemoteSubmix() = default;
|
WithRemoteSubmix() = default;
|
||||||
WithRemoteSubmix(AudioDeviceAddress address) : mAddress(address) {}
|
explicit WithRemoteSubmix(AudioDeviceAddress address) : mAddress(address) {}
|
||||||
WithRemoteSubmix(const WithRemoteSubmix&) = delete;
|
WithRemoteSubmix(const WithRemoteSubmix&) = delete;
|
||||||
WithRemoteSubmix& operator=(const WithRemoteSubmix&) = delete;
|
WithRemoteSubmix& operator=(const WithRemoteSubmix&) = delete;
|
||||||
std::optional<AudioPort> getAudioPort() {
|
static std::optional<AudioPort> getRemoteSubmixAudioPort(
|
||||||
|
ModuleConfig* moduleConfig,
|
||||||
|
const std::optional<AudioDeviceAddress>& address = std::nullopt) {
|
||||||
AudioDeviceType deviceType = IOTraits<Stream>::is_input ? AudioDeviceType::IN_SUBMIX
|
AudioDeviceType deviceType = IOTraits<Stream>::is_input ? AudioDeviceType::IN_SUBMIX
|
||||||
: AudioDeviceType::OUT_SUBMIX;
|
: AudioDeviceType::OUT_SUBMIX;
|
||||||
auto ports = mModuleConfig->getAudioPortsForDeviceTypes(
|
auto ports = moduleConfig->getAudioPortsForDeviceTypes(
|
||||||
std::vector<AudioDeviceType>{deviceType},
|
std::vector<AudioDeviceType>{deviceType},
|
||||||
AudioDeviceDescription::CONNECTION_VIRTUAL);
|
AudioDeviceDescription::CONNECTION_VIRTUAL);
|
||||||
if (!ports.empty()) return ports.front();
|
if (ports.empty()) return {};
|
||||||
return {};
|
AudioPort port = ports.front();
|
||||||
}
|
if (address) {
|
||||||
/* Connect remote submix external device */
|
port.ext.template get<AudioPortExt::Tag::device>().device.address = address.value();
|
||||||
void SetUpPortConnection() {
|
|
||||||
auto port = getAudioPort();
|
|
||||||
ASSERT_TRUE(port.has_value()) << "Device AudioPort for remote submix not found";
|
|
||||||
if (mAddress.has_value()) {
|
|
||||||
port.value().ext.template get<AudioPortExt::Tag::device>().device.address =
|
|
||||||
mAddress.value();
|
|
||||||
} else {
|
} else {
|
||||||
port = GenerateUniqueDeviceAddress(port.value());
|
port = GenerateUniqueDeviceAddress(port);
|
||||||
}
|
}
|
||||||
mConnectedPort = std::make_unique<WithDevicePortConnectedState>(port.value());
|
return port;
|
||||||
ASSERT_NO_FATAL_FAILURE(mConnectedPort->SetUp(mModule, mModuleConfig));
|
|
||||||
}
|
}
|
||||||
AudioDeviceAddress getAudioDeviceAddress() {
|
std::optional<AudioDeviceAddress> getAudioDeviceAddress() const { return mAddress; }
|
||||||
if (!mAddress.has_value()) {
|
void SetUp(IModule* module, ModuleConfig* moduleConfig, const AudioPort& connectedPort) {
|
||||||
mAddress = mConnectedPort->get()
|
|
||||||
.ext.template get<AudioPortExt::Tag::device>()
|
|
||||||
.device.address;
|
|
||||||
}
|
|
||||||
return mAddress.value();
|
|
||||||
}
|
|
||||||
/* Get mix port config for stream and setup patch for it. */
|
|
||||||
void SetupPatch() {
|
|
||||||
const auto portConfig =
|
|
||||||
mModuleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
|
|
||||||
if (!portConfig.has_value()) {
|
|
||||||
LOG(DEBUG) << __func__ << ": portConfig not found";
|
|
||||||
mSkipTest = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto devicePortConfig = mModuleConfig->getSingleConfigForDevicePort(mConnectedPort->get());
|
|
||||||
mPatch = std::make_unique<WithAudioPatch>(IOTraits<Stream>::is_input, portConfig.value(),
|
|
||||||
devicePortConfig);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(mPatch->SetUp(mModule));
|
|
||||||
}
|
|
||||||
void SetUp(IModule* module, ModuleConfig* moduleConfig) {
|
|
||||||
mModule = module;
|
mModule = module;
|
||||||
mModuleConfig = moduleConfig;
|
mModuleConfig = moduleConfig;
|
||||||
ASSERT_NO_FATAL_FAILURE(SetUpPortConnection());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(SetupPatch());
|
ASSERT_NO_FATAL_FAILURE(SetupPatch(connectedPort));
|
||||||
if (!mSkipTest) {
|
if (!mSkipTest) {
|
||||||
// open stream
|
// open stream
|
||||||
mStream = std::make_unique<WithStream<Stream>>(
|
mStream = std::make_unique<WithStream<Stream>>(
|
||||||
@@ -4233,6 +4207,11 @@ class WithRemoteSubmix {
|
|||||||
ASSERT_NO_FATAL_FAILURE(
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
mStream->SetUp(mModule, AudioCoreModuleBase::kDefaultBufferSizeFrames));
|
mStream->SetUp(mModule, AudioCoreModuleBase::kDefaultBufferSizeFrames));
|
||||||
}
|
}
|
||||||
|
mAddress = connectedPort.ext.template get<AudioPortExt::Tag::device>().device.address;
|
||||||
|
}
|
||||||
|
void SetUp(IModule* module, ModuleConfig* moduleConfig) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(SetUpPortConnection(module, moduleConfig));
|
||||||
|
SetUp(module, moduleConfig, mConnectedPort->get());
|
||||||
}
|
}
|
||||||
void sendBurstCommands() {
|
void sendBurstCommands() {
|
||||||
const StreamContext* context = mStream->getContext();
|
const StreamContext* context = mStream->getContext();
|
||||||
@@ -4250,9 +4229,31 @@ class WithRemoteSubmix {
|
|||||||
}
|
}
|
||||||
EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
|
EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
|
||||||
}
|
}
|
||||||
bool skipTest() { return mSkipTest; }
|
bool skipTest() const { return mSkipTest; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/* Connect remote submix external device */
|
||||||
|
void SetUpPortConnection(IModule* module, ModuleConfig* moduleConfig) {
|
||||||
|
auto port = getRemoteSubmixAudioPort(moduleConfig, mAddress);
|
||||||
|
ASSERT_TRUE(port.has_value()) << "Device AudioPort for remote submix not found";
|
||||||
|
mConnectedPort = std::make_unique<WithDevicePortConnectedState>(port.value());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(mConnectedPort->SetUp(module, moduleConfig));
|
||||||
|
}
|
||||||
|
/* Get mix port config for stream and setup patch for it. */
|
||||||
|
void SetupPatch(const AudioPort& connectedPort) {
|
||||||
|
const auto portConfig =
|
||||||
|
mModuleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
|
||||||
|
if (!portConfig.has_value()) {
|
||||||
|
LOG(DEBUG) << __func__ << ": portConfig not found";
|
||||||
|
mSkipTest = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto devicePortConfig = mModuleConfig->getSingleConfigForDevicePort(connectedPort);
|
||||||
|
mPatch = std::make_unique<WithAudioPatch>(IOTraits<Stream>::is_input, portConfig.value(),
|
||||||
|
devicePortConfig);
|
||||||
|
ASSERT_NO_FATAL_FAILURE(mPatch->SetUp(mModule));
|
||||||
|
}
|
||||||
|
|
||||||
bool mSkipTest = false;
|
bool mSkipTest = false;
|
||||||
IModule* mModule = nullptr;
|
IModule* mModule = nullptr;
|
||||||
ModuleConfig* mModuleConfig = nullptr;
|
ModuleConfig* mModuleConfig = nullptr;
|
||||||
@@ -4290,9 +4291,11 @@ TEST_P(AudioModuleRemoteSubmix, OutputDoesNotBlockWhenInputStuck) {
|
|||||||
if (streamOut.skipTest()) {
|
if (streamOut.skipTest()) {
|
||||||
GTEST_SKIP() << "No mix port for attached devices";
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
}
|
}
|
||||||
|
auto address = streamOut.getAudioDeviceAddress();
|
||||||
|
ASSERT_TRUE(address.has_value());
|
||||||
|
|
||||||
// open input stream
|
// open input stream
|
||||||
WithRemoteSubmix<IStreamIn> streamIn(streamOut.getAudioDeviceAddress());
|
WithRemoteSubmix<IStreamIn> streamIn(address.value());
|
||||||
ASSERT_NO_FATAL_FAILURE(streamIn.SetUp(module.get(), moduleConfig.get()));
|
ASSERT_NO_FATAL_FAILURE(streamIn.SetUp(module.get(), moduleConfig.get()));
|
||||||
if (streamIn.skipTest()) {
|
if (streamIn.skipTest()) {
|
||||||
GTEST_SKIP() << "No mix port for attached devices";
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
@@ -4309,9 +4312,11 @@ TEST_P(AudioModuleRemoteSubmix, OutputAndInput) {
|
|||||||
if (streamOut.skipTest()) {
|
if (streamOut.skipTest()) {
|
||||||
GTEST_SKIP() << "No mix port for attached devices";
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
}
|
}
|
||||||
|
auto address = streamOut.getAudioDeviceAddress();
|
||||||
|
ASSERT_TRUE(address.has_value());
|
||||||
|
|
||||||
// open input stream
|
// open input stream
|
||||||
WithRemoteSubmix<IStreamIn> streamIn(streamOut.getAudioDeviceAddress());
|
WithRemoteSubmix<IStreamIn> streamIn(address.value());
|
||||||
ASSERT_NO_FATAL_FAILURE(streamIn.SetUp(module.get(), moduleConfig.get()));
|
ASSERT_NO_FATAL_FAILURE(streamIn.SetUp(module.get(), moduleConfig.get()));
|
||||||
if (streamIn.skipTest()) {
|
if (streamIn.skipTest()) {
|
||||||
GTEST_SKIP() << "No mix port for attached devices";
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
@@ -4323,6 +4328,43 @@ TEST_P(AudioModuleRemoteSubmix, OutputAndInput) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(streamIn.sendBurstCommands());
|
ASSERT_NO_FATAL_FAILURE(streamIn.sendBurstCommands());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(AudioModuleRemoteSubmix, OpenInputMultipleTimes) {
|
||||||
|
// open output stream
|
||||||
|
WithRemoteSubmix<IStreamOut> streamOut;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(streamOut.SetUp(module.get(), moduleConfig.get()));
|
||||||
|
if (streamOut.skipTest()) {
|
||||||
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
|
}
|
||||||
|
auto address = streamOut.getAudioDeviceAddress();
|
||||||
|
ASSERT_TRUE(address.has_value());
|
||||||
|
|
||||||
|
// connect remote submix input device port
|
||||||
|
auto port = WithRemoteSubmix<IStreamIn>::getRemoteSubmixAudioPort(moduleConfig.get(),
|
||||||
|
address.value());
|
||||||
|
ASSERT_TRUE(port.has_value()) << "Device AudioPort for remote submix not found";
|
||||||
|
WithDevicePortConnectedState connectedInputPort(port.value());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(connectedInputPort.SetUp(module.get(), moduleConfig.get()));
|
||||||
|
|
||||||
|
// open input streams
|
||||||
|
const int streamInCount = 3;
|
||||||
|
std::vector<std::unique_ptr<WithRemoteSubmix<IStreamIn>>> streamIns(streamInCount);
|
||||||
|
for (int i = 0; i < streamInCount; i++) {
|
||||||
|
streamIns[i] = std::make_unique<WithRemoteSubmix<IStreamIn>>();
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
streamIns[i]->SetUp(module.get(), moduleConfig.get(), connectedInputPort.get()));
|
||||||
|
if (streamIns[i]->skipTest()) {
|
||||||
|
GTEST_SKIP() << "No mix port for attached devices";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write something to output stream
|
||||||
|
ASSERT_NO_FATAL_FAILURE(streamOut.sendBurstCommands());
|
||||||
|
|
||||||
|
// read from input streams
|
||||||
|
for (int i = 0; i < streamInCount; i++) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(streamIns[i]->sendBurstCommands());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(AudioModuleRemoteSubmixTest, AudioModuleRemoteSubmix,
|
INSTANTIATE_TEST_SUITE_P(AudioModuleRemoteSubmixTest, AudioModuleRemoteSubmix,
|
||||||
::testing::ValuesIn(getRemoteSubmixModuleInstance()));
|
::testing::ValuesIn(getRemoteSubmixModuleInstance()));
|
||||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioModuleRemoteSubmix);
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioModuleRemoteSubmix);
|
||||||
|
|||||||
Reference in New Issue
Block a user