blob: 7247f3b5822959f1e7d948911ed8b07d61855817 [file] [log] [blame]
Mikhail Naganove5d747e2021-11-16 01:31:03 +00001/*
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
Mikhail Naganov30301a42022-09-13 01:20:45 +000019#include <functional>
Mikhail Naganove5d747e2021-11-16 01:31:03 +000020#include <optional>
21#include <set>
22#include <utility>
23#include <vector>
24
Mikhail Naganovf84d6402022-06-16 00:35:31 +000025#include <aidl/android/hardware/audio/core/AudioRoute.h>
26#include <aidl/android/hardware/audio/core/IModule.h>
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000027#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
Mikhail Naganovf84d6402022-06-16 00:35:31 +000028#include <aidl/android/media/audio/common/AudioPort.h>
Mikhail Naganove5d747e2021-11-16 01:31:03 +000029
30class ModuleConfig {
31 public:
Mikhail Naganovf84d6402022-06-16 00:35:31 +000032 using SrcSinkPair = std::pair<aidl::android::media::audio::common::AudioPortConfig,
33 aidl::android::media::audio::common::AudioPortConfig>;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000034 using SrcSinkGroup =
Mikhail Naganovf84d6402022-06-16 00:35:31 +000035 std::pair<aidl::android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000036
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000037 static std::optional<aidl::android::media::audio::common::AudioOffloadInfo>
38 generateOffloadInfoIfNeeded(
39 const aidl::android::media::audio::common::AudioPortConfig& portConfig);
Mikhail Naganovef6bc742022-10-06 00:14:19 +000040 static std::vector<aidl::android::media::audio::common::AudioPort> getBuiltInMicPorts(
41 const std::vector<aidl::android::media::audio::common::AudioPort>& ports);
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000042
Mikhail Naganovf84d6402022-06-16 00:35:31 +000043 explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module);
44 const ndk::ScopedAStatus& getStatus() const { return mStatus; }
45 std::string getError() const { return mStatus.getMessage(); }
Mikhail Naganove5d747e2021-11-16 01:31:03 +000046
Mikhail Naganovf84d6402022-06-16 00:35:31 +000047 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
Mikhail Naganovef6bc742022-10-06 00:14:19 +000048 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedMicrophonePorts() const {
49 return getBuiltInMicPorts(getAttachedDevicePorts());
50 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000051 std::vector<aidl::android::media::audio::common::AudioPort> getExternalDevicePorts() const;
Mikhail Naganovef6bc742022-10-06 00:14:19 +000052 std::vector<aidl::android::media::audio::common::AudioPort> getInputMixPorts(
53 bool attachedOnly) const;
54 std::vector<aidl::android::media::audio::common::AudioPort> getOutputMixPorts(
55 bool attachedOnly) const;
56 std::vector<aidl::android::media::audio::common::AudioPort> getMixPorts(
57 bool isInput, bool attachedOnly) const {
58 return isInput ? getInputMixPorts(attachedOnly) : getOutputMixPorts(attachedOnly);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000059 }
Mikhail Naganov30301a42022-09-13 01:20:45 +000060 std::vector<aidl::android::media::audio::common::AudioPort> getNonBlockingMixPorts(
61 bool attachedOnly, bool singlePort) const;
Mikhail Naganova2c5ddf2022-09-12 22:57:14 +000062 std::vector<aidl::android::media::audio::common::AudioPort> getOffloadMixPorts(
63 bool attachedOnly, bool singlePort) const;
Mikhail Naganovef6bc742022-10-06 00:14:19 +000064 std::vector<aidl::android::media::audio::common::AudioPort> getPrimaryMixPorts(
65 bool attachedOnly, bool singlePort) const;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000066
Mikhail Naganovf84d6402022-06-16 00:35:31 +000067 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
68 bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +000069 return isInput ? getAttachedSourceDevicesPortsForMixPort(mixPort)
70 : getAttachedSinkDevicesPortsForMixPort(mixPort);
71 }
Mikhail Naganov4f5d3f12022-07-22 23:23:25 +000072 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
73 bool isInput,
74 const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const;
Mikhail Naganovf84d6402022-06-16 00:35:31 +000075 std::vector<aidl::android::media::audio::common::AudioPort>
76 getAttachedSinkDevicesPortsForMixPort(
77 const aidl::android::media::audio::common::AudioPort& mixPort) const;
78 std::vector<aidl::android::media::audio::common::AudioPort>
79 getAttachedSourceDevicesPortsForMixPort(
80 const aidl::android::media::audio::common::AudioPort& mixPort) const;
81 std::optional<aidl::android::media::audio::common::AudioPort>
82 getSourceMixPortForAttachedDevice() const;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000083
84 std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
85 std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
86 std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const;
87
Mikhail Naganovf84d6402022-06-16 00:35:31 +000088 std::vector<aidl::android::media::audio::common::AudioPortConfig>
Mikhail Naganov00603d12022-05-02 22:52:13 +000089 getPortConfigsForAttachedDevicePorts() const {
90 return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false);
91 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000092 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts()
93 const {
Mikhail Naganovef6bc742022-10-06 00:14:19 +000094 auto inputs =
95 generateAudioMixPortConfigs(getInputMixPorts(false /*attachedOnly*/), true, false);
96 auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(false /*attachedOnly*/), false,
97 false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000098 inputs.insert(inputs.end(), outputs.begin(), outputs.end());
99 return inputs;
100 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000101 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000102 bool isInput) const {
Mikhail Naganovef6bc742022-10-06 00:14:19 +0000103 return generateAudioMixPortConfigs(getMixPorts(isInput, false /*attachedOnly*/), isInput,
104 false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000105 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000106 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
107 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000108 return generateAudioMixPortConfigs({port}, isInput, false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000109 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000110 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000111 bool isInput) const {
Mikhail Naganovef6bc742022-10-06 00:14:19 +0000112 const auto config = generateAudioMixPortConfigs(
113 getMixPorts(isInput, false /*attachedOnly*/), isInput, true);
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000114 if (!config.empty()) {
115 return *config.begin();
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000116 }
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000117 return {};
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000118 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000119 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
120 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000121 const auto config = generateAudioMixPortConfigs({port}, isInput, true);
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000122 if (!config.empty()) {
123 return *config.begin();
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000124 }
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000125 return {};
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000126 }
127
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000128 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort(
129 const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov00603d12022-05-02 22:52:13 +0000130 return generateAudioDevicePortConfigs({port}, false);
131 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000132 aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort(
133 const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000134 const auto config = generateAudioDevicePortConfigs({port}, true);
135 return *config.begin();
136 }
137
Mikhail Naganov00603d12022-05-02 22:52:13 +0000138 std::string toString() const;
139
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000140 private:
Mikhail Naganov30301a42022-09-13 01:20:45 +0000141 std::vector<aidl::android::media::audio::common::AudioPort> findMixPorts(
Mikhail Naganovef6bc742022-10-06 00:14:19 +0000142 bool isInput, bool attachedOnly, bool singlePort,
143 const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred)
144 const;
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000145 std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs(
146 const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput,
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000147 bool singleProfile) const;
148
149 // Unlike MixPorts, the generator for DevicePorts always returns a non-empty
150 // vector for a non-empty input port list. If there are no profiles in the
Mikhail Naganov00603d12022-05-02 22:52:13 +0000151 // port, its initial configs are looked up, if there are none,
152 // then an empty config is used, assuming further negotiation via setAudioPortConfig.
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000153 std::vector<aidl::android::media::audio::common::AudioPortConfig>
154 generateAudioDevicePortConfigs(
155 const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000156 bool singleProfile) const;
157
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000158 ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok();
159 std::vector<aidl::android::media::audio::common::AudioPort> mPorts;
160 std::vector<aidl::android::media::audio::common::AudioPortConfig> mInitialConfigs;
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000161 std::set<int32_t> mAttachedSinkDevicePorts;
162 std::set<int32_t> mAttachedSourceDevicePorts;
Mikhail Naganov00603d12022-05-02 22:52:13 +0000163 std::set<int32_t> mExternalDevicePorts;
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000164 std::vector<aidl::android::hardware::audio::core::AudioRoute> mRoutes;
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000165};