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