blob: d83a2775eeb12175c137968525043a5ac3bc4bea [file] [log] [blame]
Mikhail Naganovad3f8a12017-12-12 13:24:23 -08001/*
2 * Copyright (C) 2017 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
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +020017#include <cstring>
Mikhail Naganov04a86632017-12-15 18:01:42 -080018#include <memory>
jiabinf4eb15a2019-08-28 15:31:47 -070019#include <string>
Mikhail Naganov21b43362018-06-04 10:37:09 -070020#include <sys/wait.h>
21#include <unistd.h>
Mikhail Naganov04a86632017-12-15 18:01:42 -080022
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080023#include <gtest/gtest.h>
Jiabin Huang3b98d322020-09-03 17:54:16 +000024#include <gmock/gmock.h>
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080025
Mikhail Naganov21b43362018-06-04 10:37:09 -070026#define LOG_TAG "APM_Test"
jiabinf4eb15a2019-08-28 15:31:47 -070027#include <Serializer.h>
28#include <android-base/file.h>
François Gaffie6ebbce02023-07-19 13:27:53 +020029#include <android-base/properties.h>
Svet Ganov3e5f14f2021-05-13 22:51:08 +000030#include <android/content/AttributionSourceState.h>
Marvin Raminbdefaf02023-11-01 09:10:32 +010031#include <android_media_audiopolicy.h>
jiabin220eea12024-05-17 17:55:20 +000032#include <com_android_media_audioserver.h>
Marvin Raminbdefaf02023-11-01 09:10:32 +010033#include <flag_macros.h>
François Gaffie6ebbce02023-07-19 13:27:53 +020034#include <hardware/audio_effect.h>
jiabinf4eb15a2019-08-28 15:31:47 -070035#include <media/AudioPolicy.h>
Mikhail Naganovdc769682018-05-04 15:34:08 -070036#include <media/PatchBuilder.h>
jiabinf4eb15a2019-08-28 15:31:47 -070037#include <media/RecordingActivityTracker.h>
Mikhail Naganov806170e2024-09-05 17:26:50 -070038#include <media/TypeConverter.h>
jiabinf4eb15a2019-08-28 15:31:47 -070039#include <utils/Log.h>
40#include <utils/Vector.h>
Oscar Azucena4f49ef62023-01-25 23:32:13 -080041#include <cutils/multiuser.h>
Mikhail Naganovdc769682018-05-04 15:34:08 -070042
jiabinf4eb15a2019-08-28 15:31:47 -070043#include "AudioPolicyInterface.h"
jiabinb3f98042019-09-26 17:56:44 -070044#include "AudioPolicyManagerTestClient.h"
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080045#include "AudioPolicyTestClient.h"
46#include "AudioPolicyTestManager.h"
Mikhail Naganov70b52652024-09-06 10:23:24 -070047#include "test_execution_tracer.h"
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080048
49using namespace android;
Jiabin Huang3b98d322020-09-03 17:54:16 +000050using testing::UnorderedElementsAre;
Marvin Raminbdefaf02023-11-01 09:10:32 +010051using testing::IsEmpty;
Svet Ganov3e5f14f2021-05-13 22:51:08 +000052using android::content::AttributionSourceState;
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080053
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020054namespace {
55
56AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
57 AudioMixMatchCriterion criterion;
58 criterion.mValue.mUid = uid;
59 criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
60 return criterion;
61}
62
Oscar Azucena873d10f2023-01-12 18:34:42 -080063AudioMixMatchCriterion createUserIdCriterion(int userId, bool exclude = false) {
64 AudioMixMatchCriterion criterion;
65 criterion.mValue.mUserId = userId;
66 criterion.mRule = exclude ? RULE_EXCLUDE_USERID : RULE_MATCH_USERID;
67 return criterion;
68}
69
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020070AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
71 AudioMixMatchCriterion criterion;
72 criterion.mValue.mUsage = usage;
73 criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
74 return criterion;
75}
76
77AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
78 AudioMixMatchCriterion criterion;
79 criterion.mValue.mSource = source;
80 criterion.mRule = exclude ?
81 RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
82 return criterion;
83}
84
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +020085AudioMixMatchCriterion createSessionIdCriterion(audio_session_t session, bool exclude = false) {
86 AudioMixMatchCriterion criterion;
87 criterion.mValue.mAudioSessionId = session;
88 criterion.mRule = exclude ?
89 RULE_EXCLUDE_AUDIO_SESSION_ID : RULE_MATCH_AUDIO_SESSION_ID;
90 return criterion;
91}
92
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +020093// TODO b/182392769: use attribution source util
94AttributionSourceState createAttributionSourceState(uid_t uid) {
95 AttributionSourceState attributionSourceState;
96 attributionSourceState.uid = uid;
97 attributionSourceState.token = sp<BBinder>::make();
98 return attributionSourceState;
99}
100
jiabin66acc432024-02-06 00:57:36 +0000101bool equals(const audio_config_base_t& config1, const audio_config_base_t& config2) {
102 return config1.format == config2.format
103 && config1.sample_rate == config2.sample_rate
104 && config1.channel_mask == config2.channel_mask;
105}
106
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +0200107} // namespace
108
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700109TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
110 auto config = AudioPolicyConfig::createWritableForTests();
111 EXPECT_TRUE(config->getSource().empty());
112 EXPECT_TRUE(config->getHwModules().isEmpty());
113 EXPECT_TRUE(config->getInputDevices().isEmpty());
114 EXPECT_TRUE(config->getOutputDevices().isEmpty());
115}
116
117TEST(AudioPolicyConfigTest, FallbackToDefault) {
118 auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
119 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
120 EXPECT_EQ(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
121}
122
123TEST(AudioPolicyConfigTest, LoadForTests) {
124 {
125 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(
126 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
127 EXPECT_FALSE(result.ok());
128 }
129 {
130 const std::string source =
131 base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml";
132 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(source);
133 ASSERT_TRUE(result.ok());
134 EXPECT_EQ(source, result.value()->getSource());
135 EXPECT_FALSE(result.value()->getHwModules().isEmpty());
136 EXPECT_FALSE(result.value()->getInputDevices().isEmpty());
137 EXPECT_FALSE(result.value()->getOutputDevices().isEmpty());
138 }
139}
140
Mikhail Naganov47835552019-05-14 10:32:51 -0700141TEST(AudioPolicyManagerTestInit, EngineFailure) {
142 AudioPolicyTestClient client;
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700143 auto config = AudioPolicyConfig::createWritableForTests();
144 config->setDefault();
145 config->setEngineLibraryNameSuffix("non-existent");
146 AudioPolicyTestManager manager(config, &client);
Mikhail Naganov47835552019-05-14 10:32:51 -0700147 ASSERT_EQ(NO_INIT, manager.initialize());
148 ASSERT_EQ(NO_INIT, manager.initCheck());
149}
150
151TEST(AudioPolicyManagerTestInit, ClientFailure) {
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800152 AudioPolicyTestClient client;
153 AudioPolicyTestManager manager(&client);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800154 // Since the default client fails to open anything,
155 // APM should indicate that the initialization didn't succeed.
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800156 ASSERT_EQ(NO_INIT, manager.initialize());
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800157 ASSERT_EQ(NO_INIT, manager.initCheck());
158}
159
160
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800161class PatchCountCheck {
162 public:
163 explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
164 : mClient{client},
165 mInitialCount{mClient->getActivePatchesCount()} {}
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800166 int deltaFromSnapshot() const {
167 size_t currentCount = mClient->getActivePatchesCount();
168 if (mInitialCount <= currentCount) {
169 return currentCount - mInitialCount;
170 } else {
171 return -(static_cast<int>(mInitialCount - currentCount));
172 }
173 }
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800174 private:
175 const AudioPolicyManagerTestClient *mClient;
176 const size_t mInitialCount;
177};
178
Mikhail Naganov04a86632017-12-15 18:01:42 -0800179class AudioPolicyManagerTest : public testing::Test {
Mikhail Naganov806170e2024-09-05 17:26:50 -0700180 public:
181 constexpr static uint32_t k384000SamplingRate = 384000;
182 constexpr static uint32_t k48000SamplingRate = 48000;
183 constexpr static uint32_t k96000SamplingRate = 96000;
184
Mikhail Naganov04a86632017-12-15 18:01:42 -0800185 protected:
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800186 void SetUp() override;
187 void TearDown() override;
jiabin7c0205e2019-09-05 10:26:04 -0700188 virtual void SetUpManagerConfig();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800189
190 void dumpToLog();
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700191 // When explicit routing is needed, selectedDeviceId needs to be set as the wanted port
192 // id. Otherwise, selectedDeviceId needs to be initialized as AUDIO_PORT_HANDLE_NONE.
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800193 void getOutputForAttr(
194 audio_port_handle_t *selectedDeviceId,
195 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700196 audio_channel_mask_t channelMask,
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800197 int sampleRate,
198 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700199 audio_io_handle_t *output = nullptr,
jiabinf4eb15a2019-08-28 15:31:47 -0700200 audio_port_handle_t *portId = nullptr,
Mikhail Naganov806170e2024-09-05 17:26:50 -0700201 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER,
jiabin3ff8d7d2022-12-13 06:27:44 +0000202 audio_session_t session = AUDIO_SESSION_NONE,
jiabin5eaf0962022-12-20 20:11:38 +0000203 int uid = 0,
204 bool* isBitPerfect = nullptr);
jiabinf4eb15a2019-08-28 15:31:47 -0700205 void getInputForAttr(
206 const audio_attributes_t &attr,
François Gaffie6ebbce02023-07-19 13:27:53 +0200207 audio_io_handle_t *input,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200208 audio_session_t session,
jiabinf4eb15a2019-08-28 15:31:47 -0700209 audio_unique_id_t riid,
210 audio_port_handle_t *selectedDeviceId,
211 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700212 audio_channel_mask_t channelMask,
jiabinf4eb15a2019-08-28 15:31:47 -0700213 int sampleRate,
214 audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100215 audio_port_handle_t *portId = nullptr,
216 uint32_t *virtualDeviceId = nullptr);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800217 PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
Mikhail Naganov04a86632017-12-15 18:01:42 -0800218
Mikhail Naganov0805de12022-02-15 23:00:07 +0000219 void getAudioPorts(audio_port_type_t type, audio_port_role_t role,
220 std::vector<audio_port_v7>* ports);
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700221 // Tries to find a device port. If 'foundPort' isn't nullptr,
222 // will generate a failure if the port hasn't been found.
223 bool findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
jiabin19cdba52020-11-24 11:28:58 -0800224 const std::string &address, audio_port_v7 *foundPort);
jiabin7c0205e2019-09-05 10:26:04 -0700225 static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
Kriti Dangef6be8f2020-11-05 11:58:19 +0100226 virtual AudioPolicyManagerTestClient* getClient() { return new AudioPolicyManagerTestClient; }
jiabinf4eb15a2019-08-28 15:31:47 -0700227
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700228 sp<AudioPolicyConfig> mConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800229 std::unique_ptr<AudioPolicyManagerTestClient> mClient;
230 std::unique_ptr<AudioPolicyTestManager> mManager;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100231
jiabin274fed92024-09-09 23:59:35 +0000232 static const std::string sTestEngineConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800233};
234
jiabin274fed92024-09-09 23:59:35 +0000235const std::string AudioPolicyManagerTest::sTestEngineConfig =
236 base::GetExecutableDirectory() + "/engine/test_audio_policy_engine_configuration.xml";
237
Mikhail Naganov04a86632017-12-15 18:01:42 -0800238void AudioPolicyManagerTest::SetUp() {
Kriti Dangef6be8f2020-11-05 11:58:19 +0100239 mClient.reset(getClient());
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700240 ASSERT_NO_FATAL_FAILURE(SetUpManagerConfig()); // Subclasses may want to customize the config.
jiabin274fed92024-09-09 23:59:35 +0000241 mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get(), sTestEngineConfig));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800242 ASSERT_EQ(NO_ERROR, mManager->initialize());
243 ASSERT_EQ(NO_ERROR, mManager->initCheck());
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800244}
Mikhail Naganov04a86632017-12-15 18:01:42 -0800245
246void AudioPolicyManagerTest::TearDown() {
247 mManager.reset();
248 mClient.reset();
249}
250
jiabin7c0205e2019-09-05 10:26:04 -0700251void AudioPolicyManagerTest::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700252 mConfig = AudioPolicyConfig::createWritableForTests();
253 mConfig->setDefault();
jiabin7c0205e2019-09-05 10:26:04 -0700254}
255
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800256void AudioPolicyManagerTest::dumpToLog() {
Mikhail Naganov21b43362018-06-04 10:37:09 -0700257 int pipefd[2];
258 ASSERT_NE(-1, pipe(pipefd));
259 pid_t cpid = fork();
260 ASSERT_NE(-1, cpid);
261 if (cpid == 0) {
262 // Child process reads from the pipe and logs.
263 close(pipefd[1]);
264 std::string line;
265 char buf;
266 while (read(pipefd[0], &buf, sizeof(buf)) > 0) {
267 if (buf != '\n') {
268 line += buf;
269 } else {
270 ALOGI("%s", line.c_str());
271 line = "";
272 }
273 }
274 if (!line.empty()) ALOGI("%s", line.c_str());
275 close(pipefd[0]);
276 _exit(EXIT_SUCCESS);
277 } else {
278 // Parent does the dump and checks the status code.
279 close(pipefd[0]);
280 ASSERT_EQ(NO_ERROR, mManager->dump(pipefd[1]));
281 close(pipefd[1]);
282 wait(NULL); // Wait for the child to exit.
283 }
284}
285
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800286void AudioPolicyManagerTest::getOutputForAttr(
287 audio_port_handle_t *selectedDeviceId,
288 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700289 audio_channel_mask_t channelMask,
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800290 int sampleRate,
291 audio_output_flags_t flags,
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700292 audio_io_handle_t *output,
jiabinf4eb15a2019-08-28 15:31:47 -0700293 audio_port_handle_t *portId,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200294 audio_attributes_t attr,
jiabin3ff8d7d2022-12-13 06:27:44 +0000295 audio_session_t session,
jiabin5eaf0962022-12-20 20:11:38 +0000296 int uid,
297 bool* isBitPerfect) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700298 audio_io_handle_t localOutput;
299 if (!output) output = &localOutput;
300 *output = AUDIO_IO_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800301 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
302 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
303 config.sample_rate = sampleRate;
304 config.channel_mask = channelMask;
305 config.format = format;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800306 audio_port_handle_t localPortId;
307 if (!portId) portId = &localPortId;
308 *portId = AUDIO_PORT_HANDLE_NONE;
Eric Laurent8a1095a2019-11-08 14:44:16 -0800309 AudioPolicyInterface::output_type_t outputType;
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200310 bool isSpatialized;
jiabin5eaf0962022-12-20 20:11:38 +0000311 bool isBitPerfectInternal;
Andy Hung6b137d12024-08-27 22:35:17 +0000312 float volume;
Vlad Popa1e865e62024-08-15 19:11:42 -0700313 bool muted;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200314 AttributionSourceState attributionSource = createAttributionSourceState(uid);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800315 ASSERT_EQ(OK, mManager->getOutputForAttr(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200316 &attr, output, session, &stream, attributionSource, &config, &flags,
jiabin5eaf0962022-12-20 20:11:38 +0000317 selectedDeviceId, portId, {}, &outputType, &isSpatialized,
Vlad Popa1e865e62024-08-15 19:11:42 -0700318 isBitPerfect == nullptr ? &isBitPerfectInternal : isBitPerfect, &volume,
319 &muted));
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800320 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700321 ASSERT_NE(AUDIO_IO_HANDLE_NONE, *output);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800322}
323
jiabinf4eb15a2019-08-28 15:31:47 -0700324void AudioPolicyManagerTest::getInputForAttr(
325 const audio_attributes_t &attr,
François Gaffie6ebbce02023-07-19 13:27:53 +0200326 audio_io_handle_t *input,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200327 const audio_session_t session,
jiabinf4eb15a2019-08-28 15:31:47 -0700328 audio_unique_id_t riid,
329 audio_port_handle_t *selectedDeviceId,
330 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700331 audio_channel_mask_t channelMask,
jiabinf4eb15a2019-08-28 15:31:47 -0700332 int sampleRate,
333 audio_input_flags_t flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100334 audio_port_handle_t *portId,
335 uint32_t *virtualDeviceId) {
jiabinf4eb15a2019-08-28 15:31:47 -0700336 audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
337 config.sample_rate = sampleRate;
338 config.channel_mask = channelMask;
339 config.format = format;
jiabinf4eb15a2019-08-28 15:31:47 -0700340 audio_port_handle_t localPortId;
341 if (!portId) portId = &localPortId;
342 *portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +0100343 if (!virtualDeviceId) virtualDeviceId = 0;
jiabinf4eb15a2019-08-28 15:31:47 -0700344 AudioPolicyInterface::input_type_t inputType;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200345 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
jiabinf4eb15a2019-08-28 15:31:47 -0700346 ASSERT_EQ(OK, mManager->getInputForAttr(
François Gaffie6ebbce02023-07-19 13:27:53 +0200347 &attr, input, riid, session, attributionSource, &config, flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100348 selectedDeviceId, &inputType, portId, virtualDeviceId));
jiabinf4eb15a2019-08-28 15:31:47 -0700349 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
350}
351
Mikhail Naganov0805de12022-02-15 23:00:07 +0000352void AudioPolicyManagerTest::getAudioPorts(audio_port_type_t type, audio_port_role_t role,
353 std::vector<audio_port_v7>* ports) {
jiabinf4eb15a2019-08-28 15:31:47 -0700354 uint32_t numPorts = 0;
355 uint32_t generation1;
356 status_t ret;
357
Mikhail Naganov0805de12022-02-15 23:00:07 +0000358 ret = mManager->listAudioPorts(role, type, &numPorts, nullptr, &generation1);
359 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
jiabinf4eb15a2019-08-28 15:31:47 -0700360
361 uint32_t generation2;
Mikhail Naganov0805de12022-02-15 23:00:07 +0000362 ports->resize(numPorts);
363 ret = mManager->listAudioPorts(role, type, &numPorts, ports->data(), &generation2);
364 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
365 ASSERT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
366}
367
368bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
369 audio_devices_t deviceType, const std::string &address, audio_port_v7 *foundPort) {
370 std::vector<audio_port_v7> ports;
371 getAudioPorts(AUDIO_PORT_TYPE_DEVICE, role, &ports);
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700372 if (HasFailure()) return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700373
374 for (const auto &port : ports) {
375 if (port.role == role && port.ext.device.type == deviceType &&
376 (strncmp(port.ext.device.address, address.c_str(),
377 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700378 if (foundPort) *foundPort = port;
379 return true;
jiabinf4eb15a2019-08-28 15:31:47 -0700380 }
381 }
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700382 if (foundPort) {
383 ADD_FAILURE() << "Device port with role " << role << " and address "
384 << address << " not found";
385 }
386 return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700387}
388
jiabin7c0205e2019-09-05 10:26:04 -0700389audio_port_handle_t AudioPolicyManagerTest::getDeviceIdFromPatch(
390 const struct audio_patch* patch) {
391 // The logic here is the same as the one in AudioIoDescriptor.
392 // Note this function is aim to get routed device id for test.
393 // In that case, device to device patch is not expected here.
394 if (patch->num_sources != 0 && patch->num_sinks != 0) {
395 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
396 return patch->sinks[0].id;
397 } else {
398 return patch->sources[0].id;
399 }
400 }
401 return AUDIO_PORT_HANDLE_NONE;
402}
403
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800404
405TEST_F(AudioPolicyManagerTest, InitSuccess) {
406 // SetUp must finish with no assertions.
407}
408
409TEST_F(AudioPolicyManagerTest, Dump) {
410 dumpToLog();
411}
412
Mikhail Naganov04a86632017-12-15 18:01:42 -0800413TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
414 audio_patch patch{};
415 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800416 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganov04a86632017-12-15 18:01:42 -0800417 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
418 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
419 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
420 patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
421 patch.num_sinks = 1;
422 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
423 patch.num_sources = 1;
424 patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
425 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
426 patch.num_sources = 2;
427 patch.num_sinks = 1;
428 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
429 patch = {};
430 patch.num_sources = 1;
431 patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
432 patch.num_sinks = 1;
433 patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
434 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
435 patch = {};
436 patch.num_sources = 1;
437 patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
438 patch.num_sinks = 1;
439 patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
440 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
441 // Verify that the handle is left unchanged.
442 ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800443 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800444}
445
446TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
Mikhail Naganov04a86632017-12-15 18:01:42 -0800447 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
448 uid_t uid = 42;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800449 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000450 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
Mikhail Naganovdc769682018-05-04 15:34:08 -0700451 PatchBuilder patchBuilder;
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000452 patchBuilder.addSource(mManager->getAvailableInputDevices()[0]).
Mikhail Naganovdc769682018-05-04 15:34:08 -0700453 addSink(mManager->getConfig().getDefaultOutputDevice());
454 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800455 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800456 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800457}
458
459// TODO: Add patch creation tests that involve already existing patch
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800460
Michael Chan6fb34492020-12-08 15:44:49 +1100461enum
462{
463 MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX = 0,
464 MSD_AUDIO_PATCH_COUNT_NAME_INDEX = 1
465};
466using MsdAudioPatchCountSpecification = std::tuple<size_t, std::string>;
467
468class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest,
469 public ::testing::WithParamInterface<MsdAudioPatchCountSpecification> {
470 public:
471 AudioPolicyManagerTestMsd();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800472 protected:
jiabin7c0205e2019-09-05 10:26:04 -0700473 void SetUpManagerConfig() override;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800474 void TearDown() override;
Dorin Drimus94d94412022-02-02 09:05:02 +0100475 AudioProfileVector getDirectProfilesForAttributes(const audio_attributes_t& attr);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800476
477 sp<DeviceDescriptor> mMsdOutputDevice;
478 sp<DeviceDescriptor> mMsdInputDevice;
Eric Laurent74c38dc2020-12-23 18:19:44 +0100479 sp<DeviceDescriptor> mDefaultOutputDevice;
Michael Chan6fb34492020-12-08 15:44:49 +1100480
481 const size_t mExpectedAudioPatchCount;
482 sp<DeviceDescriptor> mSpdifDevice;
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100483
484 sp<DeviceDescriptor> mHdmiInputDevice;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800485};
486
Michael Chan6fb34492020-12-08 15:44:49 +1100487AudioPolicyManagerTestMsd::AudioPolicyManagerTestMsd()
488 : mExpectedAudioPatchCount(std::get<MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX>(
489 GetParam())) {}
490
491INSTANTIATE_TEST_CASE_P(
492 MsdAudioPatchCount,
493 AudioPolicyManagerTestMsd,
494 ::testing::Values(
Eric Laurent0ca09402024-05-16 17:48:59 +0000495 MsdAudioPatchCountSpecification(2u, "single"),
496 MsdAudioPatchCountSpecification(3u, "dual")
Michael Chan6fb34492020-12-08 15:44:49 +1100497 ),
498 [](const ::testing::TestParamInfo<MsdAudioPatchCountSpecification> &info) {
499 return std::get<MSD_AUDIO_PATCH_COUNT_NAME_INDEX>(info.param); }
500);
501
jiabin7c0205e2019-09-05 10:26:04 -0700502void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800503 // TODO: Consider using Serializer to load part of the config from a string.
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700504 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700505 mConfig->getHwModules().getModuleFromName(
506 AUDIO_HARDWARE_MODULE_ID_PRIMARY)->setHalVersion(3, 0);
507
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800508 mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
509 sp<AudioProfile> pcmOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100510 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800511 sp<AudioProfile> ac3OutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100512 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100513 sp<AudioProfile> iec958OutputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100514 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800515 mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
516 mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100517 mMsdOutputDevice->addAudioProfile(iec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800518 mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
519 // Match output profile from AudioPolicyConfig::setDefault.
520 sp<AudioProfile> pcmInputProfile = new AudioProfile(
521 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
522 mMsdInputDevice->addAudioProfile(pcmInputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700523 mConfig->addDevice(mMsdOutputDevice);
524 mConfig->addDevice(mMsdInputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800525
Eric Laurent0ca09402024-05-16 17:48:59 +0000526 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100527 // Add SPDIF device with PCM output profile as a second device for dual MSD audio patching.
528 mSpdifDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPDIF);
529 mSpdifDevice->addAudioProfile(pcmOutputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700530 mConfig->addDevice(mSpdifDevice);
Michael Chan6fb34492020-12-08 15:44:49 +1100531
532 sp<OutputProfile> spdifOutputProfile = new OutputProfile("spdif output");
533 spdifOutputProfile->addAudioProfile(pcmOutputProfile);
534 spdifOutputProfile->addSupportedDevice(mSpdifDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700535 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Michael Chan6fb34492020-12-08 15:44:49 +1100536 addOutputProfile(spdifOutputProfile);
537 }
538
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700539 sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 3 /*halVersionMajor*/);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700540 HwModuleCollection modules = mConfig->getHwModules();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800541 modules.add(msdModule);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700542 mConfig->setHwModules(modules);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800543
jiabin5740f082019-08-19 15:08:30 -0700544 sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800545 msdOutputProfile->addAudioProfile(pcmOutputProfile);
546 msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
547 msdModule->addOutputProfile(msdOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700548 sp<OutputProfile> msdCompressedOutputProfile = new OutputProfile("msd compressed input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800549 msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
550 msdCompressedOutputProfile->setFlags(
551 AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
552 AUDIO_OUTPUT_FLAG_NON_BLOCKING);
553 msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
554 msdModule->addOutputProfile(msdCompressedOutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100555 sp<OutputProfile> msdIec958OutputProfile = new OutputProfile("msd iec958 input");
556 msdIec958OutputProfile->addAudioProfile(iec958OutputProfile);
557 msdIec958OutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
558 msdIec958OutputProfile->addSupportedDevice(mMsdOutputDevice);
559 msdModule->addOutputProfile(msdIec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800560
jiabin5740f082019-08-19 15:08:30 -0700561 sp<InputProfile> msdInputProfile = new InputProfile("msd output");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800562 msdInputProfile->addAudioProfile(pcmInputProfile);
563 msdInputProfile->addSupportedDevice(mMsdInputDevice);
564 msdModule->addInputProfile(msdInputProfile);
565
566 // Add a profile with another encoding to the default device to test routing
567 // of streams that are not supported by MSD.
568 sp<AudioProfile> dtsOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100569 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700570 mConfig->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700571 sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800572 primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
573 primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700574 primaryEncodedOutputProfile->addSupportedDevice(mConfig->getDefaultOutputDevice());
575 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800576 addOutputProfile(primaryEncodedOutputProfile);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100577
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700578 mDefaultOutputDevice = mConfig->getDefaultOutputDevice();
Eric Laurent0ca09402024-05-16 17:48:59 +0000579 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100580 mSpdifDevice->addAudioProfile(dtsOutputProfile);
581 primaryEncodedOutputProfile->addSupportedDevice(mSpdifDevice);
582 }
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100583
584 // Add HDMI input device with IEC60958 profile for HDMI in -> MSD patching.
585 mHdmiInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_HDMI);
586 sp<AudioProfile> iec958InputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100587 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100588 mHdmiInputDevice->addAudioProfile(iec958InputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700589 mConfig->addDevice(mHdmiInputDevice);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100590 sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
591 hdmiInputProfile->addAudioProfile(iec958InputProfile);
592 hdmiInputProfile->setFlags(AUDIO_INPUT_FLAG_DIRECT);
593 hdmiInputProfile->addSupportedDevice(mHdmiInputDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700594 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100595 addInputProfile(hdmiInputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800596}
597
598void AudioPolicyManagerTestMsd::TearDown() {
599 mMsdOutputDevice.clear();
600 mMsdInputDevice.clear();
Eric Laurent74c38dc2020-12-23 18:19:44 +0100601 mDefaultOutputDevice.clear();
Michael Chan6fb34492020-12-08 15:44:49 +1100602 mSpdifDevice.clear();
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100603 mHdmiInputDevice.clear();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800604 AudioPolicyManagerTest::TearDown();
605}
606
Dorin Drimus94d94412022-02-02 09:05:02 +0100607AudioProfileVector AudioPolicyManagerTestMsd::getDirectProfilesForAttributes(
608 const audio_attributes_t& attr) {
609 AudioProfileVector audioProfilesVector;
610 mManager->getDirectProfilesForAttributes(&attr, audioProfilesVector);
611 return audioProfilesVector;
612}
613
Michael Chan6fb34492020-12-08 15:44:49 +1100614TEST_P(AudioPolicyManagerTestMsd, InitSuccess) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800615 ASSERT_TRUE(mMsdOutputDevice);
616 ASSERT_TRUE(mMsdInputDevice);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100617 ASSERT_TRUE(mDefaultOutputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800618}
619
Michael Chan6fb34492020-12-08 15:44:49 +1100620TEST_P(AudioPolicyManagerTestMsd, Dump) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800621 dumpToLog();
622}
623
Michael Chan6fb34492020-12-08 15:44:49 +1100624TEST_P(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800625 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800626 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
627 AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Eric Laurent0ca09402024-05-16 17:48:59 +0000628 ASSERT_EQ(mExpectedAudioPatchCount -1 , patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800629}
630
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100631TEST_P(AudioPolicyManagerTestMsd, PatchCreationSetReleaseMsdOutputPatches) {
Michael Chan6fb34492020-12-08 15:44:49 +1100632 const PatchCountCheck patchCount = snapshotPatchCount();
633 DeviceVector devices = mManager->getAvailableOutputDevices();
634 // Remove MSD output device to avoid patching to itself
635 devices.remove(mMsdOutputDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000636 ASSERT_EQ(mExpectedAudioPatchCount -1 , devices.size());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100637 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000638 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Michael Chan6fb34492020-12-08 15:44:49 +1100639 // Dual patch: exercise creating one new audio patch and reusing another existing audio patch.
640 DeviceVector singleDevice(devices[0]);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100641 mManager->releaseMsdOutputPatches(singleDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000642 ASSERT_EQ(mExpectedAudioPatchCount - 2, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100643 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000644 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100645 mManager->releaseMsdOutputPatches(devices);
Michael Chan6fb34492020-12-08 15:44:49 +1100646 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
647}
648
649TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800650 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700651 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100652 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
653 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100654 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100655 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800656}
657
Michael Chan6fb34492020-12-08 15:44:49 +1100658TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800659 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700660 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800661 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100662 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100663 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000664 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800665}
666
Michael Chan6fb34492020-12-08 15:44:49 +1100667TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800668 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700669 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100670 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
671 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100672 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100673 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
674 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800675 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100676 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100677 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100678 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800679}
680
Michael Chan6fb34492020-12-08 15:44:49 +1100681TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800682 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700683 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100684 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
685 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800686 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000687 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800688}
689
Michael Chan6fb34492020-12-08 15:44:49 +1100690TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800691 // Switch between formats that are supported and not supported by MSD.
692 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800693 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700694 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
695 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100696 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
697 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100698 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100699 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800700 mManager->releaseOutput(portId);
Eric Laurent0ca09402024-05-16 17:48:59 +0000701 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800702 }
703 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800704 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700705 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
706 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100707 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
708 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800709 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000710 ASSERT_EQ(-static_cast<int>(mExpectedAudioPatchCount) + 2, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800711 mManager->releaseOutput(portId);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800712 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800713 }
714 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800715 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700716 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100717 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
718 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100719 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000720 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800721 }
722}
jiabinf4eb15a2019-08-28 15:31:47 -0700723
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100724TEST_P(AudioPolicyManagerTestMsd, PatchCreationFromHdmiInToMsd) {
725 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
726 uid_t uid = 42;
727 const PatchCountCheck patchCount = snapshotPatchCount();
728 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
729 PatchBuilder patchBuilder;
730 patchBuilder.
731 addSource(mManager->getAvailableInputDevices().
732 getDevice(AUDIO_DEVICE_IN_HDMI, String8(""), AUDIO_FORMAT_DEFAULT)).
733 addSink(mManager->getAvailableOutputDevices().
734 getDevice(AUDIO_DEVICE_OUT_BUS, String8(""), AUDIO_FORMAT_DEFAULT));
735 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
736 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
737 AudioPatchCollection patches = mManager->getAudioPatches();
738 sp<AudioPatch> patch = patches.valueFor(handle);
739 ASSERT_EQ(1, patch->mPatch.num_sources);
740 ASSERT_EQ(1, patch->mPatch.num_sinks);
741 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, patch->mPatch.sources[0].role);
742 ASSERT_EQ(AUDIO_PORT_ROLE_SINK, patch->mPatch.sinks[0].role);
743 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sources[0].format);
744 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sinks[0].format);
Dean Wheatley16809da2022-12-09 14:55:46 +1100745 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sources[0].channel_mask);
746 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sinks[0].channel_mask);
Dean Wheatleyd082f472022-02-04 11:10:48 +1100747 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sources[0].sample_rate);
748 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sinks[0].sample_rate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100749 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
750}
751
Dorin Drimus94d94412022-02-02 09:05:02 +0100752TEST_P(AudioPolicyManagerTestMsd, GetDirectProfilesForAttributesWithMsd) {
753 const audio_attributes_t attr = {
754 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
755 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
756
757 // count expected direct profiles for the default device
758 int countDirectProfilesPrimary = 0;
759 const auto& primary = mManager->getConfig().getHwModules()
760 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700761 for (const auto& outputProfile : primary->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100762 if (outputProfile->asAudioPort()->isDirectOutput()) {
763 countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
764 }
765 }
766
767 // count expected direct profiles for the msd device
768 int countDirectProfilesMsd = 0;
769 const auto& msd = mManager->getConfig().getHwModules()
770 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700771 for (const auto& outputProfile : msd->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100772 if (outputProfile->asAudioPort()->isDirectOutput()) {
773 countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
774 }
775 }
776
777 // before setting up MSD audio patches we only have the primary hal direct profiles
778 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
779
780 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
781 // Remove MSD output device to avoid patching to itself
782 outputDevices.remove(mMsdOutputDevice);
783 mManager->setMsdOutputPatches(&outputDevices);
784
785 // after setting up MSD audio patches the MSD direct profiles are added
786 ASSERT_EQ(countDirectProfilesPrimary + countDirectProfilesMsd,
787 getDirectProfilesForAttributes(attr).size());
788
789 mManager->releaseMsdOutputPatches(outputDevices);
790 // releasing the MSD audio patches gets us back to the primary hal direct profiles only
791 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
792}
793
Dorin Drimusecc9f422022-03-09 17:57:40 +0100794TEST_P(AudioPolicyManagerTestMsd, IsDirectPlaybackSupportedWithMsd) {
795 const audio_attributes_t attr = {
796 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
797 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
798
799 audio_config_base_t directConfig = AUDIO_CONFIG_BASE_INITIALIZER;
800 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700801 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100802 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
803
804 audio_config_base_t nonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
805 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700806 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100807 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
808
809 audio_config_base_t nonExistentConfig = AUDIO_CONFIG_BASE_INITIALIZER;
810 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700811 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100812 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
813
814 audio_config_base_t msdDirectConfig1 = AUDIO_CONFIG_BASE_INITIALIZER;
815 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700816 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100817 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
818
819 audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
820 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700821 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100822 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100823
824 audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
825 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
826 msdNonDirectConfig.sample_rate = 96000;
827 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
828
829 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
830 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
831 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
832 // before setting MSD patches the direct MSD configs return false
833 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
834 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
835 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
836
837 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
838 // Remove MSD output device to avoid patching to itself
839 outputDevices.remove(mMsdOutputDevice);
840 mManager->setMsdOutputPatches(&outputDevices);
841
842 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
843 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
844 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
845 // after setting MSD patches the direct MSD configs return true
846 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
847 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
848 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
849
850 mManager->releaseMsdOutputPatches(outputDevices);
851
852 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
853 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
854 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
855 // AFTER releasing MSD patches the direct MSD configs return false
856 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
857 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
858 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
859}
860
Dorin Drimusfae3c642022-03-17 18:36:30 +0100861TEST_P(AudioPolicyManagerTestMsd, GetDirectPlaybackSupportWithMsd) {
862 const audio_attributes_t attr = {
863 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
864 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
865
866 audio_config_t directConfig = AUDIO_CONFIG_INITIALIZER;
867 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700868 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100869 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
870
871 audio_config_t nonDirectConfig = AUDIO_CONFIG_INITIALIZER;
872 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700873 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100874 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
875
876 audio_config_t nonExistentConfig = AUDIO_CONFIG_INITIALIZER;
877 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700878 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100879 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
880
881 audio_config_t msdDirectConfig1 = AUDIO_CONFIG_INITIALIZER;
882 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700883 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100884 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
885
886 audio_config_t msdDirectConfig2 = AUDIO_CONFIG_INITIALIZER;
887 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov806170e2024-09-05 17:26:50 -0700888 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100889 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100890
891 audio_config_t msdNonDirectConfig = AUDIO_CONFIG_INITIALIZER;
892 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
893 msdNonDirectConfig.sample_rate = 96000;
894 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
895
896 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
897 mManager->getDirectPlaybackSupport(&attr, &directConfig));
898 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
899 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
900 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
901 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
902 // before setting MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
903 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
904 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
905 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
906 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
907 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
908 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
909
910 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
911 // Remove MSD output device to avoid patching to itself
912 outputDevices.remove(mMsdOutputDevice);
913 mManager->setMsdOutputPatches(&outputDevices);
914
915 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
916 mManager->getDirectPlaybackSupport(&attr, &directConfig));
917 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
918 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
919 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
920 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
921 // after setting MSD patches the direct MSD configs return values according to their flags
922 ASSERT_EQ(AUDIO_DIRECT_OFFLOAD_SUPPORTED,
923 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
924 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
925 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
926 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
927 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
928
929 mManager->releaseMsdOutputPatches(outputDevices);
930
931 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
932 mManager->getDirectPlaybackSupport(&attr, &directConfig));
933 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
934 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
935 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
936 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
937 // after releasing MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
938 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
939 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
940 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
941 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
942 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
943 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
944}
945
jiabin7c0205e2019-09-05 10:26:04 -0700946class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
947protected:
948 void SetUpManagerConfig() override;
949 virtual std::string getConfigFile() { return sDefaultConfig; }
950
951 static const std::string sExecutableDir;
952 static const std::string sDefaultConfig;
953};
954
955const std::string AudioPolicyManagerTestWithConfigurationFile::sExecutableDir =
956 base::GetExecutableDirectory() + "/";
957
958const std::string AudioPolicyManagerTestWithConfigurationFile::sDefaultConfig =
959 sExecutableDir + "test_audio_policy_configuration.xml";
960
961void AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700962 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(getConfigFile());
963 ASSERT_TRUE(result.ok());
964 mConfig = result.value();
jiabin7c0205e2019-09-05 10:26:04 -0700965}
966
967TEST_F(AudioPolicyManagerTestWithConfigurationFile, InitSuccess) {
968 // SetUp must finish with no assertions.
969}
970
971TEST_F(AudioPolicyManagerTestWithConfigurationFile, Dump) {
972 dumpToLog();
973}
974
Mikhail Naganov0805de12022-02-15 23:00:07 +0000975TEST_F(AudioPolicyManagerTestWithConfigurationFile, ListAudioPortsHasFlags) {
976 // Create an input for VOIP TX because it's not opened automatically like outputs are.
977 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
978 audio_port_handle_t mixPortId = AUDIO_PORT_HANDLE_NONE;
979 audio_source_t source = AUDIO_SOURCE_VOICE_COMMUNICATION;
François Gaffie6ebbce02023-07-19 13:27:53 +0200980 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source,
981 AUDIO_FLAG_NONE, ""};
982 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
983 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
984 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
985 AUDIO_CHANNEL_IN_MONO, 8000, AUDIO_INPUT_FLAG_VOIP_TX,
986 &mixPortId));
Mikhail Naganov0805de12022-02-15 23:00:07 +0000987
988 std::vector<audio_port_v7> ports;
989 ASSERT_NO_FATAL_FAILURE(
990 getAudioPorts(AUDIO_PORT_TYPE_MIX, AUDIO_PORT_ROLE_NONE, &ports));
991 EXPECT_NE(0, ports.size());
992 bool hasFlags = false, foundPrimary = false, foundVoipRx = false, foundVoipTx = false;
993 for (const auto& port : ports) {
994 if ((port.active_config.config_mask & AUDIO_PORT_CONFIG_FLAGS) != 0) {
995 hasFlags = true;
996 if (port.role == AUDIO_PORT_ROLE_SOURCE) {
997 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
998 foundPrimary = true;
999 }
1000 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
1001 foundVoipRx = true;
1002 }
1003 } else if (port.role == AUDIO_PORT_ROLE_SINK) {
1004 if ((port.active_config.flags.input & AUDIO_INPUT_FLAG_VOIP_TX) != 0) {
1005 foundVoipTx = true;
1006 }
1007 }
1008 }
1009 }
1010 EXPECT_TRUE(hasFlags);
1011 EXPECT_TRUE(foundPrimary);
1012 EXPECT_TRUE(foundVoipRx);
1013 EXPECT_TRUE(foundVoipTx);
1014}
1015
Ram Mohan M594558d2022-06-14 14:42:44 +05301016TEST_F(AudioPolicyManagerTestWithConfigurationFile, HandleDeviceConfigChange) {
1017 {
1018 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1019
1020 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1021 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1022 "", "", AUDIO_FORMAT_LDAC));
1023 const auto currCounter = mClient->getRoutingUpdatedCounter();
1024 EXPECT_GT(currCounter, prevCounter);
1025 }
1026 {
1027 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1028 // Update device configuration
1029 EXPECT_EQ(NO_ERROR, mManager->handleDeviceConfigChange(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1030 "" /*address*/, "" /*name*/,
1031 AUDIO_FORMAT_AAC));
1032
1033 // As mClient marks isReconfigA2dpSupported to false, device state needs to be toggled for
1034 // config changes to take effect
1035 const auto currCounter = mClient->getRoutingUpdatedCounter();
1036 EXPECT_GT(currCounter, prevCounter);
1037 }
1038}
1039
jiabina84c3d32022-12-02 18:59:55 +00001040TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferredMixerAttributes) {
1041 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1042 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1043 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1044 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1045 "", "", AUDIO_FORMAT_DEFAULT));
1046 auto devices = mManager->getAvailableOutputDevices();
1047 audio_port_handle_t maxPortId = 0;
1048 audio_port_handle_t speakerPortId;
1049 audio_port_handle_t usbPortId;
1050 for (auto device : devices) {
1051 maxPortId = std::max(maxPortId, device->getId());
1052 if (device->type() == AUDIO_DEVICE_OUT_SPEAKER) {
1053 speakerPortId = device->getId();
1054 } else if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1055 usbPortId = device->getId();
1056 }
1057 }
1058
1059 const uid_t uid = 1234;
1060 const uid_t otherUid = 4321;
1061 const audio_attributes_t mediaAttr = {
1062 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1063 .usage = AUDIO_USAGE_MEDIA,
1064 };
1065 const audio_attributes_t alarmAttr = {
1066 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
1067 .usage = AUDIO_USAGE_ALARM,
1068 };
1069
1070 std::vector<audio_mixer_attributes_t> mixerAttributes;
1071 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1072 for (const auto attrToSet : mixerAttributes) {
1073 audio_mixer_attributes_t attrFromQuery = AUDIO_MIXER_ATTRIBUTES_INITIALIZER;
1074
1075 // The given device is not available
1076 EXPECT_EQ(BAD_VALUE,
1077 mManager->setPreferredMixerAttributes(
1078 &mediaAttr, maxPortId + 1, uid, &attrToSet));
1079 // The only allowed device is USB
1080 EXPECT_EQ(BAD_VALUE,
1081 mManager->setPreferredMixerAttributes(
1082 &mediaAttr, speakerPortId, uid, &attrToSet));
1083 // The only allowed usage is media
1084 EXPECT_EQ(BAD_VALUE,
1085 mManager->setPreferredMixerAttributes(&alarmAttr, usbPortId, uid, &attrToSet));
1086 // Nothing set yet, must get null when query
1087 EXPECT_EQ(NAME_NOT_FOUND,
1088 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1089 EXPECT_EQ(NO_ERROR,
1090 mManager->setPreferredMixerAttributes(
1091 &mediaAttr, usbPortId, uid, &attrToSet));
1092 EXPECT_EQ(NO_ERROR,
1093 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1094 EXPECT_EQ(attrToSet.config.format, attrFromQuery.config.format);
1095 EXPECT_EQ(attrToSet.config.sample_rate, attrFromQuery.config.sample_rate);
1096 EXPECT_EQ(attrToSet.config.channel_mask, attrFromQuery.config.channel_mask);
1097 EXPECT_EQ(attrToSet.mixer_behavior, attrFromQuery.mixer_behavior);
1098 EXPECT_EQ(NAME_NOT_FOUND,
1099 mManager->clearPreferredMixerAttributes(&mediaAttr, speakerPortId, uid));
1100 EXPECT_EQ(PERMISSION_DENIED,
1101 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, otherUid));
1102 EXPECT_EQ(NO_ERROR,
1103 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1104 }
1105
1106 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1107 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1108 "", "", AUDIO_FORMAT_LDAC));
1109}
1110
jiabin3ff8d7d2022-12-13 06:27:44 +00001111TEST_F(AudioPolicyManagerTestWithConfigurationFile, RoutingChangedWithPreferredMixerAttributes) {
1112 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1113 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1114 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1115 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1116 "", "", AUDIO_FORMAT_DEFAULT));
1117 auto devices = mManager->getAvailableOutputDevices();
1118 audio_port_handle_t usbPortId = AUDIO_PORT_HANDLE_NONE;
1119 for (auto device : devices) {
1120 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1121 usbPortId = device->getId();
1122 break;
1123 }
1124 }
1125 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, usbPortId);
1126
1127 const uid_t uid = 1234;
1128 const audio_attributes_t mediaAttr = {
1129 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1130 .usage = AUDIO_USAGE_MEDIA,
1131 };
1132
1133 std::vector<audio_mixer_attributes_t> mixerAttributes;
1134 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1135 EXPECT_GT(mixerAttributes.size(), 0);
1136 EXPECT_EQ(NO_ERROR,
1137 mManager->setPreferredMixerAttributes(
1138 &mediaAttr, usbPortId, uid, &mixerAttributes[0]));
1139
1140 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
1141 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1142 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
1143 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07001144 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001145 AUDIO_SESSION_NONE, uid);
1146 status_t status = mManager->startOutput(portId);
1147 if (status == DEAD_OBJECT) {
1148 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07001149 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001150 AUDIO_SESSION_NONE, uid);
1151 status = mManager->startOutput(portId);
1152 }
1153 EXPECT_EQ(NO_ERROR, status);
1154 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
1155 EXPECT_NE(nullptr, mManager->getOutputs().valueFor(output));
1156 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1157 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1158 "", "", AUDIO_FORMAT_LDAC));
1159 // When BT device is connected, it will be selected as media device and trigger routing changed.
1160 // When this happens, existing output that is opened with preferred mixer attributes will be
1161 // closed and reopened with default config.
1162 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(output));
1163
1164 EXPECT_EQ(NO_ERROR,
1165 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1166
1167 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1168 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1169 "", "", AUDIO_FORMAT_LDAC));
1170 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1171 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1172 "", "", AUDIO_FORMAT_LDAC));
1173}
1174
jiabin66acc432024-02-06 00:57:36 +00001175TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferExactConfigForInput) {
1176 const audio_channel_mask_t deviceChannelMask = AUDIO_CHANNEL_IN_3POINT1;
1177 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1178 mClient->addSupportedChannelMask(deviceChannelMask);
1179 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1180 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1181 "", "", AUDIO_FORMAT_DEFAULT));
1182
1183 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1184 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1185 AUDIO_SOURCE_VOICE_COMMUNICATION,AUDIO_FLAG_NONE, ""};
1186 AudioPolicyInterface::input_type_t inputType;
1187 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1188 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
1189 audio_config_base_t requestedConfig = {
Mikhail Naganov806170e2024-09-05 17:26:50 -07001190 .sample_rate = k48000SamplingRate,
jiabin66acc432024-02-06 00:57:36 +00001191 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1192 .format = AUDIO_FORMAT_PCM_16_BIT,
jiabin66acc432024-02-06 00:57:36 +00001193 };
1194 audio_config_base_t config = requestedConfig;
1195 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +01001196 uint32_t *virtualDeviceId = 0;
jiabin66acc432024-02-06 00:57:36 +00001197 ASSERT_EQ(OK, mManager->getInputForAttr(
1198 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1199 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001200 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001201 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1202 ASSERT_TRUE(equals(requestedConfig, config));
1203
1204 attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1205 AUDIO_SOURCE_VOICE_COMMUNICATION, AUDIO_FLAG_NONE, ""};
1206 requestedConfig.channel_mask = deviceChannelMask;
1207 config = requestedConfig;
1208 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1209 input = AUDIO_PORT_HANDLE_NONE;
1210 portId = AUDIO_PORT_HANDLE_NONE;
1211 ASSERT_EQ(OK, mManager->getInputForAttr(
1212 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1213 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001214 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001215 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1216 ASSERT_TRUE(equals(requestedConfig, config));
1217
1218 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1219 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1220 "", "", AUDIO_FORMAT_DEFAULT));
1221}
1222
Mikhail Naganovc66ffc12024-05-30 16:56:25 -07001223TEST_F(AudioPolicyManagerTestWithConfigurationFile, CheckInputsForDeviceClosesStreams) {
1224 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1225 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1226 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1227 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1228 // Since 'checkInputsForDevice' is called as part of the 'setDeviceConnectionState',
1229 // call it directly here, as we need to ensure that it does not keep all intermediate
1230 // streams opened, as it may cause a rejection from the HAL based on the cap.
1231 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1232 sp<DeviceDescriptor> device = mManager->getHwModules().getDeviceDescriptor(
1233 AUDIO_DEVICE_IN_USB_DEVICE, "", "", AUDIO_FORMAT_DEFAULT, true /*allowToCreate*/);
1234 ASSERT_NE(nullptr, device.get());
1235 EXPECT_EQ(NO_ERROR,
1236 mManager->checkInputsForDevice(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
1237 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1238}
1239
1240TEST_F(AudioPolicyManagerTestWithConfigurationFile, SetDeviceConnectionStateClosesStreams) {
1241 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1242 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1243 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1244 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1245 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1246 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1247 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1248 "", "", AUDIO_FORMAT_DEFAULT));
1249 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1250}
1251
jiabin5e02d2b2024-09-23 19:26:19 +00001252TEST_F(AudioPolicyManagerTestWithConfigurationFile, UpdateConfigFromInexactProfile) {
1253 const audio_format_t expectedFormat = AUDIO_FORMAT_PCM_16_BIT;
1254 const uint32_t expectedSampleRate = 48000;
1255 const audio_channel_mask_t expectedChannelMask = AUDIO_CHANNEL_IN_STEREO;
1256 const std::string expectedIOProfile = "primary input";
1257
1258 auto devices = mManager->getAvailableInputDevices();
1259 sp<DeviceDescriptor> mic = nullptr;
1260 for (auto device : devices) {
1261 if (device->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
1262 mic = device;
1263 break;
1264 }
1265 }
1266 EXPECT_NE(nullptr, mic);
1267
1268 audio_format_t requestedFormat = AUDIO_FORMAT_PCM_16_BIT;
1269 uint32_t requestedSampleRate = 44100;
1270 audio_channel_mask_t requestedChannelMask = AUDIO_CHANNEL_IN_STEREO;
1271 auto profile = mManager->getInputProfile(
1272 mic, requestedSampleRate, requestedFormat, requestedChannelMask, AUDIO_INPUT_FLAG_NONE);
1273 EXPECT_EQ(expectedIOProfile, profile->getName());
1274 EXPECT_EQ(expectedFormat, requestedFormat);
1275 EXPECT_EQ(expectedSampleRate, requestedSampleRate);
1276 EXPECT_EQ(expectedChannelMask, requestedChannelMask);
1277}
1278
jiabin7c0205e2019-09-05 10:26:04 -07001279class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
jiabinf4eb15a2019-08-28 15:31:47 -07001280protected:
jiabinf4eb15a2019-08-28 15:31:47 -07001281 void TearDown() override;
1282
1283 status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
1284 std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001285 const std::vector<AudioMixMatchCriterion>& matchCriteria);
Marvin Raminbdefaf02023-11-01 09:10:32 +01001286
Marvin Raminabd9b892023-11-17 16:36:27 +01001287 status_t addPolicyMix(const AudioMix& mix);
1288
1289 status_t removePolicyMixes(const Vector<AudioMix>& mixes);
1290
Marvin Raminbdefaf02023-11-01 09:10:32 +01001291 std::vector<AudioMix> getRegisteredPolicyMixes();
jiabinf4eb15a2019-08-28 15:31:47 -07001292 void clearPolicyMix();
jiabin24ff57a2023-11-27 21:06:51 +00001293 void addPolicyMixAndStartInputForLoopback(
1294 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1295 const audio_config_t& audioConfig,
1296 const std::vector<AudioMixMatchCriterion>& matchCriteria,
1297 audio_session_t session=AUDIO_SESSION_NONE,
1298 audio_config_base_t config=DEFAULT_INPUT_CONFIG,
1299 audio_input_flags_t inputFlags=AUDIO_INPUT_FLAG_NONE);
jiabinf4eb15a2019-08-28 15:31:47 -07001300
1301 Vector<AudioMix> mAudioMixes;
jiabinf4eb15a2019-08-28 15:31:47 -07001302 const std::string mMixAddress = "remote_submix_media";
jiabin24ff57a2023-11-27 21:06:51 +00001303
1304 audio_port_handle_t mLoopbackInputPortId = AUDIO_PORT_HANDLE_NONE;
1305 std::unique_ptr<RecordingActivityTracker> mTracker;
1306 struct audio_port_v7 mInjectionPort;
1307
1308 constexpr static const audio_config_base_t DEFAULT_INPUT_CONFIG = {
1309 .sample_rate = k48000SamplingRate,
1310 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1311 .format = AUDIO_FORMAT_PCM_16_BIT
1312 };
jiabinf4eb15a2019-08-28 15:31:47 -07001313};
1314
jiabinf4eb15a2019-08-28 15:31:47 -07001315void AudioPolicyManagerTestDynamicPolicy::TearDown() {
jiabin24ff57a2023-11-27 21:06:51 +00001316 clearPolicyMix();
jiabin7c0205e2019-09-05 10:26:04 -07001317 AudioPolicyManagerTestWithConfigurationFile::TearDown();
jiabinf4eb15a2019-08-28 15:31:47 -07001318}
1319
1320status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
1321 audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001322 const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
1323 AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
jiabinf4eb15a2019-08-28 15:31:47 -07001324 String8(mixAddress.c_str()), 0);
1325 myAudioMix.mDeviceType = deviceType;
Marvin Ramin0783e202024-03-05 12:45:50 +01001326 myAudioMix.mToken = sp<BBinder>::make();
jiabinf4eb15a2019-08-28 15:31:47 -07001327 // Clear mAudioMix before add new one to make sure we don't add already exist mixes.
1328 mAudioMixes.clear();
Marvin Raminabd9b892023-11-17 16:36:27 +01001329 return addPolicyMix(myAudioMix);
1330}
1331
1332status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(const AudioMix& mix) {
1333 mAudioMixes.add(mix);
jiabinf4eb15a2019-08-28 15:31:47 -07001334
1335 // As the policy mixes registration may fail at some case,
1336 // caller need to check the returned status.
1337 status_t ret = mManager->registerPolicyMixes(mAudioMixes);
1338 return ret;
1339}
1340
Marvin Raminabd9b892023-11-17 16:36:27 +01001341status_t AudioPolicyManagerTestDynamicPolicy::removePolicyMixes(const Vector<AudioMix>& mixes) {
1342 status_t ret = mManager->unregisterPolicyMixes(mixes);
1343 return ret;
1344}
1345
Marvin Raminbdefaf02023-11-01 09:10:32 +01001346std::vector<AudioMix> AudioPolicyManagerTestDynamicPolicy::getRegisteredPolicyMixes() {
1347 std::vector<AudioMix> audioMixes;
1348 if (mManager != nullptr) {
1349 status_t ret = mManager->getRegisteredPolicyMixes(audioMixes);
1350 EXPECT_EQ(NO_ERROR, ret);
1351 }
1352 return audioMixes;
1353}
1354
jiabinf4eb15a2019-08-28 15:31:47 -07001355void AudioPolicyManagerTestDynamicPolicy::clearPolicyMix() {
1356 if (mManager != nullptr) {
jiabin24ff57a2023-11-27 21:06:51 +00001357 mManager->stopInput(mLoopbackInputPortId);
jiabinf4eb15a2019-08-28 15:31:47 -07001358 mManager->unregisterPolicyMixes(mAudioMixes);
1359 }
1360 mAudioMixes.clear();
1361}
1362
jiabin24ff57a2023-11-27 21:06:51 +00001363void AudioPolicyManagerTestDynamicPolicy::addPolicyMixAndStartInputForLoopback(
1364 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1365 const audio_config_t& audioConfig,
1366 const std::vector<AudioMixMatchCriterion>& matchCriteria, audio_session_t session,
1367 audio_config_base_t config, audio_input_flags_t inputFlags) {
1368 ASSERT_EQ(NO_ERROR,
1369 addPolicyMix(mixType, mixFlag, deviceType, mixAddress, audioConfig, matchCriteria));
1370 if ((mixFlag & MIX_ROUTE_FLAG_LOOP_BACK) != MIX_ROUTE_FLAG_LOOP_BACK) {
1371 return;
1372 }
1373
1374 mTracker.reset(new RecordingActivityTracker());
1375 struct audio_port_v7 extractionPort;
1376 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1377 mixAddress, &extractionPort));
1378 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1379 audio_source_t source = AUDIO_SOURCE_REMOTE_SUBMIX;
1380 audio_attributes_t attr = {
1381 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source, AUDIO_FLAG_NONE, ""};
1382 std::string tags = "addr=" + mMixAddress;
1383 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1384 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
1385 ASSERT_NO_FATAL_FAILURE(
1386 getInputForAttr(attr, &input, session, mTracker->getRiid(),
1387 &selectedDeviceId, config.format, config.channel_mask,
1388 config.sample_rate, inputFlags, &mLoopbackInputPortId));
1389 ASSERT_EQ(NO_ERROR, mManager->startInput(mLoopbackInputPortId));
1390 ASSERT_EQ(extractionPort.id, selectedDeviceId);
1391
1392 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1393 mMixAddress, &mInjectionPort));
1394}
1395
jiabinf4eb15a2019-08-28 15:31:47 -07001396TEST_F(AudioPolicyManagerTestDynamicPolicy, InitSuccess) {
jiabin7c0205e2019-09-05 10:26:04 -07001397 // SetUp must finish with no assertions
jiabinf4eb15a2019-08-28 15:31:47 -07001398}
1399
1400TEST_F(AudioPolicyManagerTestDynamicPolicy, Dump) {
1401 dumpToLog();
1402}
1403
1404TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyMixes) {
1405 status_t ret;
1406 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1407
1408 // Only capture of playback is allowed in LOOP_BACK &RENDER mode
1409 ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001410 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001411 ASSERT_EQ(INVALID_OPERATION, ret);
1412
1413 // Fail due to the device is already connected.
1414 clearPolicyMix();
1415 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001416 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001417 ASSERT_EQ(INVALID_OPERATION, ret);
1418
1419 // The first time to register policy mixes with valid parameter should succeed.
1420 clearPolicyMix();
1421 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1422 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001423 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001424 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001425 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001426 ASSERT_EQ(NO_ERROR, ret);
1427 // Registering the same policy mixes should fail.
1428 ret = mManager->registerPolicyMixes(mAudioMixes);
1429 ASSERT_EQ(INVALID_OPERATION, ret);
1430
jiabinf4eb15a2019-08-28 15:31:47 -07001431 // Registration should fail due to device not found.
1432 // Note that earpiece is not present in the test configuration file.
1433 // This will need to be updated if earpiece is added in the test configuration file.
jiabin7c0205e2019-09-05 10:26:04 -07001434 clearPolicyMix();
jiabinf4eb15a2019-08-28 15:31:47 -07001435 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001436 AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001437 ASSERT_EQ(INVALID_OPERATION, ret);
1438
1439 // Registration should fail due to output not found.
1440 clearPolicyMix();
1441 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001442 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001443 ASSERT_EQ(INVALID_OPERATION, ret);
1444
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001445 // The first time to register valid loopback policy mix should succeed.
jiabinf4eb15a2019-08-28 15:31:47 -07001446 clearPolicyMix();
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001447 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1448 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001449 ASSERT_EQ(NO_ERROR, ret);
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001450 // Registering the render policy for the loopback address should succeed.
1451 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
1452 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001453 ASSERT_EQ(INVALID_OPERATION, ret);
1454}
1455
1456TEST_F(AudioPolicyManagerTestDynamicPolicy, UnregisterPolicyMixes) {
1457 status_t ret;
1458 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1459
1460 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1461 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001462 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001463 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001464 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001465 ASSERT_EQ(NO_ERROR, ret);
1466
1467 // After successfully registering policy mixes, it should be able to unregister.
1468 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1469 ASSERT_EQ(NO_ERROR, ret);
1470
1471 // After unregistering policy mixes successfully, it should fail unregistering
1472 // the same policy mixes as they are not registered.
1473 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1474 ASSERT_EQ(INVALID_OPERATION, ret);
jiabin7c0205e2019-09-05 10:26:04 -07001475}
jiabinf4eb15a2019-08-28 15:31:47 -07001476
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001477TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
1478 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1479 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1480 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1481 audioConfig.sample_rate = k48000SamplingRate;
1482
1483 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1484 createUidCriterion(/*uid=*/42),
1485 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1486 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1487 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1488 mixMatchCriteria);
1489 ASSERT_EQ(NO_ERROR, ret);
1490}
1491
1492TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
1493 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1494 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1495 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1496 audioConfig.sample_rate = k48000SamplingRate;
1497
1498 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1499 createUidCriterion(/*uid=*/42),
1500 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1501 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1502 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1503 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1504 mixMatchCriteria);
1505 ASSERT_EQ(INVALID_OPERATION, ret);
1506}
1507
Marvin Raminbdefaf02023-11-01 09:10:32 +01001508TEST_F_WITH_FLAGS(
1509 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminabd9b892023-11-17 16:36:27 +01001510 RegisterInvalidMixesDoesNotImpactPriorMixes,
1511 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1512 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1513) {
1514 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1515 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1516 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1517 audioConfig.sample_rate = k48000SamplingRate;
1518
1519 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1520 createUidCriterion(/*uid=*/42),
1521 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1522 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1523 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1524 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1525
1526 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001527 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001528
1529 ASSERT_EQ(NO_ERROR, ret);
1530
1531 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1532 ASSERT_EQ(1, registeredMixes.size());
1533
1534 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1535 createUidCriterion(/*uid=*/42),
1536 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1537 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1538
1539 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1540 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1541 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1542
Marvin Ramin0783e202024-03-05 12:45:50 +01001543 ret = addPolicyMix(invalidAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001544
1545 ASSERT_EQ(INVALID_OPERATION, ret);
1546
1547 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1548 ASSERT_EQ(registeredMixes.size(), remainingMixes.size());
1549}
1550
1551TEST_F_WITH_FLAGS(
1552 AudioPolicyManagerTestDynamicPolicy,
1553 UnregisterInvalidMixesReturnsError,
1554 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1555 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1556) {
1557 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1558 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1559 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1560 audioConfig.sample_rate = k48000SamplingRate;
1561
1562 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1563 createUidCriterion(/*uid=*/42),
1564 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1565 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1566 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1567 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1568
1569 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001570 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001571
1572 ASSERT_EQ(NO_ERROR, ret);
1573
1574 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1575 ASSERT_EQ(1, registeredMixes.size());
1576
1577 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1578 createUidCriterion(/*uid=*/42),
1579 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1580 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1581
1582 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1583 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
Marvin Ramin0783e202024-03-05 12:45:50 +01001584 invalidAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Marvin Raminabd9b892023-11-17 16:36:27 +01001585
1586 Vector<AudioMix> mixes;
1587 mixes.add(invalidAudioMix);
1588 mixes.add(validAudioMix);
1589 ret = removePolicyMixes(mixes);
1590
1591 ASSERT_EQ(INVALID_OPERATION, ret);
1592
1593 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1594 EXPECT_THAT(remainingMixes, IsEmpty());
1595}
1596
1597TEST_F_WITH_FLAGS(
1598 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminbdefaf02023-11-01 09:10:32 +01001599 GetRegisteredPolicyMixes,
1600 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1601) {
1602 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1603 EXPECT_THAT(mixes, IsEmpty());
1604}
1605
1606TEST_F_WITH_FLAGS(AudioPolicyManagerTestDynamicPolicy,
1607 AddPolicyMixAndVerifyGetRegisteredPolicyMixes,
1608 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1609) {
1610 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1611 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1612 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1613 audioConfig.sample_rate = k48000SamplingRate;
1614
1615 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1616 createUidCriterion(/*uid=*/42),
1617 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1618 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1619 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1620 mixMatchCriteria);
1621 ASSERT_EQ(NO_ERROR, ret);
1622
1623 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1624 ASSERT_EQ(mixes.size(), 1);
1625
1626 const AudioMix& mix = mixes[0];
1627 ASSERT_EQ(mix.mCriteria.size(), mixMatchCriteria.size());
1628 for (uint32_t i = 0; i < mixMatchCriteria.size(); i++) {
1629 EXPECT_EQ(mix.mCriteria[i].mRule, mixMatchCriteria[i].mRule);
1630 EXPECT_EQ(mix.mCriteria[i].mValue.mUsage, mixMatchCriteria[i].mValue.mUsage);
1631 }
1632 EXPECT_EQ(mix.mDeviceType, AUDIO_DEVICE_OUT_REMOTE_SUBMIX);
1633 EXPECT_EQ(mix.mRouteFlags, MIX_ROUTE_FLAG_LOOP_BACK);
1634 EXPECT_EQ(mix.mMixType, MIX_TYPE_PLAYERS);
1635 EXPECT_EQ(mix.mFormat.channel_mask, audioConfig.channel_mask);
1636 EXPECT_EQ(mix.mFormat.format, audioConfig.format);
1637 EXPECT_EQ(mix.mFormat.sample_rate, audioConfig.sample_rate);
1638 EXPECT_EQ(mix.mFormat.frame_count, audioConfig.frame_count);
1639}
1640
Kriti Dangef6be8f2020-11-05 11:58:19 +01001641class AudioPolicyManagerTestForHdmi
Mikhail Naganov18885d32021-10-01 13:03:09 -07001642 : public AudioPolicyManagerTestWithConfigurationFile,
1643 public testing::WithParamInterface<audio_format_t> {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001644protected:
1645 void SetUp() override;
1646 std::string getConfigFile() override { return sTvConfig; }
Kriti Dang6537def2021-03-02 13:46:59 +01001647 std::map<audio_format_t, bool> getSurroundFormatsHelper();
1648 std::vector<audio_format_t> getReportedSurroundFormatsHelper();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001649 std::unordered_set<audio_format_t> getFormatsFromPorts();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001650 void TearDown() override;
1651
1652 static const std::string sTvConfig;
1653
1654};
1655
1656const std::string AudioPolicyManagerTestForHdmi::sTvConfig =
1657 AudioPolicyManagerTestForHdmi::sExecutableDir +
1658 "test_settop_box_surround_configuration.xml";
1659
1660void AudioPolicyManagerTestForHdmi::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001661 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUp());
Mikhail Naganov83caee02021-10-05 15:52:01 -07001662 mClient->addSupportedFormat(AUDIO_FORMAT_AC3);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001663 mClient->addSupportedFormat(AUDIO_FORMAT_E_AC3);
jiabin12537fc2023-10-12 17:56:08 +00001664 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001665 mManager->setDeviceConnectionState(
1666 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1667 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1668}
1669
1670void AudioPolicyManagerTestForHdmi::TearDown() {
1671 mManager->setDeviceConnectionState(
1672 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1673 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1674 AudioPolicyManagerTest::TearDown();
1675}
1676
1677std::map<audio_format_t, bool>
Kriti Dang6537def2021-03-02 13:46:59 +01001678 AudioPolicyManagerTestForHdmi::getSurroundFormatsHelper() {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001679 unsigned int numSurroundFormats = 0;
1680 std::map<audio_format_t, bool> surroundFormatsMap;
1681 status_t ret = mManager->getSurroundFormats(
1682 &numSurroundFormats, nullptr /* surroundFormats */,
Kriti Dang6537def2021-03-02 13:46:59 +01001683 nullptr /* surroundFormatsEnabled */);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001684 EXPECT_EQ(NO_ERROR, ret);
1685 if (ret != NO_ERROR) {
1686 return surroundFormatsMap;
1687 }
1688 audio_format_t surroundFormats[numSurroundFormats];
1689 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1690 bool surroundFormatsEnabled[numSurroundFormats];
1691 memset(surroundFormatsEnabled, 0, sizeof(bool) * numSurroundFormats);
1692 ret = mManager->getSurroundFormats(
Kriti Dang6537def2021-03-02 13:46:59 +01001693 &numSurroundFormats, surroundFormats, surroundFormatsEnabled);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001694 EXPECT_EQ(NO_ERROR, ret);
1695 if (ret != NO_ERROR) {
1696 return surroundFormatsMap;
1697 }
1698 for (int i = 0; i< numSurroundFormats; i++) {
1699 surroundFormatsMap[surroundFormats[i]] = surroundFormatsEnabled[i];
1700 }
1701 return surroundFormatsMap;
1702}
1703
Kriti Dang6537def2021-03-02 13:46:59 +01001704std::vector<audio_format_t> AudioPolicyManagerTestForHdmi::getReportedSurroundFormatsHelper() {
1705 unsigned int numSurroundFormats = 0;
1706 std::vector<audio_format_t> surroundFormatsVector;
1707 status_t ret = mManager->getReportedSurroundFormats(
1708 &numSurroundFormats, nullptr /* surroundFormats */);
1709 EXPECT_EQ(NO_ERROR, ret);
1710 if (ret != NO_ERROR) {
1711 return surroundFormatsVector;
1712 }
1713 audio_format_t surroundFormats[numSurroundFormats];
1714 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1715 ret = mManager->getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
1716 EXPECT_EQ(NO_ERROR, ret);
1717 if (ret != NO_ERROR) {
1718 return surroundFormatsVector;
1719 }
1720 for (const auto &surroundFormat : surroundFormats) {
1721 surroundFormatsVector.push_back(surroundFormat);
1722 }
1723 return surroundFormatsVector;
1724}
1725
Kriti Dangef6be8f2020-11-05 11:58:19 +01001726std::unordered_set<audio_format_t>
1727 AudioPolicyManagerTestForHdmi::getFormatsFromPorts() {
1728 uint32_t numPorts = 0;
1729 uint32_t generation1;
1730 status_t ret;
1731 std::unordered_set<audio_format_t> formats;
1732 ret = mManager->listAudioPorts(
1733 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
1734 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1735 if (ret != NO_ERROR) {
1736 return formats;
1737 }
jiabin19cdba52020-11-24 11:28:58 -08001738 struct audio_port_v7 ports[numPorts];
Kriti Dangef6be8f2020-11-05 11:58:19 +01001739 ret = mManager->listAudioPorts(
1740 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation1);
1741 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1742 if (ret != NO_ERROR) {
1743 return formats;
1744 }
1745 for (const auto &port : ports) {
jiabin19cdba52020-11-24 11:28:58 -08001746 for (size_t i = 0; i < port.num_audio_profiles; ++i) {
1747 formats.insert(port.audio_profiles[i].format);
1748 }
Kriti Dangef6be8f2020-11-05 11:58:19 +01001749 }
1750 return formats;
1751}
1752
Mikhail Naganov18885d32021-10-01 13:03:09 -07001753TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsReturnsSupportedFormats) {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001754 mManager->setForceUse(
1755 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001756 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001757 ASSERT_EQ(1, surroundFormats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001758}
1759
Mikhail Naganov18885d32021-10-01 13:03:09 -07001760TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001761 GetSurroundFormatsReturnsManipulatedFormats) {
1762 mManager->setForceUse(
1763 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1764
1765 status_t ret =
Mikhail Naganov18885d32021-10-01 13:03:09 -07001766 mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001767 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001768 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001769 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1770 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001771
Mikhail Naganov18885d32021-10-01 13:03:09 -07001772 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001773 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001774 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001775 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1776 ASSERT_TRUE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001777
Mikhail Naganov18885d32021-10-01 13:03:09 -07001778 ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001779 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001780 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001781 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1782 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001783}
1784
Mikhail Naganov18885d32021-10-01 13:03:09 -07001785TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001786 ListAudioPortsReturnManipulatedHdmiFormats) {
1787 mManager->setForceUse(
1788 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1789
Mikhail Naganov18885d32021-10-01 13:03:09 -07001790 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/));
jiabin12537fc2023-10-12 17:56:08 +00001791 auto formats = getFormatsFromPorts();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001792 ASSERT_EQ(1, formats.count(GetParam()));
jiabin12537fc2023-10-12 17:56:08 +00001793
1794 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/));
1795 formats = getFormatsFromPorts();
1796 ASSERT_EQ(0, formats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001797}
1798
Mikhail Naganov18885d32021-10-01 13:03:09 -07001799TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001800 GetReportedSurroundFormatsReturnsHdmiReportedFormats) {
1801 mManager->setForceUse(
1802 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001803 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001804 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001805}
1806
Mikhail Naganov18885d32021-10-01 13:03:09 -07001807TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001808 GetReportedSurroundFormatsReturnsNonManipulatedHdmiReportedFormats) {
1809 mManager->setForceUse(
1810 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1811
Mikhail Naganov18885d32021-10-01 13:03:09 -07001812 status_t ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001813 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001814 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001815 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001816
Mikhail Naganov18885d32021-10-01 13:03:09 -07001817 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001818 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001819 surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001820 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001821}
1822
Mikhail Naganov18885d32021-10-01 13:03:09 -07001823TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsIgnoresSupportedFormats) {
1824 mManager->setForceUse(
1825 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER);
1826 auto surroundFormats = getSurroundFormatsHelper();
1827 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1828 ASSERT_FALSE(surroundFormats[GetParam()]);
1829}
1830
1831INSTANTIATE_TEST_SUITE_P(SurroundFormatSupport, AudioPolicyManagerTestForHdmi,
1832 testing::Values(AUDIO_FORMAT_AC3, AUDIO_FORMAT_E_AC3),
1833 [](const ::testing::TestParamInfo<AudioPolicyManagerTestForHdmi::ParamType>& info) {
1834 return audio_format_to_string(info.param);
1835 });
1836
jiabin7c0205e2019-09-05 10:26:04 -07001837class AudioPolicyManagerTestDPNoRemoteSubmixModule : public AudioPolicyManagerTestDynamicPolicy {
1838protected:
1839 std::string getConfigFile() override { return sPrimaryOnlyConfig; }
1840
1841 static const std::string sPrimaryOnlyConfig;
1842};
1843
1844const std::string AudioPolicyManagerTestDPNoRemoteSubmixModule::sPrimaryOnlyConfig =
1845 sExecutableDir + "test_audio_policy_primary_only_configuration.xml";
1846
1847TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, InitSuccess) {
1848 // SetUp must finish with no assertions.
1849}
1850
1851TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, Dump) {
1852 dumpToLog();
1853}
1854
1855TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, RegistrationFailure) {
1856 // Registration/Unregistration should fail due to module for remote submix not found.
1857 status_t ret;
1858 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1859 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1860 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001861 audioConfig.sample_rate = k48000SamplingRate;
jiabin7c0205e2019-09-05 10:26:04 -07001862 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001863 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabin7c0205e2019-09-05 10:26:04 -07001864 ASSERT_EQ(INVALID_OPERATION, ret);
1865
jiabinf4eb15a2019-08-28 15:31:47 -07001866 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1867 ASSERT_EQ(INVALID_OPERATION, ret);
1868}
1869
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001870struct DPTestParam {
1871 DPTestParam(const std::vector<AudioMixMatchCriterion>& mixCriteria,
1872 bool expected_match = false)
1873 : mixCriteria(mixCriteria), attributes(defaultAttr), session(AUDIO_SESSION_NONE),
1874 expected_match(expected_match) {}
1875
1876 DPTestParam& withUsage(audio_usage_t usage) {
1877 attributes.usage = usage;
1878 return *this;
1879 }
1880
1881 DPTestParam& withTags(const char *tags) {
1882 std::strncpy(attributes.tags, tags, sizeof(attributes.tags));
1883 return *this;
1884 }
1885
1886 DPTestParam& withSource(audio_source_t source) {
1887 attributes.source = source;
1888 return *this;
1889 }
1890
1891 DPTestParam& withSessionId(audio_session_t sessionId) {
1892 session = sessionId;
1893 return *this;
1894 }
1895
1896 std::vector<AudioMixMatchCriterion> mixCriteria;
1897 audio_attributes_t attributes;
1898 audio_session_t session;
1899 bool expected_match;
1900};
1901
jiabinf4eb15a2019-08-28 15:31:47 -07001902class AudioPolicyManagerTestDPPlaybackReRouting : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001903 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07001904protected:
1905 void SetUp() override;
jiabinf4eb15a2019-08-28 15:31:47 -07001906};
1907
1908void AudioPolicyManagerTestDPPlaybackReRouting::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001909 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07001910
1911 mTracker.reset(new RecordingActivityTracker());
1912
1913 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1914 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1915 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001916 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001917
1918 DPTestParam param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00001919 ASSERT_NO_FATAL_FAILURE(
1920 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1921 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria,
1922 param.session));
jiabinf4eb15a2019-08-28 15:31:47 -07001923}
1924
jiabinf4eb15a2019-08-28 15:31:47 -07001925TEST_P(AudioPolicyManagerTestDPPlaybackReRouting, PlaybackReRouting) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001926 const DPTestParam param = GetParam();
1927 const audio_attributes_t& attr = param.attributes;
jiabinf4eb15a2019-08-28 15:31:47 -07001928
jiabin7c0205e2019-09-05 10:26:04 -07001929 audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07001930 getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11001931 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001932 attr, param.session);
1933 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07001934 EXPECT_EQ(mInjectionPort.id, playbackRoutedPortId);
1935 } else {
1936 EXPECT_NE(mInjectionPort.id, playbackRoutedPortId);
1937 }
1938}
1939
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001940const std::vector<AudioMixMatchCriterion> USAGE_MEDIA_ALARM_CRITERIA = {
1941 createUsageCriterion(AUDIO_USAGE_MEDIA),
1942 createUsageCriterion(AUDIO_USAGE_ALARM)
1943};
jiabinf4eb15a2019-08-28 15:31:47 -07001944
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001945INSTANTIATE_TEST_SUITE_P(
1946 PlaybackReroutingUsageMatch,
1947 AudioPolicyManagerTestDPPlaybackReRouting,
1948 testing::Values(
1949 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1950 .withUsage(AUDIO_USAGE_MEDIA),
1951 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1952 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=other"),
1953 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1954 .withUsage(AUDIO_USAGE_ALARM),
1955 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1956 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION),
1957 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1958 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING),
1959 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1960 .withUsage(AUDIO_USAGE_NOTIFICATION),
1961 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1962 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE),
1963 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1964 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST),
1965 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1966 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT),
1967 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1968 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED),
1969 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1970 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT),
1971 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1972 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY),
1973 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1974 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE),
1975 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1976 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION),
1977 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1978 .withUsage(AUDIO_USAGE_GAME),
1979 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1980 .withUsage(AUDIO_USAGE_ASSISTANT)));
jiabinf4eb15a2019-08-28 15:31:47 -07001981
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001982INSTANTIATE_TEST_SUITE_P(
1983 PlaybackReroutingAddressPriorityMatch,
1984 AudioPolicyManagerTestDPPlaybackReRouting,
1985 testing::Values(
1986 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1987 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=remote_submix_media"),
1988 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1989 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION).withTags("addr=remote_submix_media"),
1990 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1991 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING)
1992 .withTags("addr=remote_submix_media"),
1993 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1994 .withUsage(AUDIO_USAGE_ALARM)
1995 .withTags("addr=remote_submix_media"),
1996 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1997 .withUsage(AUDIO_USAGE_NOTIFICATION)
1998 .withTags("addr=remote_submix_media"),
1999 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2000 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE)
2001 .withTags("addr=remote_submix_media"),
2002 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2003 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST)
2004 .withTags("addr=remote_submix_media"),
2005 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2006 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
2007 .withTags("addr=remote_submix_media"),
2008 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2009 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED)
2010 .withTags("addr=remote_submix_media"),
2011 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2012 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT)
2013 .withTags("addr=remote_submix_media"),
2014 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2015 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY)
2016 .withTags("addr=remote_submix_media"),
2017 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2018 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
2019 .withTags("addr=remote_submix_media"),
2020 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2021 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION)
2022 .withTags("addr=remote_submix_media"),
2023 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2024 .withUsage(AUDIO_USAGE_GAME)
2025 .withTags("addr=remote_submix_media"),
2026 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2027 .withUsage(AUDIO_USAGE_VIRTUAL_SOURCE)
2028 .withTags("addr=remote_submix_media"),
2029 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2030 .withUsage(AUDIO_USAGE_ASSISTANT)
Jan Sebechlebskybc56bcd2022-09-26 13:15:19 +02002031 .withTags("addr=remote_submix_media"),
2032 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2033 .withUsage(AUDIO_USAGE_ASSISTANT)
2034 .withTags("sometag;addr=remote_submix_media;othertag=somevalue"),
2035 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2036 .withUsage(AUDIO_USAGE_ASSISTANT)
2037 .withTags("addr=remote_submix_media;othertag"),
2038 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2039 .withUsage(AUDIO_USAGE_ASSISTANT)
2040 .withTags("sometag;othertag;addr=remote_submix_media")));
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002041
2042static constexpr audio_session_t TEST_SESSION_ID = static_cast<audio_session_t>(42);
2043static constexpr audio_session_t OTHER_SESSION_ID = static_cast<audio_session_t>(77);
2044
2045INSTANTIATE_TEST_SUITE_P(
2046 PlaybackReRoutingWithSessionId,
2047 AudioPolicyManagerTestDPPlaybackReRouting,
2048 testing::Values(
2049 // Mix is matched because the session id matches the one specified by the mix rule.
2050 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2051 /*expected_match=*/ true)
2052 .withSessionId(TEST_SESSION_ID),
2053 // Mix is not matched because the session id doesn't match the one specified
2054 // by the mix rule.
2055 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2056 /*expected_match=*/ false)
2057 .withSessionId(OTHER_SESSION_ID),
2058 // Mix is matched, the session id doesn't match the one specified by rule,
2059 // but there's address specified in the tags which takes precedence.
2060 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2061 /*expected_match=*/ true)
2062 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2063 // Mix is matched, both the session id and the usage match ones specified by mix rule.
2064 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2065 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2066 /*expected_match=*/ true)
2067 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA),
2068 // Mix is not matched, the session id matches the one specified by mix rule,
2069 // but usage does not.
2070 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2071 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2072 /*expected_match=*/ false)
2073 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_GAME),
2074 // Mix is not matched, the usage matches the one specified by mix rule,
2075 // but the session id is excluded.
2076 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID, /*exclude=*/ true),
2077 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2078 /*expected_match=*/ false)
2079 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA)));
jiabinf4eb15a2019-08-28 15:31:47 -07002080
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002081struct DPMmapTestParam {
2082 DPMmapTestParam(int mixRouteFlags, audio_devices_t deviceType, const std::string& deviceAddress)
2083 : mixRouteFlags(mixRouteFlags), deviceType(deviceType), deviceAddress(deviceAddress) {}
2084
2085 int mixRouteFlags;
2086 audio_devices_t deviceType;
2087 std::string deviceAddress;
2088};
2089
2090class AudioPolicyManagerTestMMapPlaybackRerouting
2091 : public AudioPolicyManagerTestDynamicPolicy,
2092 public ::testing::WithParamInterface<DPMmapTestParam> {
2093 protected:
2094 void SetUp() override {
2095 AudioPolicyManagerTestDynamicPolicy::SetUp();
2096 audioConfig = AUDIO_CONFIG_INITIALIZER;
2097 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2098 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2099 audioConfig.sample_rate = k48000SamplingRate;
2100 }
2101
2102 audio_config_t audioConfig;
2103 audio_io_handle_t mOutput;
2104 audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
2105 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebskyb3d3f622023-07-13 11:09:15 +02002106 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002107 AudioPolicyInterface::output_type_t mOutputType;
2108 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
2109 bool mIsSpatialized;
2110 bool mIsBitPerfect;
Andy Hung6b137d12024-08-27 22:35:17 +00002111 float mVolume;
Vlad Popa1e865e62024-08-15 19:11:42 -07002112 bool mMuted;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002113};
2114
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002115TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting, MmapPlaybackStreamMatchingLoopbackDapMixFails) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002116 // Add mix matching the test uid.
2117 const int testUid = 12345;
2118 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002119 ASSERT_NO_FATAL_FAILURE(
2120 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2121 param.deviceType, param.deviceAddress, audioConfig,
2122 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002123
jiabin24ff57a2023-11-27 21:06:51 +00002124 // Getting output for matching uid and mmap-ed stream should fail.
2125 audio_output_flags_t outputFlags =
2126 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002127 ASSERT_EQ(INVALID_OPERATION,
2128 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2129 createAttributionSourceState(testUid), &audioConfig,
2130 &outputFlags, &mSelectedDeviceId, &mPortId, {},
Vlad Popa1e865e62024-08-15 19:11:42 -07002131 &mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
2132 &mMuted));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002133}
2134
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002135TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting,
2136 NonMmapPlaybackStreamMatchingLoopbackDapMixSucceeds) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002137 // Add mix matching the test uid.
2138 const int testUid = 12345;
2139 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002140 ASSERT_NO_FATAL_FAILURE(
2141 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2142 param.deviceType,param.deviceAddress, audioConfig,
2143 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002144
jiabin24ff57a2023-11-27 21:06:51 +00002145 // Getting output for matching uid should succeed for non-mmaped stream.
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002146 audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2147 ASSERT_EQ(NO_ERROR,
2148 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2149 createAttributionSourceState(testUid), &audioConfig,
2150 &outputFlags, &mSelectedDeviceId, &mPortId, {},
Vlad Popa1e865e62024-08-15 19:11:42 -07002151 &mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
2152 &mMuted));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002153}
2154
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002155TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002156 MmapPlaybackStreamMatchingRenderDapMixSupportingMmapSucceeds) {
jiabin24ff57a2023-11-27 21:06:51 +00002157 const std::string usbAddress = "card=1;device=0";
2158 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2159 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2160 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
2161 audio_port_v7 usbDevicePort;
2162 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_USB_DEVICE,
2163 usbAddress, &usbDevicePort));
2164
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002165 // Add render-only mix matching the test uid.
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002166 const int testUid = 12345;
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002167 // test_audio_policy_configuration.xml declares mmap-capable mix port
2168 // for AUDIO_DEVICE_OUT_USB_DEVICE.
jiabin24ff57a2023-11-27 21:06:51 +00002169 ASSERT_EQ(NO_ERROR,
2170 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2171 AUDIO_DEVICE_OUT_USB_DEVICE, /*mixAddress=*/"",
2172 audioConfig, {createUidCriterion(testUid)}));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002173
jiabin24ff57a2023-11-27 21:06:51 +00002174 static const audio_output_flags_t mmapDirectFlags =
2175 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
2176 // Getting output for matching uid should succeed for mmaped stream, because matched mix
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002177 // redirects to mmap capable device.
jiabin24ff57a2023-11-27 21:06:51 +00002178 audio_output_flags_t outputFlags = mmapDirectFlags;
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002179 ASSERT_EQ(NO_ERROR,
2180 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2181 createAttributionSourceState(testUid), &audioConfig,
2182 &outputFlags, &mSelectedDeviceId, &mPortId, {},
Vlad Popa1e865e62024-08-15 19:11:42 -07002183 &mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
2184 &mMuted));
jiabin24ff57a2023-11-27 21:06:51 +00002185 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2186 auto outputDesc = mManager->getOutputs().valueFor(mOutput);
2187 ASSERT_NE(nullptr, outputDesc);
2188 ASSERT_EQ(mmapDirectFlags, outputDesc->getFlags().output);
2189
2190 // After releasing the client, the output is closed. APM should reselect output for the policy
2191 // mix.
2192 mManager->releaseOutput(mPortId);
2193 ASSERT_EQ(nullptr, mManager->getOutputs().valueFor(mOutput));
2194 outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2195 mPortId = AUDIO_PORT_HANDLE_NONE;
2196 ASSERT_EQ(NO_ERROR,
2197 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2198 createAttributionSourceState(testUid), &audioConfig,
2199 &outputFlags, &mSelectedDeviceId, &mPortId, {},
Vlad Popa1e865e62024-08-15 19:11:42 -07002200 &mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
2201 &mMuted));
jiabin24ff57a2023-11-27 21:06:51 +00002202 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2203 outputDesc = mManager->getOutputs().valueFor(mOutput);
2204 ASSERT_NE(nullptr, outputDesc);
2205 ASSERT_NE(mmapDirectFlags, outputDesc->getFlags().output);
2206
2207 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2208 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2209 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002210}
2211
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002212TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
2213 MmapPlaybackStreamMatchingRenderDapMixNotSupportingMmapFails) {
2214 // Add render-only mix matching the test uid.
2215 const int testUid = 12345;
2216 // Per test_audio_policy_configuration.xml AUDIO_DEVICE_OUT_SPEAKER doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002217 ASSERT_EQ(NO_ERROR,
2218 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2219 AUDIO_DEVICE_OUT_SPEAKER, /*mixAddress=*/"", audioConfig,
2220 {createUidCriterion(testUid)}));
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002221
jiabin24ff57a2023-11-27 21:06:51 +00002222 // Getting output for matching uid should fail for mmaped stream, because
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002223 // matched mix redirects to device which doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002224 audio_output_flags_t outputFlags =
2225 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002226 ASSERT_EQ(INVALID_OPERATION,
2227 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2228 createAttributionSourceState(testUid), &audioConfig,
2229 &outputFlags, &mSelectedDeviceId, &mPortId, {},
Vlad Popa1e865e62024-08-15 19:11:42 -07002230 &mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
2231 &mMuted));
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002232}
2233
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002234INSTANTIATE_TEST_SUITE_P(
2235 MmapPlaybackRerouting, AudioPolicyManagerTestMMapPlaybackRerouting,
2236 testing::Values(DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2237 /*deviceAddress=*/"remote_submix_media"),
2238 DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
2239 AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
jiabin1ca6c6f2023-09-22 17:25:59 +00002240 /*deviceAddress=*/"remote_submix_media"),
2241 DPMmapTestParam(MIX_ROUTE_FLAG_RENDER, AUDIO_DEVICE_OUT_SPEAKER,
2242 /*deviceAddress=*/"")));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002243
jiabinf4eb15a2019-08-28 15:31:47 -07002244class AudioPolicyManagerTestDPMixRecordInjection : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002245 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07002246protected:
2247 void SetUp() override;
2248 void TearDown() override;
2249
2250 std::unique_ptr<RecordingActivityTracker> mTracker;
jiabin19cdba52020-11-24 11:28:58 -08002251 struct audio_port_v7 mExtractionPort;
jiabinf4eb15a2019-08-28 15:31:47 -07002252 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
2253};
2254
2255void AudioPolicyManagerTestDPMixRecordInjection::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07002256 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07002257
2258 mTracker.reset(new RecordingActivityTracker());
2259
2260 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2261 audioConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
2262 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002263 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002264
2265 DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002266 status_t ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002267 AUDIO_DEVICE_IN_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria);
jiabinf4eb15a2019-08-28 15:31:47 -07002268 ASSERT_EQ(NO_ERROR, ret);
2269
jiabin19cdba52020-11-24 11:28:58 -08002270 struct audio_port_v7 injectionPort;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002271 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2272 mMixAddress, &injectionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002273
2274 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2275 audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
Mikhail Naganov55773032020-10-01 15:08:13 -07002276 audio_attributes_t attr =
2277 {AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
jiabinf4eb15a2019-08-28 15:31:47 -07002278 std::string tags = std::string("addr=") + mMixAddress;
2279 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
2280 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002281 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, &mPortId, attr);
jiabinf4eb15a2019-08-28 15:31:47 -07002282 ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
2283 ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
2284
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002285 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
2286 mMixAddress, &mExtractionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002287}
2288
2289void AudioPolicyManagerTestDPMixRecordInjection::TearDown() {
2290 mManager->stopOutput(mPortId);
2291 AudioPolicyManagerTestDynamicPolicy::TearDown();
2292}
2293
jiabinf4eb15a2019-08-28 15:31:47 -07002294TEST_P(AudioPolicyManagerTestDPMixRecordInjection, RecordingInjection) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002295 const DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002296
jiabin7c0205e2019-09-05 10:26:04 -07002297 audio_port_handle_t captureRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07002298 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02002299 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2300 getInputForAttr(param.attributes, &input, param.session, mTracker->getRiid(),
2301 &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
2302 k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002303 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07002304 EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
2305 } else {
2306 EXPECT_NE(mExtractionPort.id, captureRoutedPortId);
2307 }
2308}
2309
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002310const std::vector<AudioMixMatchCriterion> SOURCE_CAM_MIC_VOICE_CRITERIA = {
2311 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
2312 createCapturePresetCriterion(AUDIO_SOURCE_MIC),
2313 createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
2314};
2315
jiabinf4eb15a2019-08-28 15:31:47 -07002316// No address priority rule for remote recording, address is a "don't care"
2317INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002318 RecordInjectionSource,
jiabinf4eb15a2019-08-28 15:31:47 -07002319 AudioPolicyManagerTestDPMixRecordInjection,
2320 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002321 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2322 .withSource(AUDIO_SOURCE_CAMCORDER),
2323 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2324 .withSource(AUDIO_SOURCE_CAMCORDER)
2325 .withTags("addr=remote_submix_media"),
2326 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2327 .withSource(AUDIO_SOURCE_MIC),
2328 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2329 .withSource(AUDIO_SOURCE_MIC)
2330 .withTags("addr=remote_submix_media"),
2331 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2332 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION),
2333 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2334 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION)
2335 .withTags("addr=remote_submix_media"),
2336 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2337 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION),
2338 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2339 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION)
2340 .withTags("addr=remote_submix_media"),
2341 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2342 .withSource(AUDIO_SOURCE_HOTWORD),
2343 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2344 .withSource(AUDIO_SOURCE_HOTWORD)
2345 .withTags("addr=remote_submix_media")));
jiabinf4eb15a2019-08-28 15:31:47 -07002346
jiabinf4eb15a2019-08-28 15:31:47 -07002347INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002348 RecordInjectionWithSessionId,
jiabinf4eb15a2019-08-28 15:31:47 -07002349 AudioPolicyManagerTestDPMixRecordInjection,
2350 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002351 // Mix is matched because the session id matches the one specified by the mix rule.
2352 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2353 /*expected_match=*/ true)
2354 .withSessionId(TEST_SESSION_ID),
2355 // Mix is not matched because the session id doesn't match the one specified
2356 // by the mix rule.
2357 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2358 /*expected_match=*/ false)
2359 .withSessionId(OTHER_SESSION_ID),
2360 // Mix is not matched, the session id doesn't match the one specified by rule,
2361 // but tand address specified in the tags is ignored for recorder mix.
2362 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2363 /*expected_match=*/ false)
2364 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2365 // Mix is matched, both the session id and the source match ones specified by mix rule
2366 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2367 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2368 /*expected_match=*/ true)
2369 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_CAMCORDER),
2370 // Mix is not matched, the session id matches the one specified by mix rule,
2371 // but source does not.
2372 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2373 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2374 /*expected_match=*/ false)
2375 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC),
2376 // Mix is not matched, the source matches the one specified by mix rule,
2377 // but the session id is excluded.
2378 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID,
2379 /*exclude=*/ true),
2380 createCapturePresetCriterion(AUDIO_SOURCE_MIC)},
2381 /*expected_match=*/ false)
2382 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC)));
jiabin43848a52019-09-05 14:07:25 -07002383
2384using DeviceConnectionTestParams =
2385 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/>;
2386
2387class AudioPolicyManagerTestDeviceConnection : public AudioPolicyManagerTestWithConfigurationFile,
2388 public testing::WithParamInterface<DeviceConnectionTestParams> {
2389};
2390
2391TEST_F(AudioPolicyManagerTestDeviceConnection, InitSuccess) {
2392 // SetUp must finish with no assertions.
2393}
2394
2395TEST_F(AudioPolicyManagerTestDeviceConnection, Dump) {
2396 dumpToLog();
2397}
2398
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002399TEST_F(AudioPolicyManagerTestDeviceConnection, RoutingUpdate) {
2400 mClient->resetRoutingUpdatedCounter();
2401 // Connecting a valid output device with valid parameters should trigger a routing update
2402 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2403 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002404 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002405 ASSERT_EQ(1, mClient->getRoutingUpdatedCounter());
2406
2407 // Disconnecting a connected device should succeed and trigger a routing update
2408 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2409 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002410 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002411 ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
2412
2413 // Disconnecting a disconnected device should fail and not trigger a routing update
2414 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2415 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002416 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002417 ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
2418
2419 // Changing force use should trigger an update
2420 auto config = mManager->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA);
2421 auto newConfig = config == AUDIO_POLICY_FORCE_BT_A2DP ?
2422 AUDIO_POLICY_FORCE_NONE : AUDIO_POLICY_FORCE_BT_A2DP;
2423 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, newConfig);
2424 ASSERT_EQ(3, mClient->getRoutingUpdatedCounter());
2425}
2426
jiabin43848a52019-09-05 14:07:25 -07002427TEST_P(AudioPolicyManagerTestDeviceConnection, SetDeviceConnectionState) {
2428 const audio_devices_t type = std::get<0>(GetParam());
2429 const std::string name = std::get<1>(GetParam());
2430 const std::string address = std::get<2>(GetParam());
2431
2432 if (type == AUDIO_DEVICE_OUT_HDMI) {
2433 // Set device connection state failed due to no device descriptor found
2434 // For HDMI case, it is easier to simulate device descriptor not found error
Mikhail Naganov83caee02021-10-05 15:52:01 -07002435 // by using an encoded format which isn't listed in the 'encodedFormats'
2436 // attribute for this devicePort.
jiabin43848a52019-09-05 14:07:25 -07002437 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2438 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2439 address.c_str(), name.c_str(), AUDIO_FORMAT_MAT_2_1));
2440 }
2441 // Connect with valid parameters should succeed
2442 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2443 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2444 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2445 // Try to connect with the same device again should fail
2446 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2447 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2448 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2449 // Disconnect the connected device should succeed
2450 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2451 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2452 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2453 // Disconnect device that is not connected should fail
2454 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2455 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2456 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2457 // Try to set device connection state with a invalid connection state should fail
2458 ASSERT_EQ(BAD_VALUE, mManager->setDeviceConnectionState(
2459 type, AUDIO_POLICY_DEVICE_STATE_CNT,
2460 "", "", AUDIO_FORMAT_DEFAULT));
2461}
2462
2463TEST_P(AudioPolicyManagerTestDeviceConnection, ExplicitlyRoutingAfterConnection) {
2464 const audio_devices_t type = std::get<0>(GetParam());
2465 const std::string name = std::get<1>(GetParam());
2466 const std::string address = std::get<2>(GetParam());
2467
2468 // Connect device to do explicitly routing test
2469 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2470 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2471 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2472
jiabin19cdba52020-11-24 11:28:58 -08002473 audio_port_v7 devicePort;
jiabin43848a52019-09-05 14:07:25 -07002474 const audio_port_role_t role = audio_is_output_device(type)
2475 ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002476 ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
jiabin43848a52019-09-05 14:07:25 -07002477
2478 audio_port_handle_t routedPortId = devicePort.id;
jiabin43848a52019-09-05 14:07:25 -07002479 // Try start input or output according to the device type
2480 if (audio_is_output_devices(type)) {
2481 getOutputForAttr(&routedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002482 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002483 } else if (audio_is_input_device(type)) {
2484 RecordingActivityTracker tracker;
François Gaffie6ebbce02023-07-19 13:27:53 +02002485 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2486 getInputForAttr({}, &input, AUDIO_SESSION_NONE, tracker.getRiid(), &routedPortId,
2487 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate,
2488 AUDIO_INPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002489 }
2490 ASSERT_EQ(devicePort.id, routedPortId);
2491
2492 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2493 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2494 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2495}
2496
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002497android::media::audio::common::ExtraAudioDescriptor make_ExtraAudioDescriptor(
2498 android::media::audio::common::AudioStandard audioStandard,
2499 android::media::audio::common::AudioEncapsulationType audioEncapsulationType) {
2500 android::media::audio::common::ExtraAudioDescriptor result;
2501 result.standard = audioStandard;
2502 result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
2503 result.encapsulationType = audioEncapsulationType;
2504 return result;
2505}
2506
2507TEST_P(AudioPolicyManagerTestDeviceConnection, PassingExtraAudioDescriptors) {
2508 const audio_devices_t type = std::get<0>(GetParam());
2509 if (!audio_device_is_digital(type)) {
2510 // EADs are used only for HDMI devices.
2511 GTEST_SKIP() << "Not a digital device type: " << audio_device_to_string(type);
2512 }
2513 const std::string name = std::get<1>(GetParam());
2514 const std::string address = std::get<2>(GetParam());
Atneya Nair638a6e42022-12-18 16:45:15 -08002515 android::media::AudioPortFw audioPort;
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002516 ASSERT_EQ(NO_ERROR,
2517 mManager->deviceToAudioPort(type, address.c_str(), name.c_str(), &audioPort));
2518 android::media::audio::common::AudioPort& port = audioPort.hal;
2519 port.extraAudioDescriptors.push_back(make_ExtraAudioDescriptor(
2520 android::media::audio::common::AudioStandard::EDID,
2521 android::media::audio::common::AudioEncapsulationType::IEC61937));
2522 const size_t lastConnectedDevicePortCount = mClient->getConnectedDevicePortCount();
2523 const size_t lastDisconnectedDevicePortCount = mClient->getDisconnectedDevicePortCount();
2524 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2525 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, port, AUDIO_FORMAT_DEFAULT));
2526 EXPECT_EQ(lastConnectedDevicePortCount + 1, mClient->getConnectedDevicePortCount());
2527 EXPECT_EQ(lastDisconnectedDevicePortCount, mClient->getDisconnectedDevicePortCount());
2528 const audio_port_v7* devicePort = mClient->getLastConnectedDevicePort();
2529 EXPECT_EQ(port.extraAudioDescriptors.size(), devicePort->num_extra_audio_descriptors);
2530 EXPECT_EQ(AUDIO_STANDARD_EDID, devicePort->extra_audio_descriptors[0].standard);
2531 EXPECT_EQ(AUDIO_ENCAPSULATION_TYPE_IEC61937,
2532 devicePort->extra_audio_descriptors[0].encapsulation_type);
2533 EXPECT_NE(0, devicePort->extra_audio_descriptors[0].descriptor[0]);
2534}
2535
jiabin43848a52019-09-05 14:07:25 -07002536INSTANTIATE_TEST_CASE_P(
2537 DeviceConnectionState,
2538 AudioPolicyManagerTestDeviceConnection,
2539 testing::Values(
2540 DeviceConnectionTestParams({AUDIO_DEVICE_IN_HDMI, "test_in_hdmi",
2541 "audio_policy_test_in_hdmi"}),
2542 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_HDMI, "test_out_hdmi",
2543 "audio_policy_test_out_hdmi"}),
2544 DeviceConnectionTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "bt_hfp_in",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002545 "00:11:22:33:44:55"}),
jiabin43848a52019-09-05 14:07:25 -07002546 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "bt_hfp_out",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002547 "00:11:22:33:44:55"})
jiabin43848a52019-09-05 14:07:25 -07002548 )
2549 );
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07002550
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002551namespace {
2552
2553class AudioPolicyManagerTestClientOpenFails : public AudioPolicyManagerTestClient {
2554 public:
2555 status_t openOutput(audio_module_handle_t module,
2556 audio_io_handle_t *output,
2557 audio_config_t * halConfig,
2558 audio_config_base_t * mixerConfig,
2559 const sp<DeviceDescriptorBase>& device,
2560 uint32_t * latencyMs,
Dean Wheatleydfb67b82024-01-23 09:36:29 +11002561 audio_output_flags_t *flags,
Haofan Wangf6e304f2024-07-09 23:06:58 -07002562 audio_attributes_t attributes) override {
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002563 return mSimulateFailure ? BAD_VALUE :
2564 AudioPolicyManagerTestClient::openOutput(
Haofan Wangf6e304f2024-07-09 23:06:58 -07002565 module, output, halConfig, mixerConfig, device, latencyMs, flags,
2566 attributes);
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002567 }
2568
2569 status_t openInput(audio_module_handle_t module,
2570 audio_io_handle_t *input,
2571 audio_config_t * config,
2572 audio_devices_t * device,
2573 const String8 & address,
2574 audio_source_t source,
2575 audio_input_flags_t flags) override {
2576 return mSimulateFailure ? BAD_VALUE :
2577 AudioPolicyManagerTestClient::openInput(
2578 module, input, config, device, address, source, flags);
2579 }
2580
2581 void setSimulateFailure(bool simulateFailure) { mSimulateFailure = simulateFailure; }
2582
Ping Tsai2a5a5242024-08-16 13:39:10 +08002583 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2584 if (status != NO_ERROR) {
2585 // simulate device connect status
2586 mSimulateBroadcastDeviceStatus[device] = status;
2587 } else {
2588 // remove device connection fixed status
2589 mSimulateBroadcastDeviceStatus.erase(device);
2590 }
2591 }
2592
2593 status_t setDeviceConnectedState(const struct audio_port_v7* port,
2594 media::DeviceConnectedState state) override {
2595 if (mSimulateBroadcastDeviceStatus.find(port->ext.device.type) !=
2596 mSimulateBroadcastDeviceStatus.end()) {
2597 // If a simulated status exists, return a status value
2598 return mSimulateBroadcastDeviceStatus[port->ext.device.type];
2599 }
2600 return AudioPolicyManagerTestClient::setDeviceConnectedState(port, state);
2601 }
2602
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002603 private:
2604 bool mSimulateFailure = false;
Ping Tsai2a5a5242024-08-16 13:39:10 +08002605 std::map<audio_devices_t, status_t> mSimulateBroadcastDeviceStatus;
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002606};
2607
2608} // namespace
2609
2610using DeviceConnectionWithFormatTestParams =
2611 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/,
2612 audio_format_t /*format*/>;
2613
2614class AudioPolicyManagerTestDeviceConnectionFailed :
2615 public AudioPolicyManagerTestWithConfigurationFile,
2616 public testing::WithParamInterface<DeviceConnectionWithFormatTestParams> {
2617 protected:
2618 std::string getConfigFile() override { return sBluetoothConfig; }
2619 AudioPolicyManagerTestClient* getClient() override {
2620 mFullClient = new AudioPolicyManagerTestClientOpenFails;
2621 return mFullClient;
2622 }
2623 void setSimulateOpenFailure(bool simulateFailure) {
2624 mFullClient->setSimulateFailure(simulateFailure); }
2625
Ping Tsai2a5a5242024-08-16 13:39:10 +08002626 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2627 mFullClient->setSimulateBroadcastDeviceStatus(device, status); }
2628
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002629 static const std::string sBluetoothConfig;
2630
2631 private:
2632 AudioPolicyManagerTestClientOpenFails* mFullClient;
2633};
2634
2635const std::string AudioPolicyManagerTestDeviceConnectionFailed::sBluetoothConfig =
2636 AudioPolicyManagerTestDeviceConnectionFailed::sExecutableDir +
2637 "test_audio_policy_configuration_bluetooth.xml";
2638
2639TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, SetDeviceConnectedStateHasAddress) {
2640 const audio_devices_t type = std::get<0>(GetParam());
2641 const std::string name = std::get<1>(GetParam());
2642 const std::string address = std::get<2>(GetParam());
2643 const audio_format_t format = std::get<3>(GetParam());
2644
2645 EXPECT_EQ(0, mClient->getConnectedDevicePortCount());
2646 EXPECT_EQ(0, mClient->getDisconnectedDevicePortCount());
2647
2648 setSimulateOpenFailure(true);
2649 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2650 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2651 address.c_str(), name.c_str(), format));
2652
2653 // Since the failure happens when opening input/output, the device must be connected
2654 // first and then disconnected.
2655 EXPECT_EQ(1, mClient->getConnectedDevicePortCount());
2656 EXPECT_EQ(1, mClient->getDisconnectedDevicePortCount());
2657
2658 if (mClient->getConnectedDevicePortCount() > 0) {
2659 auto port = mClient->getLastConnectedDevicePort();
2660 EXPECT_EQ(type, port->ext.device.type);
2661 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2662 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2663 }
2664 if (mClient->getDisconnectedDevicePortCount() > 0) {
2665 auto port = mClient->getLastDisconnectedDevicePort();
2666 EXPECT_EQ(type, port->ext.device.type);
2667 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2668 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2669 }
2670}
2671
Ping Tsai2a5a5242024-08-16 13:39:10 +08002672TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, BroadcastDeviceFailure) {
2673 const audio_devices_t type = std::get<0>(GetParam());
2674 const std::string name = std::get<1>(GetParam());
2675 const std::string address = std::get<2>(GetParam());
2676 const audio_format_t format = std::get<3>(GetParam());
2677
2678 // simulate broadcastDeviceConnectionState return failure
2679 setSimulateBroadcastDeviceStatus(type, INVALID_OPERATION);
2680 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2681 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2682 address.c_str(), name.c_str(), format));
2683
2684 // if broadcast is fail, device should not be added to available devices list
2685 if (audio_is_output_device(type)) {
2686 auto availableDevices = mManager->getAvailableOutputDevices();
2687 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2688 } else if (audio_is_input_device(type)) {
2689 auto availableDevices = mManager->getAvailableInputDevices();
2690 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2691 }
2692
2693 setSimulateBroadcastDeviceStatus(type, NO_ERROR);
2694}
2695
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002696INSTANTIATE_TEST_CASE_P(
2697 DeviceConnectionFailure,
2698 AudioPolicyManagerTestDeviceConnectionFailed,
2699 testing::Values(
2700 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
2701 "bt_hfp_in", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2702 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO,
2703 "bt_hfp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2704 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2705 "bt_a2dp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2706 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2707 "bt_a2dp_out", "00:11:22:33:44:66", AUDIO_FORMAT_LDAC})
2708 )
2709 );
2710
Dean Wheatleyd082f472022-02-04 11:10:48 +11002711class AudioPolicyManagerCarTest : public AudioPolicyManagerTestDynamicPolicy {
2712protected:
2713 std::string getConfigFile() override { return sCarConfig; }
2714
2715 static const std::string sCarConfig;
Oscar Azucena873d10f2023-01-12 18:34:42 -08002716 static const std::string sCarBusMediaOutput;
2717 static const std::string sCarBusNavigationOutput;
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002718 static const std::string sCarRearZoneOneOutput;
2719 static const std::string sCarRearZoneTwoOutput;
jiabin24ff57a2023-11-27 21:06:51 +00002720 static const std::string sCarBusMmapOutput;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002721};
2722
2723const std::string AudioPolicyManagerCarTest::sCarConfig =
2724 AudioPolicyManagerCarTest::sExecutableDir + "test_car_ap_atmos_offload_configuration.xml";
2725
Oscar Azucena873d10f2023-01-12 18:34:42 -08002726const std::string AudioPolicyManagerCarTest::sCarBusMediaOutput = "bus0_media_out";
2727
2728const std::string AudioPolicyManagerCarTest::sCarBusNavigationOutput = "bus1_navigation_out";
2729
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002730const std::string AudioPolicyManagerCarTest::sCarRearZoneOneOutput = "bus100_audio_zone_1";
2731
2732const std::string AudioPolicyManagerCarTest::sCarRearZoneTwoOutput = "bus200_audio_zone_2";
2733
jiabin24ff57a2023-11-27 21:06:51 +00002734const std::string AudioPolicyManagerCarTest::sCarBusMmapOutput = "bus8_mmap_out";
2735
Dean Wheatleyd082f472022-02-04 11:10:48 +11002736TEST_F(AudioPolicyManagerCarTest, InitSuccess) {
2737 // SetUp must finish with no assertions.
2738}
2739
2740TEST_F(AudioPolicyManagerCarTest, Dump) {
2741 dumpToLog();
2742}
2743
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002744TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAtmosOutputAfterRegisteringPolicyMix) {
Dean Wheatleyd082f472022-02-04 11:10:48 +11002745 status_t ret;
2746 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002747 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Oscar Azucena873d10f2023-01-12 18:34:42 -08002748 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig);
Dean Wheatleyd082f472022-02-04 11:10:48 +11002749 ASSERT_EQ(NO_ERROR, ret);
2750
2751 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2752 audio_io_handle_t output;
2753 audio_port_handle_t portId;
2754 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_E_AC3_JOC, AUDIO_CHANNEL_OUT_5POINT1,
2755 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2756 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2757 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
2758 ASSERT_NE(nullptr, outDesc.get());
2759 ASSERT_EQ(AUDIO_FORMAT_E_AC3_JOC, outDesc->getFormat());
2760 ASSERT_EQ(AUDIO_CHANNEL_OUT_5POINT1, outDesc->getChannelMask());
2761 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002762
2763 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2764 output = AUDIO_IO_HANDLE_NONE;
2765 portId = AUDIO_PORT_HANDLE_NONE;
2766 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
2767 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2768 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2769 outDesc = mManager->getOutputs().valueFor(output);
2770 ASSERT_NE(nullptr, outDesc.get());
2771 ASSERT_EQ(AUDIO_FORMAT_PCM_16_BIT, outDesc->getFormat());
2772 ASSERT_EQ(AUDIO_CHANNEL_OUT_7POINT1POINT4, outDesc->getChannelMask());
2773 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyd082f472022-02-04 11:10:48 +11002774}
2775
Oscar Azucena873d10f2023-01-12 18:34:42 -08002776TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAfterRegisteringPolicyMix) {
2777 status_t ret;
2778 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2779 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2780 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2781 audioConfig.sample_rate = k48000SamplingRate;
2782 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2783 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2784 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2785 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2786 ASSERT_EQ(NO_ERROR, ret);
2787 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2788 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2789 /*exclude=*/ false)};
2790 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2791 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2792 ASSERT_EQ(NO_ERROR, ret);
2793 audio_port_v7 mediaDevicePort;
2794 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2795 sCarBusMediaOutput, &mediaDevicePort));
2796 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2797 audio_io_handle_t output;
2798 audio_port_handle_t portId;
2799 const audio_attributes_t mediaAttribute = {
2800 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2801 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2802
2803 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2804 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2805
2806 ASSERT_EQ(mediaDevicePort.id, selectedDeviceId);
2807}
2808
2809TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterRegisteringPolicyMix) {
2810 status_t ret;
2811 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2812 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2813 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2814 audioConfig.sample_rate = k48000SamplingRate;
2815 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2816 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2817 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2818 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2819 ASSERT_EQ(NO_ERROR, ret);
2820 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2821 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2822 /*exclude=*/ false)};
2823 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2824 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2825 ASSERT_EQ(NO_ERROR, ret);
2826 audio_port_v7 navDevicePort;
2827 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2828 sCarBusNavigationOutput, &navDevicePort));
2829 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2830 audio_io_handle_t output;
2831 audio_port_handle_t portId;
2832 const audio_attributes_t mediaAttribute = {
2833 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2834 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2835
2836 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2837 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2838
2839 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2840}
2841
2842TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterUserAffinities) {
2843 status_t ret;
2844 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2845 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2846 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2847 audioConfig.sample_rate = k48000SamplingRate;
2848 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2849 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2850 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2851 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2852 ASSERT_EQ(NO_ERROR, ret);
2853 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2854 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2855 /*exclude=*/ false)};
2856 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2857 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2858 ASSERT_EQ(NO_ERROR, ret);
2859 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2860 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002861 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002862 audio_port_v7 navDevicePort;
2863 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2864 sCarBusNavigationOutput, &navDevicePort));
2865 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2866 audio_io_handle_t output;
2867 audio_port_handle_t portId;
2868 const audio_attributes_t mediaAttribute = {
2869 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2870 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2871
2872 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2873 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2874
2875 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2876}
2877
2878TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithExcludeUserIdCriteria) {
2879 status_t ret;
2880 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2881 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2882 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2883 audioConfig.sample_rate = k48000SamplingRate;
2884 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2885 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2886 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2887 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2888 ASSERT_EQ(NO_ERROR, ret);
2889 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2890 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2891 /*exclude=*/ false),
2892 createUserIdCriterion(/* userId */ 0, /* exclude */ true)};
2893 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2894 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2895 ASSERT_EQ(NO_ERROR, ret);
2896 audio_port_v7 navDevicePort;
2897 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2898 sCarBusNavigationOutput, &navDevicePort));
2899 audio_io_handle_t output;
2900 audio_port_handle_t portId;
2901 const audio_attributes_t navigationAttribute = {
2902 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2903 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2904 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2905
2906 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2907 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, navigationAttribute);
2908
2909 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2910}
2911
2912TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputExcludeUserIdCriteria) {
2913 status_t ret;
2914 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2915 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2916 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2917 audioConfig.sample_rate = k48000SamplingRate;
2918 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2919 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2920 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2921 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2922 ASSERT_EQ(NO_ERROR, ret);
2923 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2924 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2925 /*exclude=*/ false),
2926 createUserIdCriterion(0 /* userId */, /* exclude */ true)};
2927 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2928 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2929 ASSERT_EQ(NO_ERROR, ret);
2930 audio_port_v7 navDevicePort;
2931 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2932 sCarBusNavigationOutput, &navDevicePort));
2933 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2934 audio_io_handle_t output;
2935 audio_port_handle_t portId;
2936 const audio_attributes_t mediaAttribute = {
2937 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2938 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2939
2940 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2941 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2942
2943 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2944}
2945
2946TEST_F(AudioPolicyManagerCarTest,
2947 GetOutputForAttrWithMatchingMixAndSelectedOutputAfterUserAffinities) {
2948 status_t ret;
2949 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2950 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2951 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2952 audioConfig.sample_rate = k48000SamplingRate;
2953 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2954 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2955 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2956 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2957 ASSERT_EQ(NO_ERROR, ret);
2958 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2959 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2960 /*exclude=*/ false)};
2961 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2962 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2963 ASSERT_EQ(NO_ERROR, ret);
2964 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2965 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
2966 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002967 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002968 audio_port_v7 navDevicePort;
2969 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2970 sCarBusNavigationOutput, &navDevicePort));
2971 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2972 audio_io_handle_t output;
2973 audio_port_handle_t portId;
2974 const audio_attributes_t mediaAttribute = {
2975 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2976 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2977
2978 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2979 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2980
2981 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2982}
2983
2984TEST_F(AudioPolicyManagerCarTest,
2985 GetOutputForAttrWithNoMatchingMaxAndSelectedOutputAfterUserAffinities) {
2986 status_t ret;
2987 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2988 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2989 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2990 audioConfig.sample_rate = k48000SamplingRate;
2991 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2992 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2993 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2994 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2995 ASSERT_EQ(NO_ERROR, ret);
2996 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2997 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2998 /*exclude=*/ false)};
2999 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3000 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
3001 ASSERT_EQ(NO_ERROR, ret);
3002 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3003 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
3004 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003005 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08003006 audio_port_v7 navDevicePort;
3007 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3008 sCarBusNavigationOutput, &navDevicePort));
3009 audio_port_handle_t selectedDeviceId = navDevicePort.id;
3010 audio_io_handle_t output;
3011 audio_port_handle_t portId;
3012 const audio_attributes_t alarmAttribute = {
3013 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3014 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3015
3016 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3017 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3018
3019 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3020}
3021
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003022TEST_F(AudioPolicyManagerCarTest,
3023 GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
3024 status_t ret;
3025 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3026 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3027 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3028 audioConfig.sample_rate = k48000SamplingRate;
3029 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3030 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3031 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3032 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3033 ASSERT_EQ(NO_ERROR, ret);
3034 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3035 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3036 ASSERT_EQ(NO_ERROR, ret);
3037 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3038 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3039 ASSERT_EQ(NO_ERROR, ret);
3040 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3041 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3042 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3043 audio_port_v7 primaryZoneDevicePort;
3044 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3045 sCarBusMediaOutput, &primaryZoneDevicePort));
3046 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3047 audio_io_handle_t output;
3048 audio_port_handle_t portId;
3049 const audio_attributes_t mediaAttribute = {
3050 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3051 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3052 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3053
3054 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3055 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3056 AUDIO_SESSION_NONE, user11AppUid);
3057
3058 ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceId);
3059}
3060
3061TEST_F(AudioPolicyManagerCarTest,
3062 GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
3063 status_t ret;
3064 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3065 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3066 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3067 audioConfig.sample_rate = k48000SamplingRate;
3068 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3069 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3070 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3071 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3072 ASSERT_EQ(NO_ERROR, ret);
3073 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3074 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3075 ASSERT_EQ(NO_ERROR, ret);
3076 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3077 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3078 ASSERT_EQ(NO_ERROR, ret);
3079 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3080 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3081 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3082 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3083 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3084 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3085 audio_port_v7 secondaryZoneDevicePort;
3086 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3087 sCarRearZoneOneOutput, &secondaryZoneDevicePort));
3088 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3089 audio_io_handle_t output;
3090 audio_port_handle_t portId;
3091 const audio_attributes_t mediaAttribute = {
3092 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3093 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3094 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3095
3096 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3097 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3098 AUDIO_SESSION_NONE, user11AppUid);
3099
3100 ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceId);
3101}
3102
3103TEST_F(AudioPolicyManagerCarTest,
3104 GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
3105 status_t ret;
3106 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3107 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3108 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3109 audioConfig.sample_rate = k48000SamplingRate;
3110 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3111 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3112 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3113 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3114 ASSERT_EQ(NO_ERROR, ret);
3115 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3116 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3117 ASSERT_EQ(NO_ERROR, ret);
3118 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3119 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3120 ASSERT_EQ(NO_ERROR, ret);
3121 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3122 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3123 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3124 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3125 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3126 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3127 const AudioDeviceTypeAddr tertiaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput);
3128 const AudioDeviceTypeAddrVector tertiaryZoneDevices = {tertiaryOutputDevice};
3129 mManager->setUserIdDeviceAffinities(/* userId */ 15, tertiaryZoneDevices);
3130 audio_port_v7 tertiaryZoneDevicePort;
3131 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3132 sCarRearZoneTwoOutput, &tertiaryZoneDevicePort));
3133 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3134 audio_io_handle_t output;
3135 audio_port_handle_t portId;
3136 const audio_attributes_t mediaAttribute = {
3137 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3138 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3139 uid_t user15AppUid = multiuser_get_uid(/* user_id */ 15, /* app_id */ 12345);
3140
3141 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3142 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3143 AUDIO_SESSION_NONE, user15AppUid);
3144
3145 ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceId);
3146}
3147
Oscar Azucena873d10f2023-01-12 18:34:42 -08003148TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithNoMatchingMix) {
3149 status_t ret;
3150 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3151 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3152 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3153 audioConfig.sample_rate = k48000SamplingRate;
3154 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3155 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3156 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3157 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3158 ASSERT_EQ(NO_ERROR, ret);
3159 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
3160 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
3161 /*exclude=*/ false)};
3162 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3163 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
3164 ASSERT_EQ(NO_ERROR, ret);
3165 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3166 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
3167 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003168 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08003169 audio_port_v7 navDevicePort;
3170 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3171 sCarBusNavigationOutput, &navDevicePort));
3172 audio_port_handle_t selectedDeviceId = navDevicePort.id;
3173 audio_io_handle_t output;
3174 audio_port_handle_t portId;
3175 const audio_attributes_t alarmAttribute = {
3176 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3177 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3178
3179 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3180 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3181
3182 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3183}
3184
jiabin24ff57a2023-11-27 21:06:51 +00003185TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrForMMapWithPolicyMatched) {
3186 status_t ret;
3187 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3188 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3189 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3190 audioConfig.sample_rate = k48000SamplingRate;
3191 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3192 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3193 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3194 AUDIO_DEVICE_OUT_BUS, sCarBusMmapOutput, audioConfig, mediaMatchCriteria);
3195 ASSERT_EQ(NO_ERROR, ret);
3196 ASSERT_EQ(NO_ERROR, ret);
3197 audio_port_v7 mmapDevicePort;
3198 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3199 sCarBusMmapOutput, &mmapDevicePort));
3200 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3201 audio_io_handle_t output;
3202 audio_port_handle_t portId;
3203 const audio_attributes_t mediaAttribute = {
3204 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3205 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3206
3207 getOutputForAttr(
3208 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3209 k48000SamplingRate,
3210 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT),
3211 &output, &portId, mediaAttribute);
3212
3213 ASSERT_EQ(mmapDevicePort.id, selectedDeviceId);
3214}
3215
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003216class AudioPolicyManagerTVTest : public AudioPolicyManagerTestWithConfigurationFile {
3217protected:
3218 std::string getConfigFile() override { return sTvConfig; }
3219 void testHDMIPortSelection(audio_output_flags_t flags, const char* expectedMixPortName);
3220
3221 static const std::string sTvConfig;
3222};
3223
3224const std::string AudioPolicyManagerTVTest::sTvConfig =
3225 AudioPolicyManagerTVTest::sExecutableDir + "test_tv_apm_configuration.xml";
3226
3227// SwAudioOutputDescriptor doesn't populate flags so check against the port name.
3228void AudioPolicyManagerTVTest::testHDMIPortSelection(
3229 audio_output_flags_t flags, const char* expectedMixPortName) {
3230 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3231 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3232 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3233 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3234 audio_io_handle_t output;
3235 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +11003236 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3237 k48000SamplingRate, flags, &output, &portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003238 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3239 ASSERT_NE(nullptr, outDesc.get());
jiabin19cdba52020-11-24 11:28:58 -08003240 audio_port_v7 port = {};
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003241 outDesc->toAudioPort(&port);
3242 mManager->releaseOutput(portId);
3243 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3244 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3245 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3246 ASSERT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3247 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3248 ASSERT_STREQ(expectedMixPortName, port.name);
3249}
3250
3251TEST_F(AudioPolicyManagerTVTest, InitSuccess) {
3252 // SetUp must finish with no assertions.
3253}
3254
3255TEST_F(AudioPolicyManagerTVTest, Dump) {
3256 dumpToLog();
3257}
3258
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003259TEST_F(AudioPolicyManagerTVTest, MatchNoFlags) {
3260 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_NONE, "primary output");
3261}
3262
3263TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectNoHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003264 // b/140447125: The selected port must not have HW AV Sync flag (see the config file).
3265 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_DIRECT, "direct");
3266}
3267
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003268TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003269 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3270 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
3271 "tunnel");
3272}
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003273
3274TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectMMapNoIrq) {
3275 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3276 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3277 "low latency");
3278}
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003279
Mikhail Naganov806170e2024-09-05 17:26:50 -07003280class AudioPolicyManagerPhoneTest : public AudioPolicyManagerTestWithConfigurationFile {
3281protected:
3282 std::string getConfigFile() override { return sPhoneConfig; }
3283 void testOutputMixPortSelectionForAttr(audio_output_flags_t flags, audio_format_t format,
3284 int samplingRate, bool isMusic, const char* expectedMixPortName);
3285 void testOutputMixPortSelectionForStream(
3286 audio_stream_type_t stream, const char* expectedMixPortName);
3287 void verifyMixPortNameAndFlags(audio_io_handle_t output, const char* expectedMixPortName);
3288
3289 static const std::string sPhoneConfig;
3290 static const std::map<std::string, audio_output_flags_t> sMixPortFlags;
3291};
3292
3293const std::string AudioPolicyManagerPhoneTest::sPhoneConfig =
3294 AudioPolicyManagerPhoneTest::sExecutableDir + "test_phone_apm_configuration.xml";
3295
3296// Must be in sync with the contents of the sPhoneConfig file.
3297const std::map<std::string, audio_output_flags_t> AudioPolicyManagerPhoneTest::sMixPortFlags = {
3298 {"primary output",
3299 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_FAST)},
3300 {"direct", AUDIO_OUTPUT_FLAG_DIRECT},
3301 {"deep buffer", AUDIO_OUTPUT_FLAG_DEEP_BUFFER},
3302 {"compressed_offload",
3303 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3304 AUDIO_OUTPUT_FLAG_NON_BLOCKING |
3305 AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD)},
3306 {"raw", (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_FAST)},
3307 {"mmap_no_irq_out",
3308 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)},
3309 {"voip_rx", AUDIO_OUTPUT_FLAG_VOIP_RX},
3310};
3311
3312void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForAttr(
3313 audio_output_flags_t flags, audio_format_t format, int samplingRate, bool isMusic,
3314 const char* expectedMixPortName) {
3315 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3316 audio_io_handle_t output;
3317 audio_port_handle_t portId;
3318 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3319 if (isMusic) {
3320 attr.content_type = AUDIO_CONTENT_TYPE_MUSIC;
3321 attr.usage = AUDIO_USAGE_MEDIA;
3322 }
3323 getOutputForAttr(&selectedDeviceId, format, AUDIO_CHANNEL_OUT_STEREO, samplingRate, flags,
3324 &output, &portId, attr);
3325 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3326 mManager->releaseOutput(portId);
3327}
3328
3329void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForStream(
3330 audio_stream_type_t stream, const char* expectedMixPortName) {
3331 audio_io_handle_t output = mManager->getOutput(stream);
3332 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3333}
3334
3335void AudioPolicyManagerPhoneTest::verifyMixPortNameAndFlags(audio_io_handle_t output,
3336 const char* expectedMixPortName) {
3337 ALOGI("%s: checking output %d", __func__, output);
3338 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3339 ASSERT_NE(nullptr, outDesc.get());
3340 audio_port_v7 port = {};
3341 outDesc->toAudioPort(&port);
3342 EXPECT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3343 EXPECT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3344 ASSERT_STREQ(expectedMixPortName, port.name);
3345
3346 auto iter = sMixPortFlags.find(port.name);
3347 ASSERT_NE(iter, sMixPortFlags.end()) << "\"" << port.name << "\" is not in sMixPortFlags";
3348 auto actualFlags = mClient->getOpenOutputFlags(output);
3349 ASSERT_TRUE(actualFlags.has_value()) << "\"" << port.name << "\" was not opened via client";
3350 EXPECT_EQ(*actualFlags, iter->second);
3351}
3352
3353TEST_F(AudioPolicyManagerPhoneTest, InitSuccess) {
3354 // SetUp must finish with no assertions.
3355}
3356
3357enum {
3358 MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER,
3359 MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3360 MIX_PORT_ATTR_FLAGS_PARAMETER,
3361 MIX_PORT_ATTR_FORMAT_PARAMETER,
3362 MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER,
3363};
3364using MixPortSelectionForAttr =
3365 std::tuple<const char*, const char*, audio_output_flags_t, audio_format_t, int>;
3366
3367class AudioPolicyManagerOutputMixPortForAttrSelectionTest
3368 : public AudioPolicyManagerPhoneTest,
3369 public testing::WithParamInterface<MixPortSelectionForAttr> {
3370};
3371
3372// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3373// Instead, just run the same selection twice while altering the deep buffer for media setting.
3374TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags) {
3375 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3376 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3377 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3378 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3379 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3380 false /*isMusic*/,
3381 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3382}
3383TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_Music) {
3384 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3385 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3386 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3387 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3388 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3389 true /*isMusic*/,
3390 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3391}
3392TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia) {
3393 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3394 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3395 ASSERT_NO_FATAL_FAILURE(
3396 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3397 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3398 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3399 false /*isMusic*/,
3400 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3401 GetParam()) ?: fallbackName));
3402}
3403TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia_Music) {
3404 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3405 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3406 ASSERT_NO_FATAL_FAILURE(
3407 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3408 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3409 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3410 true /*isMusic*/,
3411 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3412 GetParam()) ?: fallbackName));
3413}
3414
3415INSTANTIATE_TEST_CASE_P(AudioPolicyManagerOutputMixPortForAttrSelection,
3416 AudioPolicyManagerOutputMixPortForAttrSelectionTest,
3417 ::testing::Values(
3418 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3419 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3420 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3421 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3422 // Note: this goes to "direct" because 384000 > SAMPLE_RATE_HZ_MAX (192000)
3423 std::make_tuple("direct", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3424 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3425 std::make_tuple("primary output", nullptr, AUDIO_OUTPUT_FLAG_FAST,
3426 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3427 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3428 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k96000SamplingRate),
3429 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3430 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3431 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3432 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3433 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3434 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3435 std::make_tuple("compressed_offload", nullptr,
3436 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3437 AUDIO_OUTPUT_FLAG_NON_BLOCKING),
3438 AUDIO_FORMAT_MP3, AudioPolicyManagerTest::k48000SamplingRate),
3439 std::make_tuple("raw", nullptr,
3440 AUDIO_OUTPUT_FLAG_RAW, AUDIO_FORMAT_PCM_32_BIT,
3441 AudioPolicyManagerTest::k48000SamplingRate),
3442 std::make_tuple("mmap_no_irq_out", nullptr,
3443 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3444 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3445 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3446 std::make_tuple("mmap_no_irq_out", nullptr,
3447 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3448 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3449 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3450 std::make_tuple("voip_rx", nullptr, AUDIO_OUTPUT_FLAG_VOIP_RX,
3451 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate)),
3452 [](const ::testing::TestParamInfo<MixPortSelectionForAttr>& info) {
3453 static const std::string flagPrefix = "AUDIO_OUTPUT_FLAG_";
3454 static const std::string formatPrefix = "AUDIO_FORMAT_";
3455 std::string flags;
3456 TypeConverter<OutputFlagTraits>::maskToString(
3457 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(info.param), flags, "__");
3458 size_t index = 0;
3459 while (true) {
3460 index = flags.rfind(flagPrefix);
3461 if (index == std::string::npos) break;
3462 flags.erase(index, flagPrefix.length());
3463 }
3464 std::string format;
3465 TypeConverter<FormatTraits>::toString(
3466 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(info.param), format);
3467 if (size_t index = format.find(formatPrefix); index != std::string::npos) {
3468 format.erase(index, formatPrefix.length());
3469 }
3470 return flags + "__" + format + "__" +
3471 std::to_string(std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(info.param));
3472 }
3473);
3474
3475
3476enum {
3477 MIX_PORT_STRM_EXPECTED_NAME_PARAMETER,
3478 MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3479 MIX_PORT_STRM_STREAM_PARAMETER,
3480};
3481using MixPortSelectionForStream =
3482 std::tuple<const char*, const char*, audio_stream_type_t>;
3483
3484class AudioPolicyManagerOutputMixPortForStreamSelectionTest
3485 : public AudioPolicyManagerPhoneTest,
3486 public testing::WithParamInterface<MixPortSelectionForStream> {
3487};
3488
3489// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3490// Instead, just run the same selection twice while altering the deep buffer for media setting.
3491TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_NoDBFM) {
3492 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3493 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3494 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3495 std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam())));
3496}
3497TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_WithDBFM) {
3498 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3499 const char* fallbackName = std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam());
3500 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3501 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3502 std::get<MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3503 GetParam()) ?: fallbackName));
3504}
3505
3506INSTANTIATE_TEST_CASE_P(
3507 AudioPolicyManagerOutputMixPortForStreamSelection,
3508 AudioPolicyManagerOutputMixPortForStreamSelectionTest,
3509 ::testing::Values(std::make_tuple("primary output", nullptr, AUDIO_STREAM_DEFAULT),
3510 std::make_tuple("primary output", nullptr, AUDIO_STREAM_SYSTEM),
3511 std::make_tuple("primary output", nullptr, AUDIO_STREAM_RING),
3512 std::make_tuple("primary output", "deep buffer", AUDIO_STREAM_MUSIC),
3513 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ALARM),
3514 std::make_tuple("primary output", nullptr, AUDIO_STREAM_NOTIFICATION),
3515 std::make_tuple("primary output", nullptr, AUDIO_STREAM_BLUETOOTH_SCO),
3516 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ENFORCED_AUDIBLE),
3517 std::make_tuple("primary output", nullptr, AUDIO_STREAM_DTMF),
3518 std::make_tuple("primary output", nullptr, AUDIO_STREAM_TTS),
3519 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ACCESSIBILITY),
3520 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ASSISTANT)),
3521 [](const ::testing::TestParamInfo<MixPortSelectionForStream>& info) {
3522 static const std::string streamPrefix = "AUDIO_STREAM_";
3523 std::string stream;
3524 TypeConverter<StreamTraits>::toString(
3525 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(info.param), stream);
3526 if (size_t index = stream.find(streamPrefix); index != std::string::npos) {
3527 stream.erase(index, streamPrefix.length());
3528 }
3529 return stream;
3530 }
3531);
3532
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003533class AudioPolicyManagerDynamicHwModulesTest : public AudioPolicyManagerTestWithConfigurationFile {
3534protected:
3535 void SetUpManagerConfig() override;
3536};
3537
3538void AudioPolicyManagerDynamicHwModulesTest::SetUpManagerConfig() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07003539 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig());
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003540 // Only allow successful opening of "primary" hw module during APM initialization.
3541 mClient->swapAllowedModuleNames({"primary"});
3542}
3543
3544TEST_F(AudioPolicyManagerDynamicHwModulesTest, InitSuccess) {
3545 // SetUp must finish with no assertions.
3546}
3547
3548TEST_F(AudioPolicyManagerDynamicHwModulesTest, DynamicAddition) {
3549 const auto handleBefore = mClient->peekNextModuleHandle();
3550 mManager->onNewAudioModulesAvailable();
3551 ASSERT_EQ(handleBefore, mClient->peekNextModuleHandle());
3552 // Reset module loading restrictions.
3553 mClient->swapAllowedModuleNames();
3554 mManager->onNewAudioModulesAvailable();
3555 const auto handleAfter = mClient->peekNextModuleHandle();
3556 ASSERT_GT(handleAfter, handleBefore);
3557 mManager->onNewAudioModulesAvailable();
3558 ASSERT_EQ(handleAfter, mClient->peekNextModuleHandle());
3559}
3560
3561TEST_F(AudioPolicyManagerDynamicHwModulesTest, AddedDeviceAvailable) {
3562 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, mManager->getDeviceConnectionState(
3563 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3564 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3565 mManager->onNewAudioModulesAvailable();
3566 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE, mManager->getDeviceConnectionState(
3567 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3568}
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003569
3570TEST_F(AudioPolicyManagerDynamicHwModulesTest, ListAddedAudioPorts) {
3571 ASSERT_FALSE(
3572 findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
3573 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3574 mManager->onNewAudioModulesAvailable();
jiabin19cdba52020-11-24 11:28:58 -08003575 struct audio_port_v7 port;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003576 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
3577}
3578
3579TEST_F(AudioPolicyManagerDynamicHwModulesTest, ClientIsUpdated) {
3580 const size_t prevAudioPortListUpdateCount = mClient->getAudioPortListUpdateCount();
3581 const uint32_t prevAudioPortGeneration = mManager->getAudioPortGeneration();
3582 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3583 mManager->onNewAudioModulesAvailable();
3584 EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
3585 EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
3586}
Jiabin Huang3b98d322020-09-03 17:54:16 +00003587
3588using DevicesRoleForCapturePresetParam = std::tuple<audio_source_t, device_role_t>;
3589
3590class AudioPolicyManagerDevicesRoleForCapturePresetTest
3591 : public AudioPolicyManagerTestWithConfigurationFile,
3592 public testing::WithParamInterface<DevicesRoleForCapturePresetParam> {
3593protected:
3594 // The `inputDevice` and `inputDevice2` indicate the audio devices type to be used for setting
3595 // device role. They must be declared in the test_audio_policy_configuration.xml
3596 AudioDeviceTypeAddr inputDevice = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
3597 AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_HDMI, "");
3598};
3599
3600TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCapturePreset) {
3601 const audio_source_t audioSource = std::get<0>(GetParam());
3602 const device_role_t role = std::get<1>(GetParam());
3603
3604 // Test invalid device when setting
3605 const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
3606 const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
3607 ASSERT_EQ(BAD_VALUE,
3608 mManager->setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3609 ASSERT_EQ(BAD_VALUE,
3610 mManager->addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3611 AudioDeviceTypeAddrVector devices;
3612 ASSERT_EQ(NAME_NOT_FOUND,
3613 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3614 ASSERT_TRUE(devices.empty());
3615 ASSERT_EQ(BAD_VALUE,
3616 mManager->removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3617
3618 // Without setting, call get/remove/clear must fail
3619 ASSERT_EQ(NAME_NOT_FOUND,
3620 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3621 ASSERT_EQ(NAME_NOT_FOUND,
3622 mManager->removeDevicesRoleForCapturePreset(audioSource, role, devices));
3623 ASSERT_EQ(NAME_NOT_FOUND,
3624 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3625
3626 // Test set/get devices role
3627 const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
3628 ASSERT_EQ(NO_ERROR,
3629 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3630 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3631 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice));
3632
3633 // Test setting will change the previously set devices
3634 const AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
3635 ASSERT_EQ(NO_ERROR,
3636 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
3637 devices.clear();
3638 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3639 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3640
3641 // Test add devices
3642 ASSERT_EQ(NO_ERROR,
3643 mManager->addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3644 devices.clear();
3645 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3646 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice, inputDevice2));
3647
3648 // Test remove devices
3649 ASSERT_EQ(NO_ERROR,
3650 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3651 devices.clear();
3652 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3653 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3654
3655 // Test remove devices that are not set as the device role
3656 ASSERT_EQ(BAD_VALUE,
3657 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3658
3659 // Test clear devices
3660 ASSERT_EQ(NO_ERROR,
3661 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3662 devices.clear();
3663 ASSERT_EQ(NAME_NOT_FOUND,
3664 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3665}
3666
jiabin14662b52023-03-06 21:35:29 +00003667TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) {
3668 const audio_source_t source = AUDIO_SOURCE_MIC;
3669 const device_role_t role = DEVICE_ROLE_PREFERRED;
3670 const std::string address = "card=1;device=0";
3671 const std::string deviceName = "randomName";
3672
3673 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3674 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3675 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3676 auto availableDevices = mManager->getAvailableInputDevices();
3677 ASSERT_GT(availableDevices.size(), 1);
3678
3679 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3680 attr.source = source;
3681 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003682 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3683 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003684 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003685 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003686 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3687 ASSERT_NE(nullptr, selectedDevice);
3688
3689 sp<DeviceDescriptor> preferredDevice = nullptr;
3690 for (const auto& device : availableDevices) {
3691 if (device != selectedDevice) {
3692 preferredDevice = device;
3693 break;
3694 }
3695 }
3696 ASSERT_NE(nullptr, preferredDevice);
3697 // After setting preferred device for capture preset, the selected device for input should be
3698 // the preferred device.
3699 ASSERT_EQ(NO_ERROR,
3700 mManager->setDevicesRoleForCapturePreset(source, role,
3701 {preferredDevice->getDeviceTypeAddr()}));
3702 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003703 input = AUDIO_PORT_HANDLE_NONE;
3704 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003705 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003706 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003707 ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3708
3709 // After clearing preferred device for capture preset, the selected device for input should be
3710 // the same as original one.
3711 ASSERT_EQ(NO_ERROR,
3712 mManager->clearDevicesRoleForCapturePreset(source, role));
3713 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003714 input = AUDIO_PORT_HANDLE_NONE;
3715 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003716 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003717 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003718 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3719
3720 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3721 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3722 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3723}
3724
3725TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) {
3726 const audio_source_t source = AUDIO_SOURCE_MIC;
3727 const device_role_t role = DEVICE_ROLE_DISABLED;
3728 const std::string address = "card=1;device=0";
3729 const std::string deviceName = "randomName";
3730
3731 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3732 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3733 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3734 auto availableDevices = mManager->getAvailableInputDevices();
3735 ASSERT_GT(availableDevices.size(), 1);
3736
3737 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3738 attr.source = source;
3739 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003740 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3741 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003742 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003743 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003744 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3745 ASSERT_NE(nullptr, selectedDevice);
3746
3747 // After setting disabled device for capture preset, the disabled device must not be
3748 // selected for input.
3749 ASSERT_EQ(NO_ERROR,
3750 mManager->setDevicesRoleForCapturePreset(source, role,
3751 {selectedDevice->getDeviceTypeAddr()}));
3752 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003753 input = AUDIO_PORT_HANDLE_NONE;
3754 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
3755 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003756 AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003757 ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3758
3759 // After clearing disabled device for capture preset, the selected device for input should be
3760 // the original one.
3761 ASSERT_EQ(NO_ERROR,
3762 mManager->clearDevicesRoleForCapturePreset(source, role));
3763 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003764 input = AUDIO_PORT_HANDLE_NONE;
3765 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003766 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003767 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003768 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3769
3770 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3771 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3772 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3773}
3774
Jiabin Huang3b98d322020-09-03 17:54:16 +00003775INSTANTIATE_TEST_CASE_P(
3776 DevicesRoleForCapturePresetOperation,
3777 AudioPolicyManagerDevicesRoleForCapturePresetTest,
3778 testing::Values(
3779 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_MIC, DEVICE_ROLE_PREFERRED}),
3780 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_UPLINK,
3781 DEVICE_ROLE_PREFERRED}),
3782 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_DOWNLINK,
3783 DEVICE_ROLE_PREFERRED}),
3784 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_CALL, DEVICE_ROLE_PREFERRED}),
3785 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_CAMCORDER, DEVICE_ROLE_PREFERRED}),
3786 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_RECOGNITION,
3787 DEVICE_ROLE_PREFERRED}),
3788 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_COMMUNICATION,
3789 DEVICE_ROLE_PREFERRED}),
3790 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_REMOTE_SUBMIX,
3791 DEVICE_ROLE_PREFERRED}),
3792 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_UNPROCESSED, DEVICE_ROLE_PREFERRED}),
3793 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_PERFORMANCE,
3794 DEVICE_ROLE_PREFERRED}),
3795 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_ECHO_REFERENCE,
3796 DEVICE_ROLE_PREFERRED}),
3797 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_FM_TUNER, DEVICE_ROLE_PREFERRED}),
3798 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_HOTWORD, DEVICE_ROLE_PREFERRED})
3799 )
3800 );
François Gaffie6ebbce02023-07-19 13:27:53 +02003801
3802
3803const effect_descriptor_t TEST_EFFECT_DESC = {
3804 {0xf2a4bb20, 0x0c3c, 0x11e3, 0x8b07, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
3805 {0xff93e360, 0x0c3c, 0x11e3, 0x8a97, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
3806 EFFECT_CONTROL_API_VERSION,
3807 EFFECT_FLAG_TYPE_PRE_PROC,
3808 0,
3809 1,
3810 "APM test Effect",
3811 "The Android Open Source Project",
3812};
3813
3814class AudioPolicyManagerPreProcEffectTest : public AudioPolicyManagerTestWithConfigurationFile {
3815};
3816
3817TEST_F(AudioPolicyManagerPreProcEffectTest, DeviceDisconnectWhileClientActive) {
3818 const audio_source_t source = AUDIO_SOURCE_MIC;
3819 const std::string address = "BUS00_MIC";
3820 const std::string deviceName = "randomName";
3821 audio_port_handle_t portId;
3822 audio_devices_t type = AUDIO_DEVICE_IN_BUS;
3823
3824 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(type,
3825 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(),
3826 AUDIO_FORMAT_DEFAULT));
3827 auto availableDevices = mManager->getAvailableInputDevices();
3828 ASSERT_GT(availableDevices.size(), 1);
3829
3830 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3831 attr.source = source;
3832 audio_session_t session = TEST_SESSION_ID;
3833 audio_io_handle_t inputClientHandle = 777;
3834 int effectId = 666;
3835 audio_port_v7 devicePort;
3836 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3837
3838 audio_port_handle_t routedPortId = devicePort.id;
3839 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3840 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
3841 48000, AUDIO_INPUT_FLAG_NONE, &portId));
3842 ASSERT_EQ(devicePort.id, routedPortId);
3843 auto selectedDevice = availableDevices.getDeviceFromId(routedPortId);
3844 ASSERT_NE(nullptr, selectedDevice);
3845
3846 // Add a pre processing effect on the input client session
3847 ASSERT_EQ(NO_ERROR, mManager->registerEffect(&TEST_EFFECT_DESC, inputClientHandle,
3848 PRODUCT_STRATEGY_NONE, session, effectId));
3849
3850 ASSERT_EQ(NO_ERROR, mManager->startInput(portId));
3851
3852 // Force a device disconnection to close the input, no crash expected of APM
3853 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3854 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3855 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3856
3857 // Reconnect the device
3858 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3859 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3860 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3861
3862 inputClientHandle += 1;
3863 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3864 routedPortId = devicePort.id;
3865
3866 // Reconnect the client changing voluntarily the io, but keeping the session to get the
3867 // effect attached again
3868 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3869 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07003870 k48000SamplingRate));
François Gaffie6ebbce02023-07-19 13:27:53 +02003871
3872 // unregister effect should succeed since effect shall have been restore on the client session
3873 ASSERT_EQ(NO_ERROR, mManager->unregisterEffect(effectId));
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07003874}
jiabin220eea12024-05-17 17:55:20 +00003875
3876class AudioPolicyManagerTestBitPerfectBase : public AudioPolicyManagerTestWithConfigurationFile {
3877protected:
3878 void SetUp() override;
3879 void TearDown() override;
3880
3881 void startBitPerfectOutput();
3882 void reset();
3883 void getBitPerfectOutput(status_t expected);
3884
3885 const audio_format_t mBitPerfectFormat = AUDIO_FORMAT_PCM_16_BIT;
3886 const audio_channel_mask_t mBitPerfectChannelMask = AUDIO_CHANNEL_OUT_STEREO;
Mikhail Naganov806170e2024-09-05 17:26:50 -07003887 const uint32_t mBitPerfectSampleRate = k48000SamplingRate;
jiabin220eea12024-05-17 17:55:20 +00003888 const uid_t mUid = 1234;
3889 audio_port_handle_t mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3890
3891 audio_io_handle_t mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
3892 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3893 audio_port_handle_t mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
3894
3895 static constexpr audio_attributes_t sMediaAttr = {
3896 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
3897 .usage = AUDIO_USAGE_MEDIA,
3898 };
3899};
3900
3901void AudioPolicyManagerTestBitPerfectBase::SetUp() {
3902 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUp());
3903
3904 mClient->addSupportedFormat(mBitPerfectFormat);
3905 mClient->addSupportedChannelMask(mBitPerfectChannelMask);
3906 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3907 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3908 "", "", AUDIO_FORMAT_DEFAULT));
3909 auto devices = mManager->getAvailableOutputDevices();
3910 mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3911 for (auto device : devices) {
3912 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
3913 mUsbPortId = device->getId();
3914 break;
3915 }
3916 }
3917 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, mUsbPortId);
3918
3919 std::vector<audio_mixer_attributes_t> mixerAttributes;
3920 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(mUsbPortId, mixerAttributes));
3921 EXPECT_GT(mixerAttributes.size(), 0);
3922 size_t bitPerfectIndex = 0;
3923 for (; bitPerfectIndex < mixerAttributes.size(); ++bitPerfectIndex) {
3924 if (mixerAttributes[bitPerfectIndex].mixer_behavior == AUDIO_MIXER_BEHAVIOR_BIT_PERFECT) {
3925 break;
3926 }
3927 }
3928 EXPECT_LT(bitPerfectIndex, mixerAttributes.size());
3929 EXPECT_EQ(mBitPerfectFormat, mixerAttributes[bitPerfectIndex].config.format);
3930 EXPECT_EQ(mBitPerfectChannelMask, mixerAttributes[bitPerfectIndex].config.channel_mask);
3931 EXPECT_EQ(mBitPerfectSampleRate, mixerAttributes[bitPerfectIndex].config.sample_rate);
3932 EXPECT_EQ(NO_ERROR,
3933 mManager->setPreferredMixerAttributes(
3934 &sMediaAttr, mUsbPortId, mUid, &mixerAttributes[bitPerfectIndex]));
3935}
3936
3937void AudioPolicyManagerTestBitPerfectBase::TearDown() {
3938 EXPECT_EQ(NO_ERROR,
3939 mManager->clearPreferredMixerAttributes(&sMediaAttr, mUsbPortId, mUid));
3940 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3941 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3942 "", "", AUDIO_FORMAT_LDAC));
3943
3944 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::TearDown());
3945}
3946
3947void AudioPolicyManagerTestBitPerfectBase::startBitPerfectOutput() {
3948 reset();
3949 bool isBitPerfect;
3950
3951 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3952 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3953 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3954 status_t status = mManager->startOutput(mBitPerfectPortId);
3955 if (status == DEAD_OBJECT) {
3956 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3957 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3958 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3959 status = mManager->startOutput(mBitPerfectPortId);
3960 }
3961 EXPECT_EQ(NO_ERROR, status);
3962 EXPECT_TRUE(isBitPerfect);
3963 EXPECT_NE(AUDIO_IO_HANDLE_NONE, mBitPerfectOutput);
3964 const auto bitPerfectOutputDesc = mManager->getOutputs().valueFor(mBitPerfectOutput);
3965 EXPECT_NE(nullptr, bitPerfectOutputDesc);
3966 EXPECT_EQ(AUDIO_OUTPUT_FLAG_BIT_PERFECT,
3967 bitPerfectOutputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
3968};
3969
3970void AudioPolicyManagerTestBitPerfectBase::reset() {
3971 mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
3972 mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3973 mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
3974}
3975
3976void AudioPolicyManagerTestBitPerfectBase::getBitPerfectOutput(status_t expected) {
3977 reset();
3978 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
3979 AttributionSourceState attributionSource = createAttributionSourceState(mUid);
3980 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3981 config.sample_rate = mBitPerfectSampleRate;
3982 config.channel_mask = mBitPerfectChannelMask;
3983 config.format = mBitPerfectFormat;
3984 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_BIT_PERFECT;
3985 AudioPolicyInterface::output_type_t outputType;
3986 bool isSpatialized;
3987 bool isBitPerfect;
Andy Hung6b137d12024-08-27 22:35:17 +00003988 float volume;
Vlad Popa1e865e62024-08-15 19:11:42 -07003989 bool muted;
jiabin220eea12024-05-17 17:55:20 +00003990 EXPECT_EQ(expected,
3991 mManager->getOutputForAttr(&sMediaAttr, &mBitPerfectOutput, AUDIO_SESSION_NONE,
3992 &stream, attributionSource, &config, &flags,
3993 &mSelectedDeviceId, &mBitPerfectPortId, {}, &outputType,
Vlad Popa1e865e62024-08-15 19:11:42 -07003994 &isSpatialized, &isBitPerfect, &volume, &muted));
jiabin220eea12024-05-17 17:55:20 +00003995}
3996
3997class AudioPolicyManagerTestBitPerfect : public AudioPolicyManagerTestBitPerfectBase {
3998};
3999
4000TEST_F(AudioPolicyManagerTestBitPerfect, UseBitPerfectOutput) {
4001 const uid_t anotherUid = 5678;
4002 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4003 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4004 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
4005 bool isBitPerfect;
4006
4007 // When there is no active bit-perfect playback, the output selection will follow default
4008 // routing strategy.
4009 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
4010 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4011 AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4012 EXPECT_FALSE(isBitPerfect);
4013 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
4014 const auto outputDesc = mManager->getOutputs().valueFor(output);
4015 EXPECT_NE(nullptr, outputDesc);
4016 EXPECT_NE(AUDIO_OUTPUT_FLAG_BIT_PERFECT, outputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
4017
4018 // Start bit-perfect playback
4019 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4020
4021 // If the playback is from preferred mixer attributes owner but the request doesn't match
4022 // preferred mixer attributes, it will not be bit-perfect.
4023 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
4024 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4025 AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4026 EXPECT_FALSE(isBitPerfect);
4027 EXPECT_EQ(mBitPerfectOutput, output);
4028
4029 // When bit-perfect playback is active, all other playback will be routed to bit-perfect output.
4030 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4031 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4032 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4033 EXPECT_FALSE(isBitPerfect);
4034 EXPECT_EQ(mBitPerfectOutput, output);
4035
4036 // When bit-pefect playback is active, dtmf will also be routed to bit-perfect output.
4037 const audio_attributes_t dtmfAttr = {
4038 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
4039 .usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
4040 };
4041 audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
4042 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4043 portId = AUDIO_PORT_HANDLE_NONE;
4044 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4045 48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
4046 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4047 EXPECT_FALSE(isBitPerfect);
4048 EXPECT_EQ(mBitPerfectOutput, dtmfOutput);
4049
4050 // When configuration matches preferred mixer attributes, which is bit-perfect, but the client
4051 // is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
4052 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4053 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4054 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4055 EXPECT_FALSE(isBitPerfect);
4056 EXPECT_EQ(mBitPerfectOutput, output);
4057}
4058
4059TEST_F_WITH_FLAGS(
4060 AudioPolicyManagerTestBitPerfect,
4061 InternalMuteWhenBitPerfectCLientIsActive,
4062 REQUIRES_FLAGS_ENABLED(
4063 ACONFIG_FLAG(com::android::media::audioserver,
4064 fix_concurrent_playback_behavior_with_bit_perfect_client))
4065) {
4066 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4067
4068 // When bit-perfect playback is active, the system sound will be routed to bit-perfect output.
4069 // The system sound will be muted internally in this case. The bit-perfect client will be
4070 // played normally.
4071 const uint32_t anotherSampleRate = 44100;
4072 audio_port_handle_t systemSoundPortId = AUDIO_PORT_HANDLE_NONE;
4073 audio_io_handle_t systemSoundOutput = AUDIO_IO_HANDLE_NONE;
4074 const audio_attributes_t systemSoundAttr = {
4075 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4076 .usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION,
4077 };
4078 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4079 bool isBitPerfect;
4080 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4081 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &systemSoundOutput,
4082 &systemSoundPortId, systemSoundAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4083 EXPECT_FALSE(isBitPerfect);
4084 EXPECT_EQ(mBitPerfectOutput, systemSoundOutput);
4085 EXPECT_EQ(NO_ERROR, mManager->startOutput(systemSoundPortId));
4086 EXPECT_TRUE(mClient->getTrackInternalMute(systemSoundPortId));
4087 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4088 EXPECT_EQ(NO_ERROR, mManager->stopOutput(systemSoundPortId));
4089 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4090
4091 // When bit-perfect playback is active, the notification will be routed to bit-perfect output.
4092 // The notification sound will be played normally while the bit-perfect client will be muted
4093 // internally.
4094 audio_port_handle_t notificationPortId = AUDIO_PORT_HANDLE_NONE;
4095 audio_io_handle_t notificationOutput = AUDIO_IO_HANDLE_NONE;
4096 const audio_attributes_t notificationAttr = {
4097 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4098 .usage = AUDIO_USAGE_NOTIFICATION,
4099 };
4100 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4101 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &notificationOutput,
4102 &notificationPortId, notificationAttr, AUDIO_SESSION_NONE, mUid,
4103 &isBitPerfect);
4104 EXPECT_FALSE(isBitPerfect);
4105 EXPECT_EQ(mBitPerfectOutput, notificationOutput);
4106 EXPECT_EQ(NO_ERROR, mManager->startOutput(notificationPortId));
4107 EXPECT_FALSE(mClient->getTrackInternalMute(notificationPortId));
4108 EXPECT_TRUE(mClient->getTrackInternalMute(mBitPerfectPortId));
4109 EXPECT_EQ(NO_ERROR, mManager->stopOutput(notificationPortId));
4110 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4111
4112 EXPECT_EQ(NO_ERROR, mManager->stopOutput(mBitPerfectPortId));
4113}
4114
4115class AudioPolicyManagerTestBitPerfectPhoneMode : public AudioPolicyManagerTestBitPerfectBase,
4116 public testing::WithParamInterface<audio_mode_t> {
4117};
4118
4119TEST_P(AudioPolicyManagerTestBitPerfectPhoneMode, RejectBitPerfectWhenPhoneModeIsNotNormal) {
4120 if (!com::android::media::audioserver::
4121 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4122 GTEST_SKIP()
4123 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4124 }
4125
4126 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4127
4128 audio_mode_t mode = GetParam();
4129 mManager->setPhoneState(mode);
4130 // When the phone mode is not normal, the bit-perfect output will be reopned
4131 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4132
4133 // When the phone mode is not normal, the bit-perfect output will be closed.
4134 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4135
4136 mManager->setPhoneState(AUDIO_MODE_NORMAL);
4137}
4138
4139INSTANTIATE_TEST_CASE_P(
4140 PhoneMode,
4141 AudioPolicyManagerTestBitPerfectPhoneMode,
4142 testing::Values(AUDIO_MODE_IN_CALL,
4143 AUDIO_MODE_RINGTONE,
4144 AUDIO_MODE_IN_COMMUNICATION,
4145 AUDIO_MODE_CALL_SCREEN)
4146);
4147
4148class AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive :
4149 public AudioPolicyManagerTestBitPerfectBase,
4150 public testing::WithParamInterface<audio_usage_t> {
4151};
4152
4153TEST_P(AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4154 RejectBitPerfectWhenHigherPriorityUseCaseIsActive) {
4155 if (!com::android::media::audioserver::
4156 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4157 GTEST_SKIP()
4158 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4159 }
4160
4161 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4162
4163 audio_attributes_t attr = {
Mikhail Naganov806170e2024-09-05 17:26:50 -07004164 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
jiabin220eea12024-05-17 17:55:20 +00004165 .usage = GetParam(),
jiabin220eea12024-05-17 17:55:20 +00004166 };
4167 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4168 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
4169 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4170 ASSERT_NO_FATAL_FAILURE(
4171 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4172 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, attr));
4173 EXPECT_NE(mBitPerfectOutput, output);
4174 EXPECT_EQ(NO_ERROR, mManager->startOutput(portId));
4175 // When a high priority use case is active, the bit-perfect output will be closed.
4176 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4177
4178 // When any higher priority use case is active, the bit-perfect request will be rejected.
4179 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4180}
4181
4182INSTANTIATE_TEST_CASE_P(
4183 HigherPriorityUseCases,
4184 AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4185 testing::Values(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4186 AUDIO_USAGE_ALARM)
4187);
Eric Laurentc71b11b2024-06-03 12:54:53 +00004188
4189class AudioPolicyManagerInputPreemptionTest : public AudioPolicyManagerTestWithConfigurationFile {
4190};
4191
4192TEST_F_WITH_FLAGS(
4193 AudioPolicyManagerInputPreemptionTest,
4194 SameSessionReusesInput,
4195 REQUIRES_FLAGS_ENABLED(
4196 ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
4197) {
4198 mClient->resetInputApiCallsCounters();
4199
4200 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
4201 attr.source = AUDIO_SOURCE_MIC;
4202 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4203 audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
4204 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
4205 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004206 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004207
4208 EXPECT_EQ(1, mClient->getOpenInputCallsCount());
4209
4210 audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
4211 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, TEST_SESSION_ID, 1, &selectedDeviceId,
4212 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004213 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004214
4215 EXPECT_EQ(1, mClient->getOpenInputCallsCount());
4216 EXPECT_EQ(0, mClient->getCloseInputCallsCount());
4217 EXPECT_EQ(input1, input2);
4218}
4219
4220TEST_F_WITH_FLAGS(
4221 AudioPolicyManagerInputPreemptionTest,
4222 LesserPriorityReusesInput,
4223 REQUIRES_FLAGS_ENABLED(
4224 ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
4225) {
4226 mClient->resetInputApiCallsCounters();
4227
4228 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
4229 attr.source = AUDIO_SOURCE_MIC;
4230 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4231 audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
4232 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
4233 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004234 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004235
4236 EXPECT_EQ(1, mClient->getOpenInputCallsCount());
4237
4238 audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
4239 attr.source = AUDIO_SOURCE_VOICE_RECOGNITION;
4240 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, OTHER_SESSION_ID, 1, &selectedDeviceId,
4241 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004242 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004243
4244 EXPECT_EQ(1, mClient->getOpenInputCallsCount());
4245 EXPECT_EQ(0, mClient->getCloseInputCallsCount());
4246 EXPECT_EQ(input1, input2);
4247}
4248
4249TEST_F_WITH_FLAGS(
4250 AudioPolicyManagerInputPreemptionTest,
4251 HigherPriorityPreemptsInput,
4252 REQUIRES_FLAGS_ENABLED(
4253 ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
4254) {
4255 mClient->resetInputApiCallsCounters();
4256
4257 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
4258 attr.source = AUDIO_SOURCE_MIC;
4259 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4260 audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
4261 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
4262 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004263 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004264
4265 EXPECT_EQ(1, mClient->getOpenInputCallsCount());
4266
4267 audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
4268 attr.source = AUDIO_SOURCE_CAMCORDER;
4269 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, OTHER_SESSION_ID, 1, &selectedDeviceId,
4270 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov806170e2024-09-05 17:26:50 -07004271 k48000SamplingRate));
Eric Laurentc71b11b2024-06-03 12:54:53 +00004272
4273 EXPECT_EQ(2, mClient->getOpenInputCallsCount());
4274 EXPECT_EQ(1, mClient->getCloseInputCallsCount());
4275 EXPECT_NE(input1, input2);
4276}
Mikhail Naganov70b52652024-09-06 10:23:24 -07004277
4278int main(int argc, char** argv) {
4279 ::testing::InitGoogleTest(&argc, argv);
4280 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
4281 return RUN_ALL_TESTS();
4282}