diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp index 8596466738..bb8d76f8fc 100644 --- a/audio/aidl/default/Android.bp +++ b/audio/aidl/default/Android.bp @@ -88,7 +88,6 @@ cc_library { "primary/PrimaryMixer.cpp", "primary/StreamPrimary.cpp", "r_submix/ModuleRemoteSubmix.cpp", - "r_submix/RemoteSubmixUtils.cpp", "r_submix/SubmixRoute.cpp", "r_submix/StreamRemoteSubmix.cpp", "stub/ModuleStub.cpp", diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp index 0fbf55bb12..8e02e7dfa7 100644 --- a/audio/aidl/default/Configuration.cpp +++ b/audio/aidl/default/Configuration.cpp @@ -81,8 +81,6 @@ static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags, deviceExt.device.address = "bottom"; } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) { deviceExt.device.address = "back"; - } else if (devType == AudioDeviceType::IN_SUBMIX || devType == AudioDeviceType::OUT_SUBMIX) { - deviceExt.device.address = "0"; } deviceExt.device.type.connection = std::move(connection); deviceExt.flags = flags; @@ -291,15 +289,21 @@ std::unique_ptr getPrimaryConfiguration() { // // Device ports: // * "Remote Submix Out", OUT_SUBMIX -// - profile PCM 16-bit; STEREO; 48000 +// - no profiles specified // * "Remote Submix In", IN_SUBMIX -// - profile PCM 16-bit; STEREO; 48000 +// - no profiles specified // // Mix ports: -// * "r_submix output", 1 max open, 1 max active stream -// - profile PCM 16-bit; STEREO; 48000 -// * "r_submix input", 1 max open, 1 max active stream -// - profile PCM 16-bit; STEREO; 48000 +// * "r_submix output", unlimited max open, unlimited max active stream +// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 32-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 32-bit float; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// * "r_submix input", unlimited max open, unlimited max active stream +// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 32-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// - profile PCM 32-bit float; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 // // Routes: // "r_submix output" -> "Remote Submix Out" @@ -308,6 +312,19 @@ std::unique_ptr getPrimaryConfiguration() { std::unique_ptr getRSubmixConfiguration() { static const Configuration configuration = []() { Configuration c; + const std::vector standardPcmAudioProfiles{ + createProfile(PcmType::FLOAT_32_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {8000, 11025, 16000, 32000, 44100, 48000}), + createProfile(PcmType::INT_32_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {8000, 11025, 16000, 32000, 44100, 48000}), + createProfile(PcmType::INT_24_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {8000, 11025, 16000, 32000, 44100, 48000}), + createProfile(PcmType::INT_16_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {8000, 11025, 16000, 32000, 44100, 48000})}; // Device ports @@ -315,28 +332,26 @@ std::unique_ptr getRSubmixConfiguration() { createPort(c.nextPortId++, "Remote Submix Out", 0, false, createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0, AudioDeviceDescription::CONNECTION_VIRTUAL)); - rsubmixOutDevice.profiles.push_back( - createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000})); c.ports.push_back(rsubmixOutDevice); + c.connectedProfiles[rsubmixOutDevice.id] = standardPcmAudioProfiles; - AudioPort rsubmixInDevice = createPort(c.nextPortId++, "Remote Submix In", 0, true, - createDeviceExt(AudioDeviceType::IN_SUBMIX, 0)); - rsubmixInDevice.profiles.push_back( - createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000})); + AudioPort rsubmixInDevice = + createPort(c.nextPortId++, "Remote Submix In", 0, true, + createDeviceExt(AudioDeviceType::IN_SUBMIX, 0, + AudioDeviceDescription::CONNECTION_VIRTUAL)); c.ports.push_back(rsubmixInDevice); + c.connectedProfiles[rsubmixInDevice.id] = standardPcmAudioProfiles; // Mix ports AudioPort rsubmixOutMix = - createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(1, 1)); - rsubmixOutMix.profiles.push_back( - createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000})); + createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(0, 0)); + rsubmixOutMix.profiles = standardPcmAudioProfiles; c.ports.push_back(rsubmixOutMix); AudioPort rsubmixInMix = - createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(1, 1)); - rsubmixInMix.profiles.push_back( - createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000})); + createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(0, 0)); + rsubmixInMix.profiles = standardPcmAudioProfiles; c.ports.push_back(rsubmixInMix); c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice)); diff --git a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h index e87be3d9d2..c4bf7b99c2 100644 --- a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h +++ b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h @@ -26,8 +26,6 @@ class ModuleRemoteSubmix : public Module { private: // IModule interfaces - ndk::ScopedAStatus getTelephony(std::shared_ptr* _aidl_return) override; - ndk::ScopedAStatus getBluetooth(std::shared_ptr* _aidl_return) override; ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; ndk::ScopedAStatus setMicMute(bool in_mute) override; @@ -49,9 +47,6 @@ class ModuleRemoteSubmix : public Module { const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks) override; - void onExternalDeviceConnectionChanged( - const ::aidl::android::media::audio::common::AudioPort& audioPort, - bool connected) override; ndk::ScopedAStatus onMasterMuteChanged(bool mute) override; ndk::ScopedAStatus onMasterVolumeChanged(float volume) override; }; diff --git a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp index 9be783758d..adea877be6 100644 --- a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp +++ b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp @@ -19,8 +19,8 @@ #include #include +#include -#include "RemoteSubmixUtils.h" #include "core-impl/ModuleRemoteSubmix.h" #include "core-impl/StreamRemoteSubmix.h" @@ -33,18 +33,6 @@ using aidl::android::media::audio::common::MicrophoneInfo; namespace aidl::android::hardware::audio::core { -ndk::ScopedAStatus ModuleRemoteSubmix::getTelephony(std::shared_ptr* _aidl_return) { - *_aidl_return = nullptr; - LOG(DEBUG) << __func__ << ": returning null"; - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus ModuleRemoteSubmix::getBluetooth(std::shared_ptr* _aidl_return) { - *_aidl_return = nullptr; - LOG(DEBUG) << __func__ << ": returning null"; - return ndk::ScopedAStatus::ok(); -} - ndk::ScopedAStatus ModuleRemoteSubmix::getMicMute(bool* _aidl_return __unused) { LOG(DEBUG) << __func__ << ": is not supported"; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); @@ -70,23 +58,26 @@ ndk::ScopedAStatus ModuleRemoteSubmix::createOutputStream( } ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort) { - LOG(VERBOSE) << __func__ << ": Profiles already populated by Configuration"; - for (auto profile : audioPort->profiles) { - for (auto channelMask : profile.channelMasks) { - if (!r_submix::isChannelMaskSupported(channelMask)) { - LOG(ERROR) << __func__ << ": the profile " << profile.name - << " has unsupported channel mask : " << channelMask.toString(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); - } - } - for (auto sampleRate : profile.sampleRates) { - if (!r_submix::isSampleRateSupported(sampleRate)) { - LOG(ERROR) << __func__ << ": the profile " << profile.name - << " has unsupported sample rate : " << sampleRate; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); - } - } + // Find the corresponding mix port and copy its profiles. + std::vector routes; + // At this moment, the port has the same ID as the template port, see connectExternalDevice. + RETURN_STATUS_IF_ERROR(getAudioRoutesForAudioPort(audioPort->id, &routes)); + if (routes.empty()) { + LOG(ERROR) << __func__ << ": no routes found for the port " << audioPort->toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } + const auto& route = *routes.begin(); + AudioPort mixPort; + if (route.sinkPortId == audioPort->id) { + if (route.sourcePortIds.empty()) { + LOG(ERROR) << __func__ << ": invalid route " << route.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + RETURN_STATUS_IF_ERROR(getAudioPort(*route.sourcePortIds.begin(), &mixPort)); + } else { + RETURN_STATUS_IF_ERROR(getAudioPort(route.sinkPortId, &mixPort)); + } + audioPort->profiles = mixPort.profiles; return ndk::ScopedAStatus::ok(); } @@ -106,12 +97,6 @@ ndk::ScopedAStatus ModuleRemoteSubmix::checkAudioPatchEndpointsMatch( return ndk::ScopedAStatus::ok(); } -void ModuleRemoteSubmix::onExternalDeviceConnectionChanged( - const ::aidl::android::media::audio::common::AudioPort& audioPort __unused, - bool connected __unused) { - LOG(DEBUG) << __func__ << ": do nothing and return"; -} - ndk::ScopedAStatus ModuleRemoteSubmix::onMasterMuteChanged(bool __unused) { LOG(DEBUG) << __func__ << ": is not supported"; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); diff --git a/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp b/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp deleted file mode 100644 index 2f5d17d44e..0000000000 --- a/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 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 - -#include "RemoteSubmixUtils.h" - -namespace aidl::android::hardware::audio::core::r_submix { - -bool isChannelMaskSupported(const AudioChannelLayout& channelMask) { - const static std::vector kSupportedChannelMask = { - AudioChannelLayout::make( - AudioChannelLayout::LAYOUT_MONO), - AudioChannelLayout::make( - AudioChannelLayout::LAYOUT_STEREO)}; - - if (std::find(kSupportedChannelMask.begin(), kSupportedChannelMask.end(), channelMask) != - kSupportedChannelMask.end()) { - return true; - } - return false; -} - -bool isSampleRateSupported(int sampleRate) { - const static std::vector kSupportedSampleRates = {8000, 11025, 12000, 16000, 22050, - 24000, 32000, 44100, 48000}; - - if (std::find(kSupportedSampleRates.begin(), kSupportedSampleRates.end(), sampleRate) != - kSupportedSampleRates.end()) { - return true; - } - return false; -} - -} // namespace aidl::android::hardware::audio::core::r_submix diff --git a/audio/aidl/default/r_submix/RemoteSubmixUtils.h b/audio/aidl/default/r_submix/RemoteSubmixUtils.h deleted file mode 100644 index 952a992659..0000000000 --- a/audio/aidl/default/r_submix/RemoteSubmixUtils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - -#pragma once - -#include -#include - -using aidl::android::media::audio::common::AudioChannelLayout; - -namespace aidl::android::hardware::audio::core::r_submix { - -bool isChannelMaskSupported(const AudioChannelLayout& channelMask); - -bool isSampleRateSupported(int sampleRate); - -} // namespace aidl::android::hardware::audio::core::r_submix diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp index 8c448a805e..7213034bcc 100644 --- a/audio/aidl/vts/ModuleConfig.cpp +++ b/audio/aidl/vts/ModuleConfig.cpp @@ -30,6 +30,7 @@ using namespace std::chrono_literals; using aidl::android::hardware::audio::common::isBitPositionFlagSet; using aidl::android::hardware::audio::core::IModule; using aidl::android::media::audio::common::AudioChannelLayout; +using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioEncapsulationMode; using aidl::android::media::audio::common::AudioFormatDescription; @@ -96,7 +97,10 @@ ModuleConfig::ModuleConfig(IModule* module) { } else { mAttachedSinkDevicePorts.insert(port.id); } - } else if (port.profiles.empty()) { + } else if (devicePort.device.type.connection != AudioDeviceDescription::CONNECTION_VIRTUAL + // The "virtual" connection is used for remote submix which is a dynamic + // device but it can be connected and used w/o external hardware. + && port.profiles.empty()) { mExternalDevicePorts.insert(port.id); } } diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp index b680373351..68e7151191 100644 --- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp +++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp @@ -1627,14 +1627,17 @@ TEST_P(AudioCoreModule, TryConnectMissingDevice) { if (ports.empty()) { GTEST_SKIP() << "No external devices in the module."; } - AudioPort ignored; WithDebugFlags doNotSimulateConnections = WithDebugFlags::createNested(*debug); doNotSimulateConnections.flags().simulateDeviceConnections = false; ASSERT_NO_FATAL_FAILURE(doNotSimulateConnections.SetUp(module.get())); for (const auto& port : ports) { - AudioPort portWithData = GenerateUniqueDeviceAddress(port); - EXPECT_STATUS(EX_ILLEGAL_STATE, module->connectExternalDevice(portWithData, &ignored)) - << "static port " << portWithData.toString(); + AudioPort portWithData = GenerateUniqueDeviceAddress(port), connectedPort; + ScopedAStatus status = module->connectExternalDevice(portWithData, &connectedPort); + EXPECT_STATUS(EX_ILLEGAL_STATE, status) << "static port " << portWithData.toString(); + if (status.isOk()) { + EXPECT_IS_OK(module->disconnectExternalDevice(connectedPort.id)) + << "when disconnecting device port ID " << connectedPort.id; + } } }