• 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::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