1*4d7e907cSAndroid Build Coastguard Worker /* 2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project 3*4d7e907cSAndroid Build Coastguard Worker * 4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*4d7e907cSAndroid Build Coastguard Worker * 8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*4d7e907cSAndroid Build Coastguard Worker * 10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License. 15*4d7e907cSAndroid Build Coastguard Worker */ 16*4d7e907cSAndroid Build Coastguard Worker 17*4d7e907cSAndroid Build Coastguard Worker #pragma once 18*4d7e907cSAndroid Build Coastguard Worker 19*4d7e907cSAndroid Build Coastguard Worker #include <functional> 20*4d7e907cSAndroid Build Coastguard Worker #include <optional> 21*4d7e907cSAndroid Build Coastguard Worker #include <set> 22*4d7e907cSAndroid Build Coastguard Worker #include <utility> 23*4d7e907cSAndroid Build Coastguard Worker #include <vector> 24*4d7e907cSAndroid Build Coastguard Worker 25*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/core/AudioRoute.h> 26*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/core/IModule.h> 27*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/media/audio/common/AudioOffloadInfo.h> 28*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/media/audio/common/AudioPort.h> 29*4d7e907cSAndroid Build Coastguard Worker 30*4d7e907cSAndroid Build Coastguard Worker class ModuleConfig { 31*4d7e907cSAndroid Build Coastguard Worker public: 32*4d7e907cSAndroid Build Coastguard Worker using SrcSinkPair = std::pair<aidl::android::media::audio::common::AudioPortConfig, 33*4d7e907cSAndroid Build Coastguard Worker aidl::android::media::audio::common::AudioPortConfig>; 34*4d7e907cSAndroid Build Coastguard Worker using SrcSinkGroup = 35*4d7e907cSAndroid Build Coastguard Worker std::pair<aidl::android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>; 36*4d7e907cSAndroid Build Coastguard Worker 37*4d7e907cSAndroid Build Coastguard Worker static std::optional<aidl::android::media::audio::common::AudioOffloadInfo> 38*4d7e907cSAndroid Build Coastguard Worker generateOffloadInfoIfNeeded( 39*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPortConfig& portConfig); 40*4d7e907cSAndroid Build Coastguard Worker 41*4d7e907cSAndroid Build Coastguard Worker static std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes( 42*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioPort>& ports, 43*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes, 44*4d7e907cSAndroid Build Coastguard Worker const std::string& connection = ""); 45*4d7e907cSAndroid Build Coastguard Worker static std::vector<aidl::android::media::audio::common::AudioPort> getBuiltInMicPorts( 46*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioPort>& ports); 47*4d7e907cSAndroid Build Coastguard Worker 48*4d7e907cSAndroid Build Coastguard Worker explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module); getStatus()49*4d7e907cSAndroid Build Coastguard Worker const ndk::ScopedAStatus& getStatus() const { return mStatus; } getError()50*4d7e907cSAndroid Build Coastguard Worker std::string getError() const { return mStatus.getMessage(); } 51*4d7e907cSAndroid Build Coastguard Worker 52*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const; 53*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes( 54*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes, 55*4d7e907cSAndroid Build Coastguard Worker const std::string& connection = "") const; 56*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getConnectedExternalDevicePorts() 57*4d7e907cSAndroid Build Coastguard Worker const; 58*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> getConnectedSinkDevicePorts() const; 59*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> getConnectedSourceDevicePorts() const; getAttachedMicrophonePorts()60*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getAttachedMicrophonePorts() const { 61*4d7e907cSAndroid Build Coastguard Worker return getBuiltInMicPorts(getAttachedDevicePorts()); 62*4d7e907cSAndroid Build Coastguard Worker } 63*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getExternalDevicePorts() const; 64*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getInputMixPorts( 65*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/) const; 66*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getOutputMixPorts( 67*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/) const; getMixPorts(bool isInput,bool connectedOnly)68*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getMixPorts( 69*4d7e907cSAndroid Build Coastguard Worker bool isInput, 70*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/) const { 71*4d7e907cSAndroid Build Coastguard Worker return isInput ? getInputMixPorts(connectedOnly) : getOutputMixPorts(connectedOnly); 72*4d7e907cSAndroid Build Coastguard Worker } 73*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getNonBlockingMixPorts( 74*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/, 75*4d7e907cSAndroid Build Coastguard Worker bool singlePort) const; 76*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getOffloadMixPorts( 77*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/, 78*4d7e907cSAndroid Build Coastguard Worker bool singlePort) const; 79*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getPrimaryMixPorts( 80*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/, 81*4d7e907cSAndroid Build Coastguard Worker bool singlePort) const; 82*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getMmapOutMixPorts( 83*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/, 84*4d7e907cSAndroid Build Coastguard Worker bool singlePort) const; 85*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getMmapInMixPorts( 86*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/, 87*4d7e907cSAndroid Build Coastguard Worker bool singlePort) const; 88*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getRemoteSubmixPorts( 89*4d7e907cSAndroid Build Coastguard Worker bool isInput, bool singlePort) const; 90*4d7e907cSAndroid Build Coastguard Worker getConnectedDevicesPortsForMixPort(bool isInput,const aidl::android::media::audio::common::AudioPort & mixPort)91*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort( 92*4d7e907cSAndroid Build Coastguard Worker bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const { 93*4d7e907cSAndroid Build Coastguard Worker return isInput ? getConnectedSourceDevicesPortsForMixPort(mixPort) 94*4d7e907cSAndroid Build Coastguard Worker : getConnectedSinkDevicesPortsForMixPort(mixPort); 95*4d7e907cSAndroid Build Coastguard Worker } 96*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort( 97*4d7e907cSAndroid Build Coastguard Worker bool isInput, 98*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const; 99*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> 100*4d7e907cSAndroid Build Coastguard Worker getConnectedSinkDevicesPortsForMixPort( 101*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& mixPort) const; 102*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> 103*4d7e907cSAndroid Build Coastguard Worker getConnectedSourceDevicesPortsForMixPort( 104*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& mixPort) const; 105*4d7e907cSAndroid Build Coastguard Worker std::optional<aidl::android::media::audio::common::AudioPort> 106*4d7e907cSAndroid Build Coastguard Worker getSourceMixPortForConnectedDevice() const; 107*4d7e907cSAndroid Build Coastguard Worker 108*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getRoutableDevicePortsForMixPort( 109*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port, 110*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/) const; 111*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> getRoutableMixPortsForDevicePort( 112*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port, 113*4d7e907cSAndroid Build Coastguard Worker bool connectedOnly /*Permanently attached and connected external devices*/) const; 114*4d7e907cSAndroid Build Coastguard Worker 115*4d7e907cSAndroid Build Coastguard Worker std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const; 116*4d7e907cSAndroid Build Coastguard Worker std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const; 117*4d7e907cSAndroid Build Coastguard Worker std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const; 118*4d7e907cSAndroid Build Coastguard Worker 119*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForAttachedDevicePorts()120*4d7e907cSAndroid Build Coastguard Worker getPortConfigsForAttachedDevicePorts() const { 121*4d7e907cSAndroid Build Coastguard Worker return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false); 122*4d7e907cSAndroid Build Coastguard Worker } getPortConfigsForMixPorts()123*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts() 124*4d7e907cSAndroid Build Coastguard Worker const { 125*4d7e907cSAndroid Build Coastguard Worker auto inputs = 126*4d7e907cSAndroid Build Coastguard Worker generateAudioMixPortConfigs(getInputMixPorts(false /*connectedOnly*/), true, false); 127*4d7e907cSAndroid Build Coastguard Worker auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(false /*connectedOnly*/), 128*4d7e907cSAndroid Build Coastguard Worker false, false); 129*4d7e907cSAndroid Build Coastguard Worker inputs.insert(inputs.end(), outputs.begin(), outputs.end()); 130*4d7e907cSAndroid Build Coastguard Worker return inputs; 131*4d7e907cSAndroid Build Coastguard Worker } getPortConfigsForMixPorts(bool isInput)132*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts( 133*4d7e907cSAndroid Build Coastguard Worker bool isInput) const { 134*4d7e907cSAndroid Build Coastguard Worker return generateAudioMixPortConfigs(getMixPorts(isInput, false /*connectedOnly*/), isInput, 135*4d7e907cSAndroid Build Coastguard Worker false); 136*4d7e907cSAndroid Build Coastguard Worker } getPortConfigsForMixPorts(bool isInput,const aidl::android::media::audio::common::AudioPort & port)137*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts( 138*4d7e907cSAndroid Build Coastguard Worker bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { 139*4d7e907cSAndroid Build Coastguard Worker return generateAudioMixPortConfigs({port}, isInput, false); 140*4d7e907cSAndroid Build Coastguard Worker } getSingleConfigForMixPort(bool isInput)141*4d7e907cSAndroid Build Coastguard Worker std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort( 142*4d7e907cSAndroid Build Coastguard Worker bool isInput) const { 143*4d7e907cSAndroid Build Coastguard Worker const auto config = generateAudioMixPortConfigs( 144*4d7e907cSAndroid Build Coastguard Worker getMixPorts(isInput, false /*connectedOnly*/), isInput, true); 145*4d7e907cSAndroid Build Coastguard Worker if (!config.empty()) { 146*4d7e907cSAndroid Build Coastguard Worker return *config.begin(); 147*4d7e907cSAndroid Build Coastguard Worker } 148*4d7e907cSAndroid Build Coastguard Worker return {}; 149*4d7e907cSAndroid Build Coastguard Worker } getSingleConfigForMixPort(bool isInput,const aidl::android::media::audio::common::AudioPort & port)150*4d7e907cSAndroid Build Coastguard Worker std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort( 151*4d7e907cSAndroid Build Coastguard Worker bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { 152*4d7e907cSAndroid Build Coastguard Worker const auto config = generateAudioMixPortConfigs({port}, isInput, true); 153*4d7e907cSAndroid Build Coastguard Worker if (!config.empty()) { 154*4d7e907cSAndroid Build Coastguard Worker return *config.begin(); 155*4d7e907cSAndroid Build Coastguard Worker } 156*4d7e907cSAndroid Build Coastguard Worker return {}; 157*4d7e907cSAndroid Build Coastguard Worker } 158*4d7e907cSAndroid Build Coastguard Worker getPortConfigsForDevicePort(const aidl::android::media::audio::common::AudioPort & port)159*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort( 160*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port) const { 161*4d7e907cSAndroid Build Coastguard Worker return generateAudioDevicePortConfigs({port}, false); 162*4d7e907cSAndroid Build Coastguard Worker } getSingleConfigForDevicePort(const aidl::android::media::audio::common::AudioPort & port)163*4d7e907cSAndroid Build Coastguard Worker aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort( 164*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port) const { 165*4d7e907cSAndroid Build Coastguard Worker const auto config = generateAudioDevicePortConfigs({port}, true); 166*4d7e907cSAndroid Build Coastguard Worker return *config.begin(); 167*4d7e907cSAndroid Build Coastguard Worker } 168*4d7e907cSAndroid Build Coastguard Worker 169*4d7e907cSAndroid Build Coastguard Worker std::optional<aidl::android::media::audio::common::AudioPort> getPort(int32_t portId); 170*4d7e907cSAndroid Build Coastguard Worker 171*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus onExternalDeviceConnected( 172*4d7e907cSAndroid Build Coastguard Worker aidl::android::hardware::audio::core::IModule* module, 173*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port); 174*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus onExternalDeviceDisconnected( 175*4d7e907cSAndroid Build Coastguard Worker aidl::android::hardware::audio::core::IModule* module, 176*4d7e907cSAndroid Build Coastguard Worker const aidl::android::media::audio::common::AudioPort& port); 177*4d7e907cSAndroid Build Coastguard Worker 178*4d7e907cSAndroid Build Coastguard Worker bool isMmapSupported() const; 179*4d7e907cSAndroid Build Coastguard Worker 180*4d7e907cSAndroid Build Coastguard Worker std::string toString() const; 181*4d7e907cSAndroid Build Coastguard Worker 182*4d7e907cSAndroid Build Coastguard Worker private: 183*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> findMixPorts( 184*4d7e907cSAndroid Build Coastguard Worker bool isInput, bool connectedOnly, bool singlePort, 185*4d7e907cSAndroid Build Coastguard Worker const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred) 186*4d7e907cSAndroid Build Coastguard Worker const; 187*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> findRoutablePortIds(int32_t portId) const; 188*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs( 189*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput, 190*4d7e907cSAndroid Build Coastguard Worker bool singleProfile) const; 191*4d7e907cSAndroid Build Coastguard Worker 192*4d7e907cSAndroid Build Coastguard Worker // Unlike MixPorts, the generator for DevicePorts always returns a non-empty 193*4d7e907cSAndroid Build Coastguard Worker // vector for a non-empty input port list. If there are no profiles in the 194*4d7e907cSAndroid Build Coastguard Worker // port, its initial configs are looked up, if there are none, 195*4d7e907cSAndroid Build Coastguard Worker // then an empty config is used, assuming further negotiation via setAudioPortConfig. 196*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> 197*4d7e907cSAndroid Build Coastguard Worker generateAudioDevicePortConfigs( 198*4d7e907cSAndroid Build Coastguard Worker const std::vector<aidl::android::media::audio::common::AudioPort>& ports, 199*4d7e907cSAndroid Build Coastguard Worker bool singleProfile) const; 200*4d7e907cSAndroid Build Coastguard Worker 201*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok(); 202*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPort> mPorts; 203*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::media::audio::common::AudioPortConfig> mInitialConfigs; 204*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> mAttachedSinkDevicePorts; 205*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> mAttachedSourceDevicePorts; 206*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> mExternalDevicePorts; 207*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> mConnectedExternalSinkDevicePorts; 208*4d7e907cSAndroid Build Coastguard Worker std::set<int32_t> mConnectedExternalSourceDevicePorts; 209*4d7e907cSAndroid Build Coastguard Worker std::vector<aidl::android::hardware::audio::core::AudioRoute> mRoutes; 210*4d7e907cSAndroid Build Coastguard Worker }; 211