blob: 6382c715c5e339ec1ea99cf8cf0ef5570be4957e [file] [log] [blame]
jiabin38b2c5d2019-09-26 17:56:44 -07001/*
2 * Copyright (C) 2019 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#include <map>
Mikhail Naganov21762fa2020-03-05 16:28:57 -080018#include <set>
jiabin38b2c5d2019-09-26 17:56:44 -070019
20#include <system/audio.h>
21#include <utils/Log.h>
22#include <utils/String8.h>
23
24#include "AudioPolicyTestClient.h"
25
26namespace android {
27
28class AudioPolicyManagerTestClient : public AudioPolicyTestClient {
29public:
30 // AudioPolicyClientInterface implementation
Mikhail Naganov21762fa2020-03-05 16:28:57 -080031 audio_module_handle_t loadHwModule(const char* name) override {
32 if (!mAllowedModuleNames.empty() && !mAllowedModuleNames.count(name)) {
33 return AUDIO_MODULE_HANDLE_NONE;
34 }
jiabin38b2c5d2019-09-26 17:56:44 -070035 return mNextModuleHandle++;
36 }
37
38 status_t openOutput(audio_module_handle_t module,
39 audio_io_handle_t *output,
Eric Laurentf1f22e72021-07-13 14:04:14 +020040 audio_config_t * /*halConfig*/,
41 audio_config_base_t * /*mixerConfig*/,
jiabinc0106832019-10-24 14:58:31 -070042 const sp<DeviceDescriptorBase>& /*device*/,
jiabin38b2c5d2019-09-26 17:56:44 -070043 uint32_t * /*latencyMs*/,
Haofan Wangb75aa6a2024-07-09 23:06:58 -070044 audio_output_flags_t /*flags*/,
45 audio_attributes_t /*attributes*/) override {
jiabin38b2c5d2019-09-26 17:56:44 -070046 if (module >= mNextModuleHandle) {
47 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
48 __func__, module, mNextModuleHandle);
49 return BAD_VALUE;
50 }
51 *output = mNextIoHandle++;
52 return NO_ERROR;
53 }
54
55 audio_io_handle_t openDuplicateOutput(audio_io_handle_t /*output1*/,
56 audio_io_handle_t /*output2*/) override {
57 audio_io_handle_t id = mNextIoHandle++;
58 return id;
59 }
60
61 status_t openInput(audio_module_handle_t module,
62 audio_io_handle_t *input,
63 audio_config_t * /*config*/,
64 audio_devices_t * /*device*/,
65 const String8 & /*address*/,
66 audio_source_t /*source*/,
67 audio_input_flags_t /*flags*/) override {
68 if (module >= mNextModuleHandle) {
69 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
70 __func__, module, mNextModuleHandle);
71 return BAD_VALUE;
72 }
73 *input = mNextIoHandle++;
Mikhail Naganov2b61ab52024-05-30 16:56:25 -070074 mOpenedInputs.insert(*input);
75 ALOGD("%s: opened input %d", __func__, *input);
76 return NO_ERROR;
77 }
78
79 status_t closeInput(audio_io_handle_t input) override {
80 if (mOpenedInputs.erase(input) != 1) {
81 if (input >= mNextIoHandle) {
82 ALOGE("%s: I/O handle %d has not been allocated yet (next is %d)",
83 __func__, input, mNextIoHandle);
84 } else {
85 ALOGE("%s: Attempt to close input %d twice", __func__, input);
86 }
87 return BAD_VALUE;
88 }
89 ALOGD("%s: closed input %d", __func__, input);
jiabin38b2c5d2019-09-26 17:56:44 -070090 return NO_ERROR;
91 }
92
93 status_t createAudioPatch(const struct audio_patch *patch,
94 audio_patch_handle_t *handle,
95 int /*delayMs*/) override {
Dean Wheatley514b4312020-06-17 21:45:00 +100096 auto iter = mActivePatches.find(*handle);
97 if (iter != mActivePatches.end()) {
98 mActivePatches.erase(*handle);
99 }
jiabin38b2c5d2019-09-26 17:56:44 -0700100 *handle = mNextPatchHandle++;
101 mActivePatches.insert(std::make_pair(*handle, *patch));
102 return NO_ERROR;
103 }
104
105 status_t releaseAudioPatch(audio_patch_handle_t handle,
106 int /*delayMs*/) override {
107 if (mActivePatches.erase(handle) != 1) {
108 if (handle >= mNextPatchHandle) {
109 ALOGE("%s: Patch handle %d has not been allocated yet (next is %d)",
110 __func__, handle, mNextPatchHandle);
111 } else {
112 ALOGE("%s: Attempt to release patch %d twice", __func__, handle);
113 }
114 return BAD_VALUE;
115 }
116 return NO_ERROR;
117 }
118
Mikhail Naganova30ec142020-03-24 09:32:34 -0700119 void onAudioPortListUpdate() override {
120 ++mAudioPortListUpdateCount;
121 }
122
jiabinc0048632023-04-27 22:04:31 +0000123 status_t setDeviceConnectedState(const struct audio_port_v7 *port,
124 media::DeviceConnectedState state) override {
125 if (state == media::DeviceConnectedState::CONNECTED) {
Mikhail Naganovddc5f312022-06-11 00:47:52 +0000126 mConnectedDevicePorts.push_back(*port);
jiabinc0048632023-04-27 22:04:31 +0000127 } else if (state == media::DeviceConnectedState::DISCONNECTED){
Mikhail Naganovddc5f312022-06-11 00:47:52 +0000128 mDisconnectedDevicePorts.push_back(*port);
129 }
Mikhail Naganov516d3982022-02-01 23:53:59 +0000130 return NO_ERROR;
131 }
132
jiabin38b2c5d2019-09-26 17:56:44 -0700133 // Helper methods for tests
134 size_t getActivePatchesCount() const { return mActivePatches.size(); }
135
136 const struct audio_patch *getLastAddedPatch() const {
137 if (mActivePatches.empty()) {
138 return nullptr;
139 }
140 auto it = --mActivePatches.end();
141 return &it->second;
142 };
143
Mikhail Naganov2b61ab52024-05-30 16:56:25 -0700144 size_t getOpenedInputsCount() const { return mOpenedInputs.size(); }
145
Mikhail Naganov21762fa2020-03-05 16:28:57 -0800146 audio_module_handle_t peekNextModuleHandle() const { return mNextModuleHandle; }
147
148 void swapAllowedModuleNames(std::set<std::string>&& names = {}) {
149 mAllowedModuleNames.swap(names);
150 }
151
Mikhail Naganova30ec142020-03-24 09:32:34 -0700152 size_t getAudioPortListUpdateCount() const { return mAudioPortListUpdateCount; }
153
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700154 void onRoutingUpdated() override {
155 mRoutingUpdatedUpdateCount++;
156 }
157
158 void resetRoutingUpdatedCounter() {
159 mRoutingUpdatedUpdateCount = 0;
160 }
161
162 size_t getRoutingUpdatedCounter() const {
Jean-Michel Trivi78f2b302022-04-15 18:18:41 +0000163 return mRoutingUpdatedUpdateCount;
164 }
165
166 void onVolumeRangeInitRequest() override {
167
168 }
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700169
jiabinf042b9b2021-05-07 23:46:28 +0000170 status_t updateSecondaryOutputs(
171 const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
172 return NO_ERROR;
173 }
174
Mikhail Naganovddc5f312022-06-11 00:47:52 +0000175 size_t getConnectedDevicePortCount() const {
176 return mConnectedDevicePorts.size();
177 }
178
179 const struct audio_port_v7 *getLastConnectedDevicePort() const {
180 if (mConnectedDevicePorts.empty()) {
181 return nullptr;
182 }
183 auto it = --mConnectedDevicePorts.end();
184 return &(*it);
185 }
186
187 size_t getDisconnectedDevicePortCount() const {
188 return mDisconnectedDevicePorts.size();
189 }
190
191 const struct audio_port_v7 *getLastDisconnectedDevicePort() const {
192 if (mDisconnectedDevicePorts.empty()) {
193 return nullptr;
194 }
195 auto it = --mDisconnectedDevicePorts.end();
196 return &(*it);
197 }
198
jiabina84c3d32022-12-02 18:59:55 +0000199 String8 getParameters(audio_io_handle_t /* ioHandle */, const String8& /* keys*/ ) override {
200 AudioParameter mAudioParameters;
201 std::string formats;
202 for (const auto& f : mSupportedFormats) {
203 if (!formats.empty()) formats += AUDIO_PARAMETER_VALUE_LIST_SEPARATOR;
204 formats += audio_format_to_string(f);
205 }
206 mAudioParameters.add(
207 String8(AudioParameter::keyStreamSupportedFormats),
208 String8(formats.c_str()));
209 mAudioParameters.addInt(String8(AudioParameter::keyStreamSupportedSamplingRates), 48000);
210 std::string channelMasks;
211 for (const auto& cm : mSupportedChannelMasks) {
jiabin3ff8d7d2022-12-13 06:27:44 +0000212 if (!audio_channel_mask_is_valid(cm)) {
jiabina84c3d32022-12-02 18:59:55 +0000213 continue;
214 }
215 if (!channelMasks.empty()) channelMasks += AUDIO_PARAMETER_VALUE_LIST_SEPARATOR;
216 channelMasks += audio_channel_mask_to_string(cm);
217 }
218 mAudioParameters.add(
219 String8(AudioParameter::keyStreamSupportedChannels), String8(channelMasks.c_str()));
220 return mAudioParameters.toString();
221 }
222
jiabin12537fc2023-10-12 17:56:08 +0000223 status_t getAudioMixPort(const struct audio_port_v7 *devicePort __unused,
224 struct audio_port_v7 *mixPort) override {
225 mixPort->num_audio_profiles = 0;
226 for (auto format : mSupportedFormats) {
227 const int i = mixPort->num_audio_profiles;
228 mixPort->audio_profiles[i].format = format;
229 mixPort->audio_profiles[i].num_sample_rates = 1;
230 mixPort->audio_profiles[i].sample_rates[0] = 48000;
231 mixPort->audio_profiles[i].num_channel_masks = 0;
232 for (const auto& cm : mSupportedChannelMasks) {
233 if (audio_channel_mask_is_valid(cm)) {
234 mixPort->audio_profiles[i].channel_masks[
235 mixPort->audio_profiles[i].num_channel_masks++] = cm;
236 }
237 }
238 mixPort->num_audio_profiles++;
239 }
240 return NO_ERROR;
241 }
242
jiabina84c3d32022-12-02 18:59:55 +0000243 void addSupportedFormat(audio_format_t format) {
244 mSupportedFormats.insert(format);
245 }
246
247 void addSupportedChannelMask(audio_channel_mask_t channelMask) {
248 mSupportedChannelMasks.insert(channelMask);
249 }
250
jiabin38b2c5d2019-09-26 17:56:44 -0700251private:
252 audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
253 audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
254 audio_patch_handle_t mNextPatchHandle = AUDIO_PATCH_HANDLE_NONE + 1;
255 std::map<audio_patch_handle_t, struct audio_patch> mActivePatches;
Mikhail Naganov21762fa2020-03-05 16:28:57 -0800256 std::set<std::string> mAllowedModuleNames;
Mikhail Naganova30ec142020-03-24 09:32:34 -0700257 size_t mAudioPortListUpdateCount = 0;
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -0700258 size_t mRoutingUpdatedUpdateCount = 0;
Mikhail Naganovddc5f312022-06-11 00:47:52 +0000259 std::vector<struct audio_port_v7> mConnectedDevicePorts;
260 std::vector<struct audio_port_v7> mDisconnectedDevicePorts;
jiabina84c3d32022-12-02 18:59:55 +0000261 std::set<audio_format_t> mSupportedFormats;
262 std::set<audio_channel_mask_t> mSupportedChannelMasks;
Mikhail Naganov2b61ab52024-05-30 16:56:25 -0700263 std::set<audio_io_handle_t> mOpenedInputs;
jiabin38b2c5d2019-09-26 17:56:44 -0700264};
265
266} // namespace android