blob: dc109a792f59ac8f0ffacd6d3996d3a2d2d6d78a [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
19#include <optional>
20#include <set>
21#include <utility>
22#include <vector>
23
Mikhail Naganovf84d6402022-06-16 00:35:31 +000024#include <aidl/android/hardware/audio/core/AudioRoute.h>
25#include <aidl/android/hardware/audio/core/IModule.h>
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000026#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
Mikhail Naganovf84d6402022-06-16 00:35:31 +000027#include <aidl/android/media/audio/common/AudioPort.h>
Mikhail Naganove5d747e2021-11-16 01:31:03 +000028
29class ModuleConfig {
30 public:
Mikhail Naganovf84d6402022-06-16 00:35:31 +000031 using SrcSinkPair = std::pair<aidl::android::media::audio::common::AudioPortConfig,
32 aidl::android::media::audio::common::AudioPortConfig>;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000033 using SrcSinkGroup =
Mikhail Naganovf84d6402022-06-16 00:35:31 +000034 std::pair<aidl::android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000035
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000036 static std::optional<aidl::android::media::audio::common::AudioOffloadInfo>
37 generateOffloadInfoIfNeeded(
38 const aidl::android::media::audio::common::AudioPortConfig& portConfig);
39
Mikhail Naganovf84d6402022-06-16 00:35:31 +000040 explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module);
41 const ndk::ScopedAStatus& getStatus() const { return mStatus; }
42 std::string getError() const { return mStatus.getMessage(); }
Mikhail Naganove5d747e2021-11-16 01:31:03 +000043
Mikhail Naganovf84d6402022-06-16 00:35:31 +000044 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
45 std::vector<aidl::android::media::audio::common::AudioPort> getExternalDevicePorts() const;
46 std::vector<aidl::android::media::audio::common::AudioPort> getInputMixPorts() const;
47 std::vector<aidl::android::media::audio::common::AudioPort> getOutputMixPorts() const;
48 std::vector<aidl::android::media::audio::common::AudioPort> getMixPorts(bool isInput) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +000049 return isInput ? getInputMixPorts() : getOutputMixPorts();
50 }
Mikhail Naganova2c5ddf2022-09-12 22:57:14 +000051 std::vector<aidl::android::media::audio::common::AudioPort> getOffloadMixPorts(
52 bool attachedOnly, bool singlePort) const;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000053
Mikhail Naganovf84d6402022-06-16 00:35:31 +000054 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
55 bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +000056 return isInput ? getAttachedSourceDevicesPortsForMixPort(mixPort)
57 : getAttachedSinkDevicesPortsForMixPort(mixPort);
58 }
Mikhail Naganov4f5d3f12022-07-22 23:23:25 +000059 std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
60 bool isInput,
61 const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const;
Mikhail Naganovf84d6402022-06-16 00:35:31 +000062 std::vector<aidl::android::media::audio::common::AudioPort>
63 getAttachedSinkDevicesPortsForMixPort(
64 const aidl::android::media::audio::common::AudioPort& mixPort) const;
65 std::vector<aidl::android::media::audio::common::AudioPort>
66 getAttachedSourceDevicesPortsForMixPort(
67 const aidl::android::media::audio::common::AudioPort& mixPort) const;
68 std::optional<aidl::android::media::audio::common::AudioPort>
69 getSourceMixPortForAttachedDevice() const;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000070
71 std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
72 std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
73 std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const;
74
Mikhail Naganovf84d6402022-06-16 00:35:31 +000075 std::vector<aidl::android::media::audio::common::AudioPortConfig>
Mikhail Naganov00603d12022-05-02 22:52:13 +000076 getPortConfigsForAttachedDevicePorts() const {
77 return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false);
78 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000079 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts()
80 const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000081 auto inputs = generateAudioMixPortConfigs(getInputMixPorts(), true, false);
82 auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(), false, false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000083 inputs.insert(inputs.end(), outputs.begin(), outputs.end());
84 return inputs;
85 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000086 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
Mikhail Naganove5d747e2021-11-16 01:31:03 +000087 bool isInput) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000088 return generateAudioMixPortConfigs(getMixPorts(isInput), isInput, false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000089 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000090 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
91 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000092 return generateAudioMixPortConfigs({port}, isInput, false);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000093 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +000094 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
Mikhail Naganove5d747e2021-11-16 01:31:03 +000095 bool isInput) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000096 const auto config = generateAudioMixPortConfigs(getMixPorts(isInput), isInput, true);
Mikhail Naganove5d747e2021-11-16 01:31:03 +000097 if (!config.empty()) {
98 return *config.begin();
Mikhail Naganove5d747e2021-11-16 01:31:03 +000099 }
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000100 return {};
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000101 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000102 std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
103 bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000104 const auto config = generateAudioMixPortConfigs({port}, isInput, true);
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000105 if (!config.empty()) {
106 return *config.begin();
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000107 }
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000108 return {};
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000109 }
110
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000111 std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort(
112 const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganov00603d12022-05-02 22:52:13 +0000113 return generateAudioDevicePortConfigs({port}, false);
114 }
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000115 aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort(
116 const aidl::android::media::audio::common::AudioPort& port) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000117 const auto config = generateAudioDevicePortConfigs({port}, true);
118 return *config.begin();
119 }
120
Mikhail Naganov00603d12022-05-02 22:52:13 +0000121 std::string toString() const;
122
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000123 private:
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000124 std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs(
125 const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput,
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000126 bool singleProfile) const;
127
128 // Unlike MixPorts, the generator for DevicePorts always returns a non-empty
129 // vector for a non-empty input port list. If there are no profiles in the
Mikhail Naganov00603d12022-05-02 22:52:13 +0000130 // port, its initial configs are looked up, if there are none,
131 // then an empty config is used, assuming further negotiation via setAudioPortConfig.
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000132 std::vector<aidl::android::media::audio::common::AudioPortConfig>
133 generateAudioDevicePortConfigs(
134 const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000135 bool singleProfile) const;
136
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000137 ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok();
138 std::vector<aidl::android::media::audio::common::AudioPort> mPorts;
139 std::vector<aidl::android::media::audio::common::AudioPortConfig> mInitialConfigs;
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000140 std::set<int32_t> mAttachedSinkDevicePorts;
141 std::set<int32_t> mAttachedSourceDevicePorts;
Mikhail Naganov00603d12022-05-02 22:52:13 +0000142 std::set<int32_t> mExternalDevicePorts;
Mikhail Naganovf84d6402022-06-16 00:35:31 +0000143 std::vector<aidl::android::hardware::audio::core::AudioRoute> mRoutes;
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000144};