/* * Copyright (C) 2022 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 #include #include #include #include #include #include #include class ModuleConfig { public: using SrcSinkPair = std::pair; using SrcSinkGroup = std::pair>; static std::optional generateOffloadInfoIfNeeded( const aidl::android::media::audio::common::AudioPortConfig& portConfig); static std::vector getBuiltInMicPorts( const std::vector& ports); explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module); const ndk::ScopedAStatus& getStatus() const { return mStatus; } std::string getError() const { return mStatus.getMessage(); } std::vector getAttachedDevicePorts() const; std::vector getAttachedMicrophonePorts() const { return getBuiltInMicPorts(getAttachedDevicePorts()); } std::vector getExternalDevicePorts() const; std::vector getInputMixPorts( bool attachedOnly) const; std::vector getOutputMixPorts( bool attachedOnly) const; std::vector getMixPorts( bool isInput, bool attachedOnly) const { return isInput ? getInputMixPorts(attachedOnly) : getOutputMixPorts(attachedOnly); } std::vector getNonBlockingMixPorts( bool attachedOnly, bool singlePort) const; std::vector getOffloadMixPorts( bool attachedOnly, bool singlePort) const; std::vector getPrimaryMixPorts( bool attachedOnly, bool singlePort) const; std::vector getMmapOutMixPorts( bool attachedOnly, bool singlePort) const; std::vector getMmapInMixPorts( bool attachedOnly, bool singlePort) const; std::vector getAttachedDevicesPortsForMixPort( bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const { return isInput ? getAttachedSourceDevicesPortsForMixPort(mixPort) : getAttachedSinkDevicesPortsForMixPort(mixPort); } std::vector getAttachedDevicesPortsForMixPort( bool isInput, const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const; std::vector getAttachedSinkDevicesPortsForMixPort( const aidl::android::media::audio::common::AudioPort& mixPort) const; std::vector getAttachedSourceDevicesPortsForMixPort( const aidl::android::media::audio::common::AudioPort& mixPort) const; std::optional getSourceMixPortForAttachedDevice() const; std::optional getNonRoutableSrcSinkPair(bool isInput) const; std::optional getRoutableSrcSinkPair(bool isInput) const; std::vector getRoutableSrcSinkGroups(bool isInput) const; std::vector getPortConfigsForAttachedDevicePorts() const { return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false); } std::vector getPortConfigsForMixPorts() const { auto inputs = generateAudioMixPortConfigs(getInputMixPorts(false /*attachedOnly*/), true, false); auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(false /*attachedOnly*/), false, false); inputs.insert(inputs.end(), outputs.begin(), outputs.end()); return inputs; } std::vector getPortConfigsForMixPorts( bool isInput) const { return generateAudioMixPortConfigs(getMixPorts(isInput, false /*attachedOnly*/), isInput, false); } std::vector getPortConfigsForMixPorts( bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { return generateAudioMixPortConfigs({port}, isInput, false); } std::optional getSingleConfigForMixPort( bool isInput) const { const auto config = generateAudioMixPortConfigs( getMixPorts(isInput, false /*attachedOnly*/), isInput, true); if (!config.empty()) { return *config.begin(); } return {}; } std::optional getSingleConfigForMixPort( bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { const auto config = generateAudioMixPortConfigs({port}, isInput, true); if (!config.empty()) { return *config.begin(); } return {}; } std::vector getPortConfigsForDevicePort( const aidl::android::media::audio::common::AudioPort& port) const { return generateAudioDevicePortConfigs({port}, false); } aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort( const aidl::android::media::audio::common::AudioPort& port) const { const auto config = generateAudioDevicePortConfigs({port}, true); return *config.begin(); } bool isMmapSupported() const; std::string toString() const; private: std::vector findMixPorts( bool isInput, bool attachedOnly, bool singlePort, const std::function& pred) const; std::vector generateAudioMixPortConfigs( const std::vector& ports, bool isInput, bool singleProfile) const; // Unlike MixPorts, the generator for DevicePorts always returns a non-empty // vector for a non-empty input port list. If there are no profiles in the // port, its initial configs are looked up, if there are none, // then an empty config is used, assuming further negotiation via setAudioPortConfig. std::vector generateAudioDevicePortConfigs( const std::vector& ports, bool singleProfile) const; ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok(); std::vector mPorts; std::vector mInitialConfigs; std::set mAttachedSinkDevicePorts; std::set mAttachedSourceDevicePorts; std::set mExternalDevicePorts; std::vector mRoutes; };