blob: 0e2738b3060a25efb4ee1c044fa317cc5ad38a1b [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
24#include <android/hardware/audio/core/AudioRoute.h>
25#include <android/hardware/audio/core/IModule.h>
26#include <android/media/audio/common/AudioPort.h>
27#include <binder/Status.h>
28
29class ModuleConfig {
30 public:
31 using SrcSinkPair = std::pair<android::media::audio::common::AudioPortConfig,
32 android::media::audio::common::AudioPortConfig>;
33 using SrcSinkGroup =
34 std::pair<android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>;
35
36 explicit ModuleConfig(android::hardware::audio::core::IModule* module);
37 android::binder::Status getStatus() const { return mStatus; }
38 std::string getError() const { return mStatus.toString8().c_str(); }
39
Mikhail Naganov00603d12022-05-02 22:52:13 +000040 std::vector<android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
41 std::vector<android::media::audio::common::AudioPort> getExternalDevicePorts() const;
Mikhail Naganove5d747e2021-11-16 01:31:03 +000042 std::vector<android::media::audio::common::AudioPort> getInputMixPorts() const;
43 std::vector<android::media::audio::common::AudioPort> getOutputMixPorts() const;
44 std::vector<android::media::audio::common::AudioPort> getMixPorts(bool isInput) const {
45 return isInput ? getInputMixPorts() : getOutputMixPorts();
46 }
47
48 std::vector<android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
49 bool isInput, const android::media::audio::common::AudioPort& mixPort) const {
50 return isInput ? getAttachedSourceDevicesPortsForMixPort(mixPort)
51 : getAttachedSinkDevicesPortsForMixPort(mixPort);
52 }
53 std::vector<android::media::audio::common::AudioPort> getAttachedSinkDevicesPortsForMixPort(
54 const android::media::audio::common::AudioPort& mixPort) const;
55 std::vector<android::media::audio::common::AudioPort> getAttachedSourceDevicesPortsForMixPort(
56 const android::media::audio::common::AudioPort& mixPort) const;
57 std::optional<android::media::audio::common::AudioPort> getSourceMixPortForAttachedDevice()
58 const;
59
60 std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
61 std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
62 std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const;
63
Mikhail Naganov00603d12022-05-02 22:52:13 +000064 std::vector<android::media::audio::common::AudioPortConfig>
65 getPortConfigsForAttachedDevicePorts() const {
66 return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false);
67 }
Mikhail Naganove5d747e2021-11-16 01:31:03 +000068 std::vector<android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts() const {
69 auto inputs = generateInputAudioMixPortConfigs(getInputMixPorts(), false);
70 auto outputs = generateOutputAudioMixPortConfigs(getOutputMixPorts(), false);
71 inputs.insert(inputs.end(), outputs.begin(), outputs.end());
72 return inputs;
73 }
74 std::vector<android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
75 bool isInput) const {
76 return isInput ? generateInputAudioMixPortConfigs(getInputMixPorts(), false)
77 : generateOutputAudioMixPortConfigs(getOutputMixPorts(), false);
78 }
79 std::vector<android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
80 bool isInput, const android::media::audio::common::AudioPort& port) const {
81 return isInput ? generateInputAudioMixPortConfigs({port}, false)
82 : generateOutputAudioMixPortConfigs({port}, false);
83 }
84 std::optional<android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
85 bool isInput) const {
86 const auto config = isInput ? generateInputAudioMixPortConfigs(getInputMixPorts(), true)
87 : generateOutputAudioMixPortConfigs(getOutputMixPorts(), true);
88 // TODO: Avoid returning configs for offload since they require an extra
89 // argument to openOutputStream.
90 if (!config.empty()) {
91 return *config.begin();
92 } else {
93 return {};
94 }
95 }
96 std::optional<android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
97 bool isInput, const android::media::audio::common::AudioPort& port) const {
98 const auto config = isInput ? generateInputAudioMixPortConfigs({port}, true)
99 : generateOutputAudioMixPortConfigs({port}, true);
100 if (!config.empty()) {
101 return *config.begin();
102 } else {
103 return {};
104 }
105 }
106
Mikhail Naganov00603d12022-05-02 22:52:13 +0000107 std::vector<android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort(
108 const android::media::audio::common::AudioPort& port) const {
109 return generateAudioDevicePortConfigs({port}, false);
110 }
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000111 android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort(
112 const android::media::audio::common::AudioPort& port) const {
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000113 const auto config = generateAudioDevicePortConfigs({port}, true);
114 return *config.begin();
115 }
116
Mikhail Naganov00603d12022-05-02 22:52:13 +0000117 std::string toString() const;
118
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000119 private:
120 std::vector<android::media::audio::common::AudioPortConfig> generateInputAudioMixPortConfigs(
121 const std::vector<android::media::audio::common::AudioPort>& ports,
122 bool singleProfile) const;
123 std::vector<android::media::audio::common::AudioPortConfig> generateOutputAudioMixPortConfigs(
124 const std::vector<android::media::audio::common::AudioPort>& ports,
125 bool singleProfile) const;
126
127 // Unlike MixPorts, the generator for DevicePorts always returns a non-empty
128 // vector for a non-empty input port list. If there are no profiles in the
Mikhail Naganov00603d12022-05-02 22:52:13 +0000129 // port, its initial configs are looked up, if there are none,
130 // then an empty config is used, assuming further negotiation via setAudioPortConfig.
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000131 std::vector<android::media::audio::common::AudioPortConfig> generateAudioDevicePortConfigs(
132 const std::vector<android::media::audio::common::AudioPort>& ports,
133 bool singleProfile) const;
134
135 android::binder::Status mStatus = android::binder::Status::ok();
136 std::vector<android::media::audio::common::AudioPort> mPorts;
137 std::vector<android::media::audio::common::AudioPortConfig> mInitialConfigs;
138 std::set<int32_t> mAttachedSinkDevicePorts;
139 std::set<int32_t> mAttachedSourceDevicePorts;
Mikhail Naganov00603d12022-05-02 22:52:13 +0000140 std::set<int32_t> mExternalDevicePorts;
Mikhail Naganove5d747e2021-11-16 01:31:03 +0000141 std::vector<android::hardware::audio::core::AudioRoute> mRoutes;
142};