Merge "Audio : Add OpenInputMultipleTimes VTS for r_submix" into main

This commit is contained in:
Treehugger Robot
2023-09-28 20:53:33 +00:00
committed by Gerrit Code Review

View File

@@ -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);