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