• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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