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