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 std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes( 42 const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes, 43 const std::string& connection = ""); 44 static std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes( 45 const std::vector<aidl::android::media::audio::common::AudioPort>& ports, 46 const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes, 47 const std::string& connection = ""); 48 static std::vector<aidl::android::media::audio::common::AudioPort> getBuiltInMicPorts( 49 const std::vector<aidl::android::media::audio::common::AudioPort>& ports); 50 51 explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module); getStatus()52 const ndk::ScopedAStatus& getStatus() const { return mStatus; } getError()53 std::string getError() const { return mStatus.getMessage(); } 54 55 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() 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 getConnectedDevicesPortsForMixPort(bool isInput,const aidl::android::media::audio::common::AudioPort & mixPort)89 std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort( 90 bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const { 91 return isInput ? getConnectedSourceDevicesPortsForMixPort(mixPort) 92 : getConnectedSinkDevicesPortsForMixPort(mixPort); 93 } 94 std::vector<aidl::android::media::audio::common::AudioPort> getConnectedDevicesPortsForMixPort( 95 bool isInput, 96 const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const; 97 std::vector<aidl::android::media::audio::common::AudioPort> 98 getConnectedSinkDevicesPortsForMixPort( 99 const aidl::android::media::audio::common::AudioPort& mixPort) const; 100 std::vector<aidl::android::media::audio::common::AudioPort> 101 getConnectedSourceDevicesPortsForMixPort( 102 const aidl::android::media::audio::common::AudioPort& mixPort) const; 103 std::optional<aidl::android::media::audio::common::AudioPort> 104 getSourceMixPortForConnectedDevice() const; 105 106 std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const; 107 std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const; 108 std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const; 109 110 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForAttachedDevicePorts()111 getPortConfigsForAttachedDevicePorts() const { 112 return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false); 113 } getPortConfigsForMixPorts()114 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts() 115 const { 116 auto inputs = 117 generateAudioMixPortConfigs(getInputMixPorts(false /*connectedOnly*/), true, false); 118 auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(false /*connectedOnly*/), 119 false, false); 120 inputs.insert(inputs.end(), outputs.begin(), outputs.end()); 121 return inputs; 122 } getPortConfigsForMixPorts(bool isInput)123 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts( 124 bool isInput) const { 125 return generateAudioMixPortConfigs(getMixPorts(isInput, false /*connectedOnly*/), isInput, 126 false); 127 } getPortConfigsForMixPorts(bool isInput,const aidl::android::media::audio::common::AudioPort & port)128 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts( 129 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { 130 return generateAudioMixPortConfigs({port}, isInput, false); 131 } getSingleConfigForMixPort(bool isInput)132 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort( 133 bool isInput) const { 134 const auto config = generateAudioMixPortConfigs( 135 getMixPorts(isInput, false /*connectedOnly*/), isInput, true); 136 if (!config.empty()) { 137 return *config.begin(); 138 } 139 return {}; 140 } getSingleConfigForMixPort(bool isInput,const aidl::android::media::audio::common::AudioPort & port)141 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort( 142 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const { 143 const auto config = generateAudioMixPortConfigs({port}, isInput, true); 144 if (!config.empty()) { 145 return *config.begin(); 146 } 147 return {}; 148 } 149 getPortConfigsForDevicePort(const aidl::android::media::audio::common::AudioPort & port)150 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort( 151 const aidl::android::media::audio::common::AudioPort& port) const { 152 return generateAudioDevicePortConfigs({port}, false); 153 } getSingleConfigForDevicePort(const aidl::android::media::audio::common::AudioPort & port)154 aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort( 155 const aidl::android::media::audio::common::AudioPort& port) const { 156 const auto config = generateAudioDevicePortConfigs({port}, true); 157 return *config.begin(); 158 } 159 160 const ndk::ScopedAStatus& onExternalDeviceConnected( 161 aidl::android::hardware::audio::core::IModule* module, 162 const aidl::android::media::audio::common::AudioPort& port); 163 const ndk::ScopedAStatus& onExternalDeviceDisconnected( 164 aidl::android::hardware::audio::core::IModule* module, 165 const aidl::android::media::audio::common::AudioPort& port); 166 167 bool isMmapSupported() const; 168 169 std::string toString() const; 170 171 private: 172 std::vector<aidl::android::media::audio::common::AudioPort> findMixPorts( 173 bool isInput, bool connectedOnly, bool singlePort, 174 const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred) 175 const; 176 std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs( 177 const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput, 178 bool singleProfile) const; 179 180 // Unlike MixPorts, the generator for DevicePorts always returns a non-empty 181 // vector for a non-empty input port list. If there are no profiles in the 182 // port, its initial configs are looked up, if there are none, 183 // then an empty config is used, assuming further negotiation via setAudioPortConfig. 184 std::vector<aidl::android::media::audio::common::AudioPortConfig> 185 generateAudioDevicePortConfigs( 186 const std::vector<aidl::android::media::audio::common::AudioPort>& ports, 187 bool singleProfile) const; 188 189 ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok(); 190 std::vector<aidl::android::media::audio::common::AudioPort> mPorts; 191 std::vector<aidl::android::media::audio::common::AudioPortConfig> mInitialConfigs; 192 std::set<int32_t> mAttachedSinkDevicePorts; 193 std::set<int32_t> mAttachedSourceDevicePorts; 194 std::set<int32_t> mExternalDevicePorts; 195 std::set<int32_t> mConnectedExternalSinkDevicePorts; 196 std::set<int32_t> mConnectedExternalSourceDevicePorts; 197 std::vector<aidl::android::hardware::audio::core::AudioRoute> mRoutes; 198 }; 199