blob: 3662ddf962a390fb41a0fbc4b5e47253e6bd90d7 [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 Naganov285c1732024-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"
47
48using namespace android;
Jiabin Huang3b98d322020-09-03 17:54:16 +000049using testing::UnorderedElementsAre;
Marvin Raminbdefaf02023-11-01 09:10:32 +010050using testing::IsEmpty;
Svet Ganov3e5f14f2021-05-13 22:51:08 +000051using android::content::AttributionSourceState;
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080052
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020053namespace {
54
55AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
56 AudioMixMatchCriterion criterion;
57 criterion.mValue.mUid = uid;
58 criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
59 return criterion;
60}
61
Oscar Azucena873d10f2023-01-12 18:34:42 -080062AudioMixMatchCriterion createUserIdCriterion(int userId, bool exclude = false) {
63 AudioMixMatchCriterion criterion;
64 criterion.mValue.mUserId = userId;
65 criterion.mRule = exclude ? RULE_EXCLUDE_USERID : RULE_MATCH_USERID;
66 return criterion;
67}
68
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020069AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
70 AudioMixMatchCriterion criterion;
71 criterion.mValue.mUsage = usage;
72 criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
73 return criterion;
74}
75
76AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
77 AudioMixMatchCriterion criterion;
78 criterion.mValue.mSource = source;
79 criterion.mRule = exclude ?
80 RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
81 return criterion;
82}
83
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +020084AudioMixMatchCriterion createSessionIdCriterion(audio_session_t session, bool exclude = false) {
85 AudioMixMatchCriterion criterion;
86 criterion.mValue.mAudioSessionId = session;
87 criterion.mRule = exclude ?
88 RULE_EXCLUDE_AUDIO_SESSION_ID : RULE_MATCH_AUDIO_SESSION_ID;
89 return criterion;
90}
91
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +020092// TODO b/182392769: use attribution source util
93AttributionSourceState createAttributionSourceState(uid_t uid) {
94 AttributionSourceState attributionSourceState;
95 attributionSourceState.uid = uid;
96 attributionSourceState.token = sp<BBinder>::make();
97 return attributionSourceState;
98}
99
jiabin66acc432024-02-06 00:57:36 +0000100bool equals(const audio_config_base_t& config1, const audio_config_base_t& config2) {
101 return config1.format == config2.format
102 && config1.sample_rate == config2.sample_rate
103 && config1.channel_mask == config2.channel_mask;
104}
105
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +0200106} // namespace
107
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700108TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
109 auto config = AudioPolicyConfig::createWritableForTests();
110 EXPECT_TRUE(config->getSource().empty());
111 EXPECT_TRUE(config->getHwModules().isEmpty());
112 EXPECT_TRUE(config->getInputDevices().isEmpty());
113 EXPECT_TRUE(config->getOutputDevices().isEmpty());
114}
115
116TEST(AudioPolicyConfigTest, FallbackToDefault) {
117 auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
118 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
119 EXPECT_EQ(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
120}
121
122TEST(AudioPolicyConfigTest, LoadForTests) {
123 {
124 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(
125 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
126 EXPECT_FALSE(result.ok());
127 }
128 {
129 const std::string source =
130 base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml";
131 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(source);
132 ASSERT_TRUE(result.ok());
133 EXPECT_EQ(source, result.value()->getSource());
134 EXPECT_FALSE(result.value()->getHwModules().isEmpty());
135 EXPECT_FALSE(result.value()->getInputDevices().isEmpty());
136 EXPECT_FALSE(result.value()->getOutputDevices().isEmpty());
137 }
138}
139
Mikhail Naganov47835552019-05-14 10:32:51 -0700140TEST(AudioPolicyManagerTestInit, EngineFailure) {
141 AudioPolicyTestClient client;
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700142 auto config = AudioPolicyConfig::createWritableForTests();
143 config->setDefault();
144 config->setEngineLibraryNameSuffix("non-existent");
145 AudioPolicyTestManager manager(config, &client);
Mikhail Naganov47835552019-05-14 10:32:51 -0700146 ASSERT_EQ(NO_INIT, manager.initialize());
147 ASSERT_EQ(NO_INIT, manager.initCheck());
148}
149
150TEST(AudioPolicyManagerTestInit, ClientFailure) {
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800151 AudioPolicyTestClient client;
152 AudioPolicyTestManager manager(&client);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800153 // Since the default client fails to open anything,
154 // APM should indicate that the initialization didn't succeed.
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800155 ASSERT_EQ(NO_INIT, manager.initialize());
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800156 ASSERT_EQ(NO_INIT, manager.initCheck());
157}
158
159
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800160class PatchCountCheck {
161 public:
162 explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
163 : mClient{client},
164 mInitialCount{mClient->getActivePatchesCount()} {}
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800165 int deltaFromSnapshot() const {
166 size_t currentCount = mClient->getActivePatchesCount();
167 if (mInitialCount <= currentCount) {
168 return currentCount - mInitialCount;
169 } else {
170 return -(static_cast<int>(mInitialCount - currentCount));
171 }
172 }
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800173 private:
174 const AudioPolicyManagerTestClient *mClient;
175 const size_t mInitialCount;
176};
177
Mikhail Naganov04a86632017-12-15 18:01:42 -0800178class AudioPolicyManagerTest : public testing::Test {
Mikhail Naganov285c1732024-09-05 17:26:50 -0700179 public:
180 constexpr static uint32_t k384000SamplingRate = 384000;
181 constexpr static uint32_t k48000SamplingRate = 48000;
182 constexpr static uint32_t k96000SamplingRate = 96000;
183
Mikhail Naganov04a86632017-12-15 18:01:42 -0800184 protected:
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800185 void SetUp() override;
186 void TearDown() override;
jiabin7c0205e2019-09-05 10:26:04 -0700187 virtual void SetUpManagerConfig();
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800188 virtual std::string getEngineConfigFilePath() const { return sTestEngineConfig; }
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 Naganov285c1732024-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; }
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800227 void verifyBuiltInStrategyIdsAreValid();
jiabinf4eb15a2019-08-28 15:31:47 -0700228
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700229 sp<AudioPolicyConfig> mConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800230 std::unique_ptr<AudioPolicyManagerTestClient> mClient;
231 std::unique_ptr<AudioPolicyTestManager> mManager;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100232
jiabind9f7fbd2024-09-10 23:07:04 +0000233 static const std::string sTestEngineConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800234};
235
jiabind9f7fbd2024-09-10 23:07:04 +0000236const std::string AudioPolicyManagerTest::sTestEngineConfig =
237 base::GetExecutableDirectory() + "/engine/test_audio_policy_engine_configuration.xml";
238
Mikhail Naganov04a86632017-12-15 18:01:42 -0800239void AudioPolicyManagerTest::SetUp() {
Kriti Dangef6be8f2020-11-05 11:58:19 +0100240 mClient.reset(getClient());
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700241 ASSERT_NO_FATAL_FAILURE(SetUpManagerConfig()); // Subclasses may want to customize the config.
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800242 mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get(), getEngineConfigFilePath()));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800243 ASSERT_EQ(NO_ERROR, mManager->initialize());
244 ASSERT_EQ(NO_ERROR, mManager->initCheck());
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800245}
Mikhail Naganov04a86632017-12-15 18:01:42 -0800246
247void AudioPolicyManagerTest::TearDown() {
248 mManager.reset();
249 mClient.reset();
250}
251
jiabin7c0205e2019-09-05 10:26:04 -0700252void AudioPolicyManagerTest::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700253 mConfig = AudioPolicyConfig::createWritableForTests();
254 mConfig->setDefault();
jiabin7c0205e2019-09-05 10:26:04 -0700255}
256
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800257void AudioPolicyManagerTest::dumpToLog() {
Mikhail Naganov21b43362018-06-04 10:37:09 -0700258 int pipefd[2];
259 ASSERT_NE(-1, pipe(pipefd));
260 pid_t cpid = fork();
261 ASSERT_NE(-1, cpid);
262 if (cpid == 0) {
263 // Child process reads from the pipe and logs.
264 close(pipefd[1]);
265 std::string line;
266 char buf;
267 while (read(pipefd[0], &buf, sizeof(buf)) > 0) {
268 if (buf != '\n') {
269 line += buf;
270 } else {
271 ALOGI("%s", line.c_str());
272 line = "";
273 }
274 }
275 if (!line.empty()) ALOGI("%s", line.c_str());
276 close(pipefd[0]);
277 _exit(EXIT_SUCCESS);
278 } else {
279 // Parent does the dump and checks the status code.
280 close(pipefd[0]);
281 ASSERT_EQ(NO_ERROR, mManager->dump(pipefd[1]));
282 close(pipefd[1]);
283 wait(NULL); // Wait for the child to exit.
284 }
285}
286
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800287void AudioPolicyManagerTest::getOutputForAttr(
288 audio_port_handle_t *selectedDeviceId,
289 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700290 audio_channel_mask_t channelMask,
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800291 int sampleRate,
292 audio_output_flags_t flags,
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700293 audio_io_handle_t *output,
jiabinf4eb15a2019-08-28 15:31:47 -0700294 audio_port_handle_t *portId,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200295 audio_attributes_t attr,
jiabin3ff8d7d2022-12-13 06:27:44 +0000296 audio_session_t session,
jiabin5eaf0962022-12-20 20:11:38 +0000297 int uid,
298 bool* isBitPerfect) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700299 audio_io_handle_t localOutput;
300 if (!output) output = &localOutput;
301 *output = AUDIO_IO_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800302 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
303 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
304 config.sample_rate = sampleRate;
305 config.channel_mask = channelMask;
306 config.format = format;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800307 audio_port_handle_t localPortId;
308 if (!portId) portId = &localPortId;
309 *portId = AUDIO_PORT_HANDLE_NONE;
Eric Laurent8a1095a2019-11-08 14:44:16 -0800310 AudioPolicyInterface::output_type_t outputType;
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200311 bool isSpatialized;
jiabin5eaf0962022-12-20 20:11:38 +0000312 bool isBitPerfectInternal;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200313 AttributionSourceState attributionSource = createAttributionSourceState(uid);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800314 ASSERT_EQ(OK, mManager->getOutputForAttr(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200315 &attr, output, session, &stream, attributionSource, &config, &flags,
jiabin5eaf0962022-12-20 20:11:38 +0000316 selectedDeviceId, portId, {}, &outputType, &isSpatialized,
317 isBitPerfect == nullptr ? &isBitPerfectInternal : isBitPerfect));
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800318 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700319 ASSERT_NE(AUDIO_IO_HANDLE_NONE, *output);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800320}
321
jiabinf4eb15a2019-08-28 15:31:47 -0700322void AudioPolicyManagerTest::getInputForAttr(
323 const audio_attributes_t &attr,
François Gaffie6ebbce02023-07-19 13:27:53 +0200324 audio_io_handle_t *input,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200325 const audio_session_t session,
jiabinf4eb15a2019-08-28 15:31:47 -0700326 audio_unique_id_t riid,
327 audio_port_handle_t *selectedDeviceId,
328 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700329 audio_channel_mask_t channelMask,
jiabinf4eb15a2019-08-28 15:31:47 -0700330 int sampleRate,
331 audio_input_flags_t flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100332 audio_port_handle_t *portId,
333 uint32_t *virtualDeviceId) {
jiabinf4eb15a2019-08-28 15:31:47 -0700334 audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
335 config.sample_rate = sampleRate;
336 config.channel_mask = channelMask;
337 config.format = format;
jiabinf4eb15a2019-08-28 15:31:47 -0700338 audio_port_handle_t localPortId;
339 if (!portId) portId = &localPortId;
340 *portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +0100341 if (!virtualDeviceId) virtualDeviceId = 0;
jiabinf4eb15a2019-08-28 15:31:47 -0700342 AudioPolicyInterface::input_type_t inputType;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200343 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
jiabinf4eb15a2019-08-28 15:31:47 -0700344 ASSERT_EQ(OK, mManager->getInputForAttr(
François Gaffie6ebbce02023-07-19 13:27:53 +0200345 &attr, input, riid, session, attributionSource, &config, flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100346 selectedDeviceId, &inputType, portId, virtualDeviceId));
jiabinf4eb15a2019-08-28 15:31:47 -0700347 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
348}
349
Mikhail Naganov0805de12022-02-15 23:00:07 +0000350void AudioPolicyManagerTest::getAudioPorts(audio_port_type_t type, audio_port_role_t role,
351 std::vector<audio_port_v7>* ports) {
jiabinf4eb15a2019-08-28 15:31:47 -0700352 uint32_t numPorts = 0;
353 uint32_t generation1;
354 status_t ret;
355
Mikhail Naganov0805de12022-02-15 23:00:07 +0000356 ret = mManager->listAudioPorts(role, type, &numPorts, nullptr, &generation1);
357 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
jiabinf4eb15a2019-08-28 15:31:47 -0700358
359 uint32_t generation2;
Mikhail Naganov0805de12022-02-15 23:00:07 +0000360 ports->resize(numPorts);
361 ret = mManager->listAudioPorts(role, type, &numPorts, ports->data(), &generation2);
362 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
363 ASSERT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
364}
365
366bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
367 audio_devices_t deviceType, const std::string &address, audio_port_v7 *foundPort) {
368 std::vector<audio_port_v7> ports;
369 getAudioPorts(AUDIO_PORT_TYPE_DEVICE, role, &ports);
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700370 if (HasFailure()) return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700371
372 for (const auto &port : ports) {
373 if (port.role == role && port.ext.device.type == deviceType &&
374 (strncmp(port.ext.device.address, address.c_str(),
375 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700376 if (foundPort) *foundPort = port;
377 return true;
jiabinf4eb15a2019-08-28 15:31:47 -0700378 }
379 }
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700380 if (foundPort) {
381 ADD_FAILURE() << "Device port with role " << role << " and address "
382 << address << " not found";
383 }
384 return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700385}
386
jiabin7c0205e2019-09-05 10:26:04 -0700387audio_port_handle_t AudioPolicyManagerTest::getDeviceIdFromPatch(
388 const struct audio_patch* patch) {
389 // The logic here is the same as the one in AudioIoDescriptor.
390 // Note this function is aim to get routed device id for test.
391 // In that case, device to device patch is not expected here.
392 if (patch->num_sources != 0 && patch->num_sinks != 0) {
393 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
394 return patch->sinks[0].id;
395 } else {
396 return patch->sources[0].id;
397 }
398 }
399 return AUDIO_PORT_HANDLE_NONE;
400}
401
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800402void AudioPolicyManagerTest::verifyBuiltInStrategyIdsAreValid() {
403 AudioProductStrategyVector strategies;
404 ASSERT_EQ(NO_ERROR, mManager->listAudioProductStrategies(strategies));
405 for (const auto& strategy : strategies) {
406 // Since ids are unsigned, this will also cover the case when the id is 'NONE' which is -1.
407 EXPECT_LT(strategy.getId(),
408 media::audio::common::AudioHalProductStrategy::VENDOR_STRATEGY_ID_START)
409 << strategy.getName();
410 }
411}
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800412
413TEST_F(AudioPolicyManagerTest, InitSuccess) {
414 // SetUp must finish with no assertions.
415}
416
417TEST_F(AudioPolicyManagerTest, Dump) {
418 dumpToLog();
419}
420
Mikhail Naganov04a86632017-12-15 18:01:42 -0800421TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
422 audio_patch patch{};
423 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800424 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganov04a86632017-12-15 18:01:42 -0800425 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
426 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
427 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
428 patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
429 patch.num_sinks = 1;
430 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
431 patch.num_sources = 1;
432 patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
433 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
434 patch.num_sources = 2;
435 patch.num_sinks = 1;
436 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
437 patch = {};
438 patch.num_sources = 1;
439 patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
440 patch.num_sinks = 1;
441 patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
442 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
443 patch = {};
444 patch.num_sources = 1;
445 patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
446 patch.num_sinks = 1;
447 patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
448 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
449 // Verify that the handle is left unchanged.
450 ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800451 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800452}
453
454TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
Mikhail Naganov04a86632017-12-15 18:01:42 -0800455 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
456 uid_t uid = 42;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800457 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000458 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
Mikhail Naganovdc769682018-05-04 15:34:08 -0700459 PatchBuilder patchBuilder;
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000460 patchBuilder.addSource(mManager->getAvailableInputDevices()[0]).
Mikhail Naganovdc769682018-05-04 15:34:08 -0700461 addSink(mManager->getConfig().getDefaultOutputDevice());
462 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800463 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800464 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800465}
466
467// TODO: Add patch creation tests that involve already existing patch
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800468
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800469TEST_F(AudioPolicyManagerTest, BuiltInStrategyIdsAreValid) {
470 verifyBuiltInStrategyIdsAreValid();
471}
472
473class AudioPolicyManagerTestWithDefaultEngineConfig : public AudioPolicyManagerTest {
474 protected:
475 // The APM will use the default engine config from EngineDefaultConfig.h.
476 std::string getEngineConfigFilePath() const override { return ""; }
477};
478
479TEST_F(AudioPolicyManagerTestWithDefaultEngineConfig, BuiltInStrategyIdsAreValid) {
480 verifyBuiltInStrategyIdsAreValid();
481}
482
Michael Chan6fb34492020-12-08 15:44:49 +1100483enum
484{
485 MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX = 0,
486 MSD_AUDIO_PATCH_COUNT_NAME_INDEX = 1
487};
488using MsdAudioPatchCountSpecification = std::tuple<size_t, std::string>;
489
490class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest,
491 public ::testing::WithParamInterface<MsdAudioPatchCountSpecification> {
492 public:
493 AudioPolicyManagerTestMsd();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800494 protected:
jiabin7c0205e2019-09-05 10:26:04 -0700495 void SetUpManagerConfig() override;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800496 void TearDown() override;
Dorin Drimus94d94412022-02-02 09:05:02 +0100497 AudioProfileVector getDirectProfilesForAttributes(const audio_attributes_t& attr);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800498
499 sp<DeviceDescriptor> mMsdOutputDevice;
500 sp<DeviceDescriptor> mMsdInputDevice;
Eric Laurent74c38dc2020-12-23 18:19:44 +0100501 sp<DeviceDescriptor> mDefaultOutputDevice;
Michael Chan6fb34492020-12-08 15:44:49 +1100502
503 const size_t mExpectedAudioPatchCount;
504 sp<DeviceDescriptor> mSpdifDevice;
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100505
506 sp<DeviceDescriptor> mHdmiInputDevice;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800507};
508
Michael Chan6fb34492020-12-08 15:44:49 +1100509AudioPolicyManagerTestMsd::AudioPolicyManagerTestMsd()
510 : mExpectedAudioPatchCount(std::get<MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX>(
511 GetParam())) {}
512
513INSTANTIATE_TEST_CASE_P(
514 MsdAudioPatchCount,
515 AudioPolicyManagerTestMsd,
516 ::testing::Values(
Eric Laurent0ca09402024-05-16 17:48:59 +0000517 MsdAudioPatchCountSpecification(2u, "single"),
518 MsdAudioPatchCountSpecification(3u, "dual")
Michael Chan6fb34492020-12-08 15:44:49 +1100519 ),
520 [](const ::testing::TestParamInfo<MsdAudioPatchCountSpecification> &info) {
521 return std::get<MSD_AUDIO_PATCH_COUNT_NAME_INDEX>(info.param); }
522);
523
jiabin7c0205e2019-09-05 10:26:04 -0700524void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800525 // TODO: Consider using Serializer to load part of the config from a string.
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700526 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700527 mConfig->getHwModules().getModuleFromName(
528 AUDIO_HARDWARE_MODULE_ID_PRIMARY)->setHalVersion(3, 0);
529
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800530 mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
531 sp<AudioProfile> pcmOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100532 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800533 sp<AudioProfile> ac3OutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100534 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100535 sp<AudioProfile> iec958OutputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100536 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800537 mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
538 mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100539 mMsdOutputDevice->addAudioProfile(iec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800540 mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
541 // Match output profile from AudioPolicyConfig::setDefault.
542 sp<AudioProfile> pcmInputProfile = new AudioProfile(
543 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
544 mMsdInputDevice->addAudioProfile(pcmInputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700545 mConfig->addDevice(mMsdOutputDevice);
546 mConfig->addDevice(mMsdInputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800547
Eric Laurent0ca09402024-05-16 17:48:59 +0000548 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100549 // Add SPDIF device with PCM output profile as a second device for dual MSD audio patching.
550 mSpdifDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPDIF);
551 mSpdifDevice->addAudioProfile(pcmOutputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700552 mConfig->addDevice(mSpdifDevice);
Michael Chan6fb34492020-12-08 15:44:49 +1100553
554 sp<OutputProfile> spdifOutputProfile = new OutputProfile("spdif output");
555 spdifOutputProfile->addAudioProfile(pcmOutputProfile);
556 spdifOutputProfile->addSupportedDevice(mSpdifDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700557 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Michael Chan6fb34492020-12-08 15:44:49 +1100558 addOutputProfile(spdifOutputProfile);
559 }
560
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700561 sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 3 /*halVersionMajor*/);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700562 HwModuleCollection modules = mConfig->getHwModules();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800563 modules.add(msdModule);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700564 mConfig->setHwModules(modules);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800565
jiabin5740f082019-08-19 15:08:30 -0700566 sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800567 msdOutputProfile->addAudioProfile(pcmOutputProfile);
568 msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
569 msdModule->addOutputProfile(msdOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700570 sp<OutputProfile> msdCompressedOutputProfile = new OutputProfile("msd compressed input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800571 msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
572 msdCompressedOutputProfile->setFlags(
573 AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
574 AUDIO_OUTPUT_FLAG_NON_BLOCKING);
575 msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
576 msdModule->addOutputProfile(msdCompressedOutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100577 sp<OutputProfile> msdIec958OutputProfile = new OutputProfile("msd iec958 input");
578 msdIec958OutputProfile->addAudioProfile(iec958OutputProfile);
579 msdIec958OutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
580 msdIec958OutputProfile->addSupportedDevice(mMsdOutputDevice);
581 msdModule->addOutputProfile(msdIec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800582
jiabin5740f082019-08-19 15:08:30 -0700583 sp<InputProfile> msdInputProfile = new InputProfile("msd output");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800584 msdInputProfile->addAudioProfile(pcmInputProfile);
585 msdInputProfile->addSupportedDevice(mMsdInputDevice);
586 msdModule->addInputProfile(msdInputProfile);
587
588 // Add a profile with another encoding to the default device to test routing
589 // of streams that are not supported by MSD.
590 sp<AudioProfile> dtsOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100591 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700592 mConfig->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700593 sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800594 primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
595 primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700596 primaryEncodedOutputProfile->addSupportedDevice(mConfig->getDefaultOutputDevice());
597 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800598 addOutputProfile(primaryEncodedOutputProfile);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100599
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700600 mDefaultOutputDevice = mConfig->getDefaultOutputDevice();
Eric Laurent0ca09402024-05-16 17:48:59 +0000601 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100602 mSpdifDevice->addAudioProfile(dtsOutputProfile);
603 primaryEncodedOutputProfile->addSupportedDevice(mSpdifDevice);
604 }
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100605
606 // Add HDMI input device with IEC60958 profile for HDMI in -> MSD patching.
607 mHdmiInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_HDMI);
608 sp<AudioProfile> iec958InputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100609 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100610 mHdmiInputDevice->addAudioProfile(iec958InputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700611 mConfig->addDevice(mHdmiInputDevice);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100612 sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
613 hdmiInputProfile->addAudioProfile(iec958InputProfile);
614 hdmiInputProfile->setFlags(AUDIO_INPUT_FLAG_DIRECT);
615 hdmiInputProfile->addSupportedDevice(mHdmiInputDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700616 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100617 addInputProfile(hdmiInputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800618}
619
620void AudioPolicyManagerTestMsd::TearDown() {
621 mMsdOutputDevice.clear();
622 mMsdInputDevice.clear();
Eric Laurent74c38dc2020-12-23 18:19:44 +0100623 mDefaultOutputDevice.clear();
Michael Chan6fb34492020-12-08 15:44:49 +1100624 mSpdifDevice.clear();
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100625 mHdmiInputDevice.clear();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800626 AudioPolicyManagerTest::TearDown();
627}
628
Dorin Drimus94d94412022-02-02 09:05:02 +0100629AudioProfileVector AudioPolicyManagerTestMsd::getDirectProfilesForAttributes(
630 const audio_attributes_t& attr) {
631 AudioProfileVector audioProfilesVector;
632 mManager->getDirectProfilesForAttributes(&attr, audioProfilesVector);
633 return audioProfilesVector;
634}
635
Michael Chan6fb34492020-12-08 15:44:49 +1100636TEST_P(AudioPolicyManagerTestMsd, InitSuccess) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800637 ASSERT_TRUE(mMsdOutputDevice);
638 ASSERT_TRUE(mMsdInputDevice);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100639 ASSERT_TRUE(mDefaultOutputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800640}
641
Michael Chan6fb34492020-12-08 15:44:49 +1100642TEST_P(AudioPolicyManagerTestMsd, Dump) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800643 dumpToLog();
644}
645
Michael Chan6fb34492020-12-08 15:44:49 +1100646TEST_P(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800647 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800648 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
649 AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Eric Laurent0ca09402024-05-16 17:48:59 +0000650 ASSERT_EQ(mExpectedAudioPatchCount -1 , patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800651}
652
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100653TEST_P(AudioPolicyManagerTestMsd, PatchCreationSetReleaseMsdOutputPatches) {
Michael Chan6fb34492020-12-08 15:44:49 +1100654 const PatchCountCheck patchCount = snapshotPatchCount();
655 DeviceVector devices = mManager->getAvailableOutputDevices();
656 // Remove MSD output device to avoid patching to itself
657 devices.remove(mMsdOutputDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000658 ASSERT_EQ(mExpectedAudioPatchCount -1 , devices.size());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100659 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000660 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Michael Chan6fb34492020-12-08 15:44:49 +1100661 // Dual patch: exercise creating one new audio patch and reusing another existing audio patch.
662 DeviceVector singleDevice(devices[0]);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100663 mManager->releaseMsdOutputPatches(singleDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000664 ASSERT_EQ(mExpectedAudioPatchCount - 2, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100665 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000666 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100667 mManager->releaseMsdOutputPatches(devices);
Michael Chan6fb34492020-12-08 15:44:49 +1100668 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
669}
670
671TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800672 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700673 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100674 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
675 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100676 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100677 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800678}
679
Michael Chan6fb34492020-12-08 15:44:49 +1100680TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800681 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700682 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800683 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100684 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100685 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000686 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800687}
688
Michael Chan6fb34492020-12-08 15:44:49 +1100689TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800690 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700691 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100692 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
693 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100694 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100695 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
696 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800697 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100698 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100699 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100700 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800701}
702
Michael Chan6fb34492020-12-08 15:44:49 +1100703TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
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;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100706 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
707 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800708 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000709 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800710}
711
Michael Chan6fb34492020-12-08 15:44:49 +1100712TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800713 // Switch between formats that are supported and not supported by MSD.
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;
717 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100718 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
719 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100720 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100721 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800722 mManager->releaseOutput(portId);
Eric Laurent0ca09402024-05-16 17:48:59 +0000723 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800724 }
725 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800726 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700727 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
728 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100729 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
730 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800731 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000732 ASSERT_EQ(-static_cast<int>(mExpectedAudioPatchCount) + 2, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800733 mManager->releaseOutput(portId);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800734 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800735 }
736 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800737 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700738 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100739 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
740 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100741 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000742 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800743 }
744}
jiabinf4eb15a2019-08-28 15:31:47 -0700745
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100746TEST_P(AudioPolicyManagerTestMsd, PatchCreationFromHdmiInToMsd) {
747 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
748 uid_t uid = 42;
749 const PatchCountCheck patchCount = snapshotPatchCount();
750 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
751 PatchBuilder patchBuilder;
752 patchBuilder.
753 addSource(mManager->getAvailableInputDevices().
754 getDevice(AUDIO_DEVICE_IN_HDMI, String8(""), AUDIO_FORMAT_DEFAULT)).
755 addSink(mManager->getAvailableOutputDevices().
756 getDevice(AUDIO_DEVICE_OUT_BUS, String8(""), AUDIO_FORMAT_DEFAULT));
757 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
758 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
759 AudioPatchCollection patches = mManager->getAudioPatches();
760 sp<AudioPatch> patch = patches.valueFor(handle);
761 ASSERT_EQ(1, patch->mPatch.num_sources);
762 ASSERT_EQ(1, patch->mPatch.num_sinks);
763 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, patch->mPatch.sources[0].role);
764 ASSERT_EQ(AUDIO_PORT_ROLE_SINK, patch->mPatch.sinks[0].role);
765 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sources[0].format);
766 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sinks[0].format);
Dean Wheatley16809da2022-12-09 14:55:46 +1100767 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sources[0].channel_mask);
768 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sinks[0].channel_mask);
Dean Wheatleyd082f472022-02-04 11:10:48 +1100769 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sources[0].sample_rate);
770 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sinks[0].sample_rate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100771 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
772}
773
Dorin Drimus94d94412022-02-02 09:05:02 +0100774TEST_P(AudioPolicyManagerTestMsd, GetDirectProfilesForAttributesWithMsd) {
775 const audio_attributes_t attr = {
776 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
777 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
778
779 // count expected direct profiles for the default device
780 int countDirectProfilesPrimary = 0;
781 const auto& primary = mManager->getConfig().getHwModules()
782 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700783 for (const auto& outputProfile : primary->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100784 if (outputProfile->asAudioPort()->isDirectOutput()) {
785 countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
786 }
787 }
788
789 // count expected direct profiles for the msd device
790 int countDirectProfilesMsd = 0;
791 const auto& msd = mManager->getConfig().getHwModules()
792 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700793 for (const auto& outputProfile : msd->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100794 if (outputProfile->asAudioPort()->isDirectOutput()) {
795 countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
796 }
797 }
798
799 // before setting up MSD audio patches we only have the primary hal direct profiles
800 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
801
802 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
803 // Remove MSD output device to avoid patching to itself
804 outputDevices.remove(mMsdOutputDevice);
805 mManager->setMsdOutputPatches(&outputDevices);
806
807 // after setting up MSD audio patches the MSD direct profiles are added
808 ASSERT_EQ(countDirectProfilesPrimary + countDirectProfilesMsd,
809 getDirectProfilesForAttributes(attr).size());
810
811 mManager->releaseMsdOutputPatches(outputDevices);
812 // releasing the MSD audio patches gets us back to the primary hal direct profiles only
813 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
814}
815
Dorin Drimusecc9f422022-03-09 17:57:40 +0100816TEST_P(AudioPolicyManagerTestMsd, IsDirectPlaybackSupportedWithMsd) {
817 const audio_attributes_t attr = {
818 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
819 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
820
821 audio_config_base_t directConfig = AUDIO_CONFIG_BASE_INITIALIZER;
822 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700823 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100824 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
825
826 audio_config_base_t nonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
827 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700828 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100829 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
830
831 audio_config_base_t nonExistentConfig = AUDIO_CONFIG_BASE_INITIALIZER;
832 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700833 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100834 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
835
836 audio_config_base_t msdDirectConfig1 = AUDIO_CONFIG_BASE_INITIALIZER;
837 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700838 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100839 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
840
841 audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
842 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700843 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100844 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100845
846 audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
847 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
848 msdNonDirectConfig.sample_rate = 96000;
849 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
850
851 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
852 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
853 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
854 // before setting MSD patches the direct MSD configs return false
855 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
856 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
857 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
858
859 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
860 // Remove MSD output device to avoid patching to itself
861 outputDevices.remove(mMsdOutputDevice);
862 mManager->setMsdOutputPatches(&outputDevices);
863
864 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
865 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
866 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
867 // after setting MSD patches the direct MSD configs return true
868 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
869 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
870 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
871
872 mManager->releaseMsdOutputPatches(outputDevices);
873
874 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
875 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
876 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
877 // AFTER releasing MSD patches the direct MSD configs return false
878 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
879 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
880 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
881}
882
Dorin Drimusfae3c642022-03-17 18:36:30 +0100883TEST_P(AudioPolicyManagerTestMsd, GetDirectPlaybackSupportWithMsd) {
884 const audio_attributes_t attr = {
885 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
886 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
887
888 audio_config_t directConfig = AUDIO_CONFIG_INITIALIZER;
889 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700890 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100891 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
892
893 audio_config_t nonDirectConfig = AUDIO_CONFIG_INITIALIZER;
894 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700895 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100896 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
897
898 audio_config_t nonExistentConfig = AUDIO_CONFIG_INITIALIZER;
899 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700900 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100901 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
902
903 audio_config_t msdDirectConfig1 = AUDIO_CONFIG_INITIALIZER;
904 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700905 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100906 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
907
908 audio_config_t msdDirectConfig2 = AUDIO_CONFIG_INITIALIZER;
909 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700910 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100911 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100912
913 audio_config_t msdNonDirectConfig = AUDIO_CONFIG_INITIALIZER;
914 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
915 msdNonDirectConfig.sample_rate = 96000;
916 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
917
918 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
919 mManager->getDirectPlaybackSupport(&attr, &directConfig));
920 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
921 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
922 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
923 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
924 // before setting MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
925 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
926 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
927 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
928 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
929 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
930 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
931
932 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
933 // Remove MSD output device to avoid patching to itself
934 outputDevices.remove(mMsdOutputDevice);
935 mManager->setMsdOutputPatches(&outputDevices);
936
937 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
938 mManager->getDirectPlaybackSupport(&attr, &directConfig));
939 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
940 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
941 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
942 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
943 // after setting MSD patches the direct MSD configs return values according to their flags
944 ASSERT_EQ(AUDIO_DIRECT_OFFLOAD_SUPPORTED,
945 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
946 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
947 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
948 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
949 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
950
951 mManager->releaseMsdOutputPatches(outputDevices);
952
953 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
954 mManager->getDirectPlaybackSupport(&attr, &directConfig));
955 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
956 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
957 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
958 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
959 // after releasing MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
960 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
961 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
962 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
963 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
964 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
965 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
966}
967
jiabin7c0205e2019-09-05 10:26:04 -0700968class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
969protected:
970 void SetUpManagerConfig() override;
971 virtual std::string getConfigFile() { return sDefaultConfig; }
972
973 static const std::string sExecutableDir;
974 static const std::string sDefaultConfig;
975};
976
977const std::string AudioPolicyManagerTestWithConfigurationFile::sExecutableDir =
978 base::GetExecutableDirectory() + "/";
979
980const std::string AudioPolicyManagerTestWithConfigurationFile::sDefaultConfig =
981 sExecutableDir + "test_audio_policy_configuration.xml";
982
983void AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700984 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(getConfigFile());
985 ASSERT_TRUE(result.ok());
986 mConfig = result.value();
jiabin7c0205e2019-09-05 10:26:04 -0700987}
988
989TEST_F(AudioPolicyManagerTestWithConfigurationFile, InitSuccess) {
990 // SetUp must finish with no assertions.
991}
992
993TEST_F(AudioPolicyManagerTestWithConfigurationFile, Dump) {
994 dumpToLog();
995}
996
Mikhail Naganov0805de12022-02-15 23:00:07 +0000997TEST_F(AudioPolicyManagerTestWithConfigurationFile, ListAudioPortsHasFlags) {
998 // Create an input for VOIP TX because it's not opened automatically like outputs are.
999 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1000 audio_port_handle_t mixPortId = AUDIO_PORT_HANDLE_NONE;
1001 audio_source_t source = AUDIO_SOURCE_VOICE_COMMUNICATION;
François Gaffie6ebbce02023-07-19 13:27:53 +02001002 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source,
1003 AUDIO_FLAG_NONE, ""};
1004 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1005 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
1006 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
1007 AUDIO_CHANNEL_IN_MONO, 8000, AUDIO_INPUT_FLAG_VOIP_TX,
1008 &mixPortId));
Mikhail Naganov0805de12022-02-15 23:00:07 +00001009
1010 std::vector<audio_port_v7> ports;
1011 ASSERT_NO_FATAL_FAILURE(
1012 getAudioPorts(AUDIO_PORT_TYPE_MIX, AUDIO_PORT_ROLE_NONE, &ports));
1013 EXPECT_NE(0, ports.size());
1014 bool hasFlags = false, foundPrimary = false, foundVoipRx = false, foundVoipTx = false;
1015 for (const auto& port : ports) {
1016 if ((port.active_config.config_mask & AUDIO_PORT_CONFIG_FLAGS) != 0) {
1017 hasFlags = true;
1018 if (port.role == AUDIO_PORT_ROLE_SOURCE) {
1019 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
1020 foundPrimary = true;
1021 }
1022 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
1023 foundVoipRx = true;
1024 }
1025 } else if (port.role == AUDIO_PORT_ROLE_SINK) {
1026 if ((port.active_config.flags.input & AUDIO_INPUT_FLAG_VOIP_TX) != 0) {
1027 foundVoipTx = true;
1028 }
1029 }
1030 }
1031 }
1032 EXPECT_TRUE(hasFlags);
1033 EXPECT_TRUE(foundPrimary);
1034 EXPECT_TRUE(foundVoipRx);
1035 EXPECT_TRUE(foundVoipTx);
1036}
1037
Ram Mohan M594558d2022-06-14 14:42:44 +05301038TEST_F(AudioPolicyManagerTestWithConfigurationFile, HandleDeviceConfigChange) {
1039 {
1040 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1041
1042 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1043 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1044 "", "", AUDIO_FORMAT_LDAC));
1045 const auto currCounter = mClient->getRoutingUpdatedCounter();
1046 EXPECT_GT(currCounter, prevCounter);
1047 }
1048 {
1049 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1050 // Update device configuration
1051 EXPECT_EQ(NO_ERROR, mManager->handleDeviceConfigChange(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1052 "" /*address*/, "" /*name*/,
1053 AUDIO_FORMAT_AAC));
1054
1055 // As mClient marks isReconfigA2dpSupported to false, device state needs to be toggled for
1056 // config changes to take effect
1057 const auto currCounter = mClient->getRoutingUpdatedCounter();
1058 EXPECT_GT(currCounter, prevCounter);
1059 }
1060}
1061
jiabina84c3d32022-12-02 18:59:55 +00001062TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferredMixerAttributes) {
1063 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1064 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1065 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1066 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1067 "", "", AUDIO_FORMAT_DEFAULT));
1068 auto devices = mManager->getAvailableOutputDevices();
1069 audio_port_handle_t maxPortId = 0;
1070 audio_port_handle_t speakerPortId;
1071 audio_port_handle_t usbPortId;
1072 for (auto device : devices) {
1073 maxPortId = std::max(maxPortId, device->getId());
1074 if (device->type() == AUDIO_DEVICE_OUT_SPEAKER) {
1075 speakerPortId = device->getId();
1076 } else if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1077 usbPortId = device->getId();
1078 }
1079 }
1080
1081 const uid_t uid = 1234;
1082 const uid_t otherUid = 4321;
1083 const audio_attributes_t mediaAttr = {
1084 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1085 .usage = AUDIO_USAGE_MEDIA,
1086 };
1087 const audio_attributes_t alarmAttr = {
1088 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
1089 .usage = AUDIO_USAGE_ALARM,
1090 };
1091
1092 std::vector<audio_mixer_attributes_t> mixerAttributes;
1093 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1094 for (const auto attrToSet : mixerAttributes) {
1095 audio_mixer_attributes_t attrFromQuery = AUDIO_MIXER_ATTRIBUTES_INITIALIZER;
1096
1097 // The given device is not available
1098 EXPECT_EQ(BAD_VALUE,
1099 mManager->setPreferredMixerAttributes(
1100 &mediaAttr, maxPortId + 1, uid, &attrToSet));
1101 // The only allowed device is USB
1102 EXPECT_EQ(BAD_VALUE,
1103 mManager->setPreferredMixerAttributes(
1104 &mediaAttr, speakerPortId, uid, &attrToSet));
1105 // The only allowed usage is media
1106 EXPECT_EQ(BAD_VALUE,
1107 mManager->setPreferredMixerAttributes(&alarmAttr, usbPortId, uid, &attrToSet));
1108 // Nothing set yet, must get null when query
1109 EXPECT_EQ(NAME_NOT_FOUND,
1110 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1111 EXPECT_EQ(NO_ERROR,
1112 mManager->setPreferredMixerAttributes(
1113 &mediaAttr, usbPortId, uid, &attrToSet));
1114 EXPECT_EQ(NO_ERROR,
1115 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1116 EXPECT_EQ(attrToSet.config.format, attrFromQuery.config.format);
1117 EXPECT_EQ(attrToSet.config.sample_rate, attrFromQuery.config.sample_rate);
1118 EXPECT_EQ(attrToSet.config.channel_mask, attrFromQuery.config.channel_mask);
1119 EXPECT_EQ(attrToSet.mixer_behavior, attrFromQuery.mixer_behavior);
1120 EXPECT_EQ(NAME_NOT_FOUND,
1121 mManager->clearPreferredMixerAttributes(&mediaAttr, speakerPortId, uid));
1122 EXPECT_EQ(PERMISSION_DENIED,
1123 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, otherUid));
1124 EXPECT_EQ(NO_ERROR,
1125 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1126 }
1127
1128 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1129 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1130 "", "", AUDIO_FORMAT_LDAC));
1131}
1132
jiabin3ff8d7d2022-12-13 06:27:44 +00001133TEST_F(AudioPolicyManagerTestWithConfigurationFile, RoutingChangedWithPreferredMixerAttributes) {
1134 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1135 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1136 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1137 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1138 "", "", AUDIO_FORMAT_DEFAULT));
1139 auto devices = mManager->getAvailableOutputDevices();
1140 audio_port_handle_t usbPortId = AUDIO_PORT_HANDLE_NONE;
1141 for (auto device : devices) {
1142 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1143 usbPortId = device->getId();
1144 break;
1145 }
1146 }
1147 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, usbPortId);
1148
1149 const uid_t uid = 1234;
1150 const audio_attributes_t mediaAttr = {
1151 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1152 .usage = AUDIO_USAGE_MEDIA,
1153 };
1154
1155 std::vector<audio_mixer_attributes_t> mixerAttributes;
1156 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1157 EXPECT_GT(mixerAttributes.size(), 0);
1158 EXPECT_EQ(NO_ERROR,
1159 mManager->setPreferredMixerAttributes(
1160 &mediaAttr, usbPortId, uid, &mixerAttributes[0]));
1161
1162 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
1163 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1164 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
1165 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07001166 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001167 AUDIO_SESSION_NONE, uid);
1168 status_t status = mManager->startOutput(portId);
1169 if (status == DEAD_OBJECT) {
1170 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07001171 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001172 AUDIO_SESSION_NONE, uid);
1173 status = mManager->startOutput(portId);
1174 }
1175 EXPECT_EQ(NO_ERROR, status);
1176 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
1177 EXPECT_NE(nullptr, mManager->getOutputs().valueFor(output));
1178 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1179 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1180 "", "", AUDIO_FORMAT_LDAC));
1181 // When BT device is connected, it will be selected as media device and trigger routing changed.
1182 // When this happens, existing output that is opened with preferred mixer attributes will be
1183 // closed and reopened with default config.
1184 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(output));
1185
1186 EXPECT_EQ(NO_ERROR,
1187 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1188
1189 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1190 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1191 "", "", AUDIO_FORMAT_LDAC));
1192 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1193 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1194 "", "", AUDIO_FORMAT_LDAC));
1195}
1196
jiabin66acc432024-02-06 00:57:36 +00001197TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferExactConfigForInput) {
1198 const audio_channel_mask_t deviceChannelMask = AUDIO_CHANNEL_IN_3POINT1;
1199 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1200 mClient->addSupportedChannelMask(deviceChannelMask);
1201 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1202 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1203 "", "", AUDIO_FORMAT_DEFAULT));
1204
1205 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1206 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1207 AUDIO_SOURCE_VOICE_COMMUNICATION,AUDIO_FLAG_NONE, ""};
1208 AudioPolicyInterface::input_type_t inputType;
1209 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1210 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
1211 audio_config_base_t requestedConfig = {
Mikhail Naganov285c1732024-09-05 17:26:50 -07001212 .sample_rate = k48000SamplingRate,
jiabin66acc432024-02-06 00:57:36 +00001213 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1214 .format = AUDIO_FORMAT_PCM_16_BIT,
jiabin66acc432024-02-06 00:57:36 +00001215 };
1216 audio_config_base_t config = requestedConfig;
1217 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +01001218 uint32_t *virtualDeviceId = 0;
jiabin66acc432024-02-06 00:57:36 +00001219 ASSERT_EQ(OK, mManager->getInputForAttr(
1220 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1221 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001222 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001223 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1224 ASSERT_TRUE(equals(requestedConfig, config));
1225
1226 attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1227 AUDIO_SOURCE_VOICE_COMMUNICATION, AUDIO_FLAG_NONE, ""};
1228 requestedConfig.channel_mask = deviceChannelMask;
1229 config = requestedConfig;
1230 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1231 input = AUDIO_PORT_HANDLE_NONE;
1232 portId = AUDIO_PORT_HANDLE_NONE;
1233 ASSERT_EQ(OK, mManager->getInputForAttr(
1234 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1235 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001236 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001237 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1238 ASSERT_TRUE(equals(requestedConfig, config));
1239
1240 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1241 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1242 "", "", AUDIO_FORMAT_DEFAULT));
1243}
1244
Mikhail Naganovc66ffc12024-05-30 16:56:25 -07001245TEST_F(AudioPolicyManagerTestWithConfigurationFile, CheckInputsForDeviceClosesStreams) {
1246 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1247 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1248 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1249 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1250 // Since 'checkInputsForDevice' is called as part of the 'setDeviceConnectionState',
1251 // call it directly here, as we need to ensure that it does not keep all intermediate
1252 // streams opened, as it may cause a rejection from the HAL based on the cap.
1253 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1254 sp<DeviceDescriptor> device = mManager->getHwModules().getDeviceDescriptor(
1255 AUDIO_DEVICE_IN_USB_DEVICE, "", "", AUDIO_FORMAT_DEFAULT, true /*allowToCreate*/);
1256 ASSERT_NE(nullptr, device.get());
1257 EXPECT_EQ(NO_ERROR,
1258 mManager->checkInputsForDevice(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
1259 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1260}
1261
1262TEST_F(AudioPolicyManagerTestWithConfigurationFile, SetDeviceConnectionStateClosesStreams) {
1263 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1264 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1265 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1266 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1267 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1268 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1269 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1270 "", "", AUDIO_FORMAT_DEFAULT));
1271 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1272}
1273
jiabin7c0205e2019-09-05 10:26:04 -07001274class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
jiabinf4eb15a2019-08-28 15:31:47 -07001275protected:
jiabinf4eb15a2019-08-28 15:31:47 -07001276 void TearDown() override;
1277
1278 status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
1279 std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001280 const std::vector<AudioMixMatchCriterion>& matchCriteria);
Marvin Raminbdefaf02023-11-01 09:10:32 +01001281
Marvin Raminabd9b892023-11-17 16:36:27 +01001282 status_t addPolicyMix(const AudioMix& mix);
1283
1284 status_t removePolicyMixes(const Vector<AudioMix>& mixes);
1285
Marvin Raminbdefaf02023-11-01 09:10:32 +01001286 std::vector<AudioMix> getRegisteredPolicyMixes();
jiabinf4eb15a2019-08-28 15:31:47 -07001287 void clearPolicyMix();
jiabin24ff57a2023-11-27 21:06:51 +00001288 void addPolicyMixAndStartInputForLoopback(
1289 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1290 const audio_config_t& audioConfig,
1291 const std::vector<AudioMixMatchCriterion>& matchCriteria,
1292 audio_session_t session=AUDIO_SESSION_NONE,
1293 audio_config_base_t config=DEFAULT_INPUT_CONFIG,
1294 audio_input_flags_t inputFlags=AUDIO_INPUT_FLAG_NONE);
jiabinf4eb15a2019-08-28 15:31:47 -07001295
1296 Vector<AudioMix> mAudioMixes;
jiabinf4eb15a2019-08-28 15:31:47 -07001297 const std::string mMixAddress = "remote_submix_media";
jiabin24ff57a2023-11-27 21:06:51 +00001298
1299 audio_port_handle_t mLoopbackInputPortId = AUDIO_PORT_HANDLE_NONE;
1300 std::unique_ptr<RecordingActivityTracker> mTracker;
1301 struct audio_port_v7 mInjectionPort;
1302
1303 constexpr static const audio_config_base_t DEFAULT_INPUT_CONFIG = {
1304 .sample_rate = k48000SamplingRate,
1305 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1306 .format = AUDIO_FORMAT_PCM_16_BIT
1307 };
jiabinf4eb15a2019-08-28 15:31:47 -07001308};
1309
jiabinf4eb15a2019-08-28 15:31:47 -07001310void AudioPolicyManagerTestDynamicPolicy::TearDown() {
jiabin24ff57a2023-11-27 21:06:51 +00001311 clearPolicyMix();
jiabin7c0205e2019-09-05 10:26:04 -07001312 AudioPolicyManagerTestWithConfigurationFile::TearDown();
jiabinf4eb15a2019-08-28 15:31:47 -07001313}
1314
1315status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
1316 audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001317 const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
1318 AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
jiabinf4eb15a2019-08-28 15:31:47 -07001319 String8(mixAddress.c_str()), 0);
1320 myAudioMix.mDeviceType = deviceType;
Marvin Ramin0783e202024-03-05 12:45:50 +01001321 myAudioMix.mToken = sp<BBinder>::make();
jiabinf4eb15a2019-08-28 15:31:47 -07001322 // Clear mAudioMix before add new one to make sure we don't add already exist mixes.
1323 mAudioMixes.clear();
Marvin Raminabd9b892023-11-17 16:36:27 +01001324 return addPolicyMix(myAudioMix);
1325}
1326
1327status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(const AudioMix& mix) {
1328 mAudioMixes.add(mix);
jiabinf4eb15a2019-08-28 15:31:47 -07001329
1330 // As the policy mixes registration may fail at some case,
1331 // caller need to check the returned status.
1332 status_t ret = mManager->registerPolicyMixes(mAudioMixes);
1333 return ret;
1334}
1335
Marvin Raminabd9b892023-11-17 16:36:27 +01001336status_t AudioPolicyManagerTestDynamicPolicy::removePolicyMixes(const Vector<AudioMix>& mixes) {
1337 status_t ret = mManager->unregisterPolicyMixes(mixes);
1338 return ret;
1339}
1340
Marvin Raminbdefaf02023-11-01 09:10:32 +01001341std::vector<AudioMix> AudioPolicyManagerTestDynamicPolicy::getRegisteredPolicyMixes() {
1342 std::vector<AudioMix> audioMixes;
1343 if (mManager != nullptr) {
1344 status_t ret = mManager->getRegisteredPolicyMixes(audioMixes);
1345 EXPECT_EQ(NO_ERROR, ret);
1346 }
1347 return audioMixes;
1348}
1349
jiabinf4eb15a2019-08-28 15:31:47 -07001350void AudioPolicyManagerTestDynamicPolicy::clearPolicyMix() {
1351 if (mManager != nullptr) {
jiabin24ff57a2023-11-27 21:06:51 +00001352 mManager->stopInput(mLoopbackInputPortId);
jiabinf4eb15a2019-08-28 15:31:47 -07001353 mManager->unregisterPolicyMixes(mAudioMixes);
1354 }
1355 mAudioMixes.clear();
1356}
1357
jiabin24ff57a2023-11-27 21:06:51 +00001358void AudioPolicyManagerTestDynamicPolicy::addPolicyMixAndStartInputForLoopback(
1359 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1360 const audio_config_t& audioConfig,
1361 const std::vector<AudioMixMatchCriterion>& matchCriteria, audio_session_t session,
1362 audio_config_base_t config, audio_input_flags_t inputFlags) {
1363 ASSERT_EQ(NO_ERROR,
1364 addPolicyMix(mixType, mixFlag, deviceType, mixAddress, audioConfig, matchCriteria));
1365 if ((mixFlag & MIX_ROUTE_FLAG_LOOP_BACK) != MIX_ROUTE_FLAG_LOOP_BACK) {
1366 return;
1367 }
1368
1369 mTracker.reset(new RecordingActivityTracker());
1370 struct audio_port_v7 extractionPort;
1371 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1372 mixAddress, &extractionPort));
1373 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1374 audio_source_t source = AUDIO_SOURCE_REMOTE_SUBMIX;
1375 audio_attributes_t attr = {
1376 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source, AUDIO_FLAG_NONE, ""};
1377 std::string tags = "addr=" + mMixAddress;
1378 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1379 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
1380 ASSERT_NO_FATAL_FAILURE(
1381 getInputForAttr(attr, &input, session, mTracker->getRiid(),
1382 &selectedDeviceId, config.format, config.channel_mask,
1383 config.sample_rate, inputFlags, &mLoopbackInputPortId));
1384 ASSERT_EQ(NO_ERROR, mManager->startInput(mLoopbackInputPortId));
1385 ASSERT_EQ(extractionPort.id, selectedDeviceId);
1386
1387 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1388 mMixAddress, &mInjectionPort));
1389}
1390
jiabinf4eb15a2019-08-28 15:31:47 -07001391TEST_F(AudioPolicyManagerTestDynamicPolicy, InitSuccess) {
jiabin7c0205e2019-09-05 10:26:04 -07001392 // SetUp must finish with no assertions
jiabinf4eb15a2019-08-28 15:31:47 -07001393}
1394
1395TEST_F(AudioPolicyManagerTestDynamicPolicy, Dump) {
1396 dumpToLog();
1397}
1398
1399TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyMixes) {
1400 status_t ret;
1401 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1402
1403 // Only capture of playback is allowed in LOOP_BACK &RENDER mode
1404 ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001405 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001406 ASSERT_EQ(INVALID_OPERATION, ret);
1407
1408 // Fail due to the device is already connected.
1409 clearPolicyMix();
1410 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001411 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001412 ASSERT_EQ(INVALID_OPERATION, ret);
1413
1414 // The first time to register policy mixes with valid parameter should succeed.
1415 clearPolicyMix();
1416 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1417 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001418 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001419 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001420 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001421 ASSERT_EQ(NO_ERROR, ret);
1422 // Registering the same policy mixes should fail.
1423 ret = mManager->registerPolicyMixes(mAudioMixes);
1424 ASSERT_EQ(INVALID_OPERATION, ret);
1425
jiabinf4eb15a2019-08-28 15:31:47 -07001426 // Registration should fail due to device not found.
1427 // Note that earpiece is not present in the test configuration file.
1428 // This will need to be updated if earpiece is added in the test configuration file.
jiabin7c0205e2019-09-05 10:26:04 -07001429 clearPolicyMix();
jiabinf4eb15a2019-08-28 15:31:47 -07001430 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001431 AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001432 ASSERT_EQ(INVALID_OPERATION, ret);
1433
1434 // Registration should fail due to output not found.
1435 clearPolicyMix();
1436 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001437 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001438 ASSERT_EQ(INVALID_OPERATION, ret);
1439
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001440 // The first time to register valid loopback policy mix should succeed.
jiabinf4eb15a2019-08-28 15:31:47 -07001441 clearPolicyMix();
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001442 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1443 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001444 ASSERT_EQ(NO_ERROR, ret);
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001445 // Registering the render policy for the loopback address should succeed.
1446 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
1447 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001448 ASSERT_EQ(INVALID_OPERATION, ret);
1449}
1450
1451TEST_F(AudioPolicyManagerTestDynamicPolicy, UnregisterPolicyMixes) {
1452 status_t ret;
1453 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1454
1455 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1456 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001457 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001458 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001459 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001460 ASSERT_EQ(NO_ERROR, ret);
1461
1462 // After successfully registering policy mixes, it should be able to unregister.
1463 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1464 ASSERT_EQ(NO_ERROR, ret);
1465
1466 // After unregistering policy mixes successfully, it should fail unregistering
1467 // the same policy mixes as they are not registered.
1468 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1469 ASSERT_EQ(INVALID_OPERATION, ret);
jiabin7c0205e2019-09-05 10:26:04 -07001470}
jiabinf4eb15a2019-08-28 15:31:47 -07001471
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001472TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
1473 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1474 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1475 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1476 audioConfig.sample_rate = k48000SamplingRate;
1477
1478 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1479 createUidCriterion(/*uid=*/42),
1480 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1481 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1482 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1483 mixMatchCriteria);
1484 ASSERT_EQ(NO_ERROR, ret);
1485}
1486
1487TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
1488 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1489 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1490 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1491 audioConfig.sample_rate = k48000SamplingRate;
1492
1493 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1494 createUidCriterion(/*uid=*/42),
1495 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1496 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1497 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1498 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1499 mixMatchCriteria);
1500 ASSERT_EQ(INVALID_OPERATION, ret);
1501}
1502
Marvin Raminbdefaf02023-11-01 09:10:32 +01001503TEST_F_WITH_FLAGS(
1504 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminabd9b892023-11-17 16:36:27 +01001505 RegisterInvalidMixesDoesNotImpactPriorMixes,
1506 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1507 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1508) {
1509 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1510 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1511 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1512 audioConfig.sample_rate = k48000SamplingRate;
1513
1514 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1515 createUidCriterion(/*uid=*/42),
1516 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1517 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1518 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1519 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1520
1521 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001522 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001523
1524 ASSERT_EQ(NO_ERROR, ret);
1525
1526 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1527 ASSERT_EQ(1, registeredMixes.size());
1528
1529 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1530 createUidCriterion(/*uid=*/42),
1531 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1532 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1533
1534 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1535 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1536 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1537
Marvin Ramin0783e202024-03-05 12:45:50 +01001538 ret = addPolicyMix(invalidAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001539
1540 ASSERT_EQ(INVALID_OPERATION, ret);
1541
1542 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1543 ASSERT_EQ(registeredMixes.size(), remainingMixes.size());
1544}
1545
1546TEST_F_WITH_FLAGS(
1547 AudioPolicyManagerTestDynamicPolicy,
1548 UnregisterInvalidMixesReturnsError,
1549 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1550 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1551) {
1552 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1553 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1554 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1555 audioConfig.sample_rate = k48000SamplingRate;
1556
1557 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1558 createUidCriterion(/*uid=*/42),
1559 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1560 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1561 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1562 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1563
1564 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001565 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001566
1567 ASSERT_EQ(NO_ERROR, ret);
1568
1569 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1570 ASSERT_EQ(1, registeredMixes.size());
1571
1572 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1573 createUidCriterion(/*uid=*/42),
1574 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1575 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1576
1577 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1578 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
Marvin Ramin0783e202024-03-05 12:45:50 +01001579 invalidAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Marvin Raminabd9b892023-11-17 16:36:27 +01001580
1581 Vector<AudioMix> mixes;
1582 mixes.add(invalidAudioMix);
1583 mixes.add(validAudioMix);
1584 ret = removePolicyMixes(mixes);
1585
1586 ASSERT_EQ(INVALID_OPERATION, ret);
1587
1588 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1589 EXPECT_THAT(remainingMixes, IsEmpty());
1590}
1591
1592TEST_F_WITH_FLAGS(
1593 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminbdefaf02023-11-01 09:10:32 +01001594 GetRegisteredPolicyMixes,
1595 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1596) {
1597 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1598 EXPECT_THAT(mixes, IsEmpty());
1599}
1600
1601TEST_F_WITH_FLAGS(AudioPolicyManagerTestDynamicPolicy,
1602 AddPolicyMixAndVerifyGetRegisteredPolicyMixes,
1603 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1604) {
1605 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1606 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1607 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1608 audioConfig.sample_rate = k48000SamplingRate;
1609
1610 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1611 createUidCriterion(/*uid=*/42),
1612 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1613 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1614 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1615 mixMatchCriteria);
1616 ASSERT_EQ(NO_ERROR, ret);
1617
1618 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1619 ASSERT_EQ(mixes.size(), 1);
1620
1621 const AudioMix& mix = mixes[0];
1622 ASSERT_EQ(mix.mCriteria.size(), mixMatchCriteria.size());
1623 for (uint32_t i = 0; i < mixMatchCriteria.size(); i++) {
1624 EXPECT_EQ(mix.mCriteria[i].mRule, mixMatchCriteria[i].mRule);
1625 EXPECT_EQ(mix.mCriteria[i].mValue.mUsage, mixMatchCriteria[i].mValue.mUsage);
1626 }
1627 EXPECT_EQ(mix.mDeviceType, AUDIO_DEVICE_OUT_REMOTE_SUBMIX);
1628 EXPECT_EQ(mix.mRouteFlags, MIX_ROUTE_FLAG_LOOP_BACK);
1629 EXPECT_EQ(mix.mMixType, MIX_TYPE_PLAYERS);
1630 EXPECT_EQ(mix.mFormat.channel_mask, audioConfig.channel_mask);
1631 EXPECT_EQ(mix.mFormat.format, audioConfig.format);
1632 EXPECT_EQ(mix.mFormat.sample_rate, audioConfig.sample_rate);
1633 EXPECT_EQ(mix.mFormat.frame_count, audioConfig.frame_count);
1634}
1635
Kriti Dangef6be8f2020-11-05 11:58:19 +01001636class AudioPolicyManagerTestForHdmi
Mikhail Naganov18885d32021-10-01 13:03:09 -07001637 : public AudioPolicyManagerTestWithConfigurationFile,
1638 public testing::WithParamInterface<audio_format_t> {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001639protected:
1640 void SetUp() override;
1641 std::string getConfigFile() override { return sTvConfig; }
Kriti Dang6537def2021-03-02 13:46:59 +01001642 std::map<audio_format_t, bool> getSurroundFormatsHelper();
1643 std::vector<audio_format_t> getReportedSurroundFormatsHelper();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001644 std::unordered_set<audio_format_t> getFormatsFromPorts();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001645 void TearDown() override;
1646
1647 static const std::string sTvConfig;
1648
1649};
1650
1651const std::string AudioPolicyManagerTestForHdmi::sTvConfig =
1652 AudioPolicyManagerTestForHdmi::sExecutableDir +
1653 "test_settop_box_surround_configuration.xml";
1654
1655void AudioPolicyManagerTestForHdmi::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001656 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUp());
Mikhail Naganov83caee02021-10-05 15:52:01 -07001657 mClient->addSupportedFormat(AUDIO_FORMAT_AC3);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001658 mClient->addSupportedFormat(AUDIO_FORMAT_E_AC3);
jiabin12537fc2023-10-12 17:56:08 +00001659 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001660 mManager->setDeviceConnectionState(
1661 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1662 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1663}
1664
1665void AudioPolicyManagerTestForHdmi::TearDown() {
1666 mManager->setDeviceConnectionState(
1667 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1668 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1669 AudioPolicyManagerTest::TearDown();
1670}
1671
1672std::map<audio_format_t, bool>
Kriti Dang6537def2021-03-02 13:46:59 +01001673 AudioPolicyManagerTestForHdmi::getSurroundFormatsHelper() {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001674 unsigned int numSurroundFormats = 0;
1675 std::map<audio_format_t, bool> surroundFormatsMap;
1676 status_t ret = mManager->getSurroundFormats(
1677 &numSurroundFormats, nullptr /* surroundFormats */,
Kriti Dang6537def2021-03-02 13:46:59 +01001678 nullptr /* surroundFormatsEnabled */);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001679 EXPECT_EQ(NO_ERROR, ret);
1680 if (ret != NO_ERROR) {
1681 return surroundFormatsMap;
1682 }
1683 audio_format_t surroundFormats[numSurroundFormats];
1684 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1685 bool surroundFormatsEnabled[numSurroundFormats];
1686 memset(surroundFormatsEnabled, 0, sizeof(bool) * numSurroundFormats);
1687 ret = mManager->getSurroundFormats(
Kriti Dang6537def2021-03-02 13:46:59 +01001688 &numSurroundFormats, surroundFormats, surroundFormatsEnabled);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001689 EXPECT_EQ(NO_ERROR, ret);
1690 if (ret != NO_ERROR) {
1691 return surroundFormatsMap;
1692 }
1693 for (int i = 0; i< numSurroundFormats; i++) {
1694 surroundFormatsMap[surroundFormats[i]] = surroundFormatsEnabled[i];
1695 }
1696 return surroundFormatsMap;
1697}
1698
Kriti Dang6537def2021-03-02 13:46:59 +01001699std::vector<audio_format_t> AudioPolicyManagerTestForHdmi::getReportedSurroundFormatsHelper() {
1700 unsigned int numSurroundFormats = 0;
1701 std::vector<audio_format_t> surroundFormatsVector;
1702 status_t ret = mManager->getReportedSurroundFormats(
1703 &numSurroundFormats, nullptr /* surroundFormats */);
1704 EXPECT_EQ(NO_ERROR, ret);
1705 if (ret != NO_ERROR) {
1706 return surroundFormatsVector;
1707 }
1708 audio_format_t surroundFormats[numSurroundFormats];
1709 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1710 ret = mManager->getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
1711 EXPECT_EQ(NO_ERROR, ret);
1712 if (ret != NO_ERROR) {
1713 return surroundFormatsVector;
1714 }
1715 for (const auto &surroundFormat : surroundFormats) {
1716 surroundFormatsVector.push_back(surroundFormat);
1717 }
1718 return surroundFormatsVector;
1719}
1720
Kriti Dangef6be8f2020-11-05 11:58:19 +01001721std::unordered_set<audio_format_t>
1722 AudioPolicyManagerTestForHdmi::getFormatsFromPorts() {
1723 uint32_t numPorts = 0;
1724 uint32_t generation1;
1725 status_t ret;
1726 std::unordered_set<audio_format_t> formats;
1727 ret = mManager->listAudioPorts(
1728 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
1729 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1730 if (ret != NO_ERROR) {
1731 return formats;
1732 }
jiabin19cdba52020-11-24 11:28:58 -08001733 struct audio_port_v7 ports[numPorts];
Kriti Dangef6be8f2020-11-05 11:58:19 +01001734 ret = mManager->listAudioPorts(
1735 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation1);
1736 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1737 if (ret != NO_ERROR) {
1738 return formats;
1739 }
1740 for (const auto &port : ports) {
jiabin19cdba52020-11-24 11:28:58 -08001741 for (size_t i = 0; i < port.num_audio_profiles; ++i) {
1742 formats.insert(port.audio_profiles[i].format);
1743 }
Kriti Dangef6be8f2020-11-05 11:58:19 +01001744 }
1745 return formats;
1746}
1747
Mikhail Naganov18885d32021-10-01 13:03:09 -07001748TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsReturnsSupportedFormats) {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001749 mManager->setForceUse(
1750 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001751 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001752 ASSERT_EQ(1, surroundFormats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001753}
1754
Mikhail Naganov18885d32021-10-01 13:03:09 -07001755TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001756 GetSurroundFormatsReturnsManipulatedFormats) {
1757 mManager->setForceUse(
1758 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1759
1760 status_t ret =
Mikhail Naganov18885d32021-10-01 13:03:09 -07001761 mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001762 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001763 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001764 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1765 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001766
Mikhail Naganov18885d32021-10-01 13:03:09 -07001767 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001768 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001769 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001770 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1771 ASSERT_TRUE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001772
Mikhail Naganov18885d32021-10-01 13:03:09 -07001773 ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001774 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001775 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001776 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1777 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001778}
1779
Mikhail Naganov18885d32021-10-01 13:03:09 -07001780TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001781 ListAudioPortsReturnManipulatedHdmiFormats) {
1782 mManager->setForceUse(
1783 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1784
Mikhail Naganov18885d32021-10-01 13:03:09 -07001785 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/));
jiabin12537fc2023-10-12 17:56:08 +00001786 auto formats = getFormatsFromPorts();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001787 ASSERT_EQ(1, formats.count(GetParam()));
jiabin12537fc2023-10-12 17:56:08 +00001788
1789 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/));
1790 formats = getFormatsFromPorts();
1791 ASSERT_EQ(0, formats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001792}
1793
Mikhail Naganov18885d32021-10-01 13:03:09 -07001794TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001795 GetReportedSurroundFormatsReturnsHdmiReportedFormats) {
1796 mManager->setForceUse(
1797 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001798 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001799 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001800}
1801
Mikhail Naganov18885d32021-10-01 13:03:09 -07001802TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001803 GetReportedSurroundFormatsReturnsNonManipulatedHdmiReportedFormats) {
1804 mManager->setForceUse(
1805 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1806
Mikhail Naganov18885d32021-10-01 13:03:09 -07001807 status_t ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001808 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001809 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001810 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001811
Mikhail Naganov18885d32021-10-01 13:03:09 -07001812 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001813 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001814 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}
1817
Mikhail Naganov18885d32021-10-01 13:03:09 -07001818TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsIgnoresSupportedFormats) {
1819 mManager->setForceUse(
1820 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER);
1821 auto surroundFormats = getSurroundFormatsHelper();
1822 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1823 ASSERT_FALSE(surroundFormats[GetParam()]);
1824}
1825
1826INSTANTIATE_TEST_SUITE_P(SurroundFormatSupport, AudioPolicyManagerTestForHdmi,
1827 testing::Values(AUDIO_FORMAT_AC3, AUDIO_FORMAT_E_AC3),
1828 [](const ::testing::TestParamInfo<AudioPolicyManagerTestForHdmi::ParamType>& info) {
1829 return audio_format_to_string(info.param);
1830 });
1831
jiabin7c0205e2019-09-05 10:26:04 -07001832class AudioPolicyManagerTestDPNoRemoteSubmixModule : public AudioPolicyManagerTestDynamicPolicy {
1833protected:
1834 std::string getConfigFile() override { return sPrimaryOnlyConfig; }
1835
1836 static const std::string sPrimaryOnlyConfig;
1837};
1838
1839const std::string AudioPolicyManagerTestDPNoRemoteSubmixModule::sPrimaryOnlyConfig =
1840 sExecutableDir + "test_audio_policy_primary_only_configuration.xml";
1841
1842TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, InitSuccess) {
1843 // SetUp must finish with no assertions.
1844}
1845
1846TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, Dump) {
1847 dumpToLog();
1848}
1849
1850TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, RegistrationFailure) {
1851 // Registration/Unregistration should fail due to module for remote submix not found.
1852 status_t ret;
1853 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1854 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1855 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001856 audioConfig.sample_rate = k48000SamplingRate;
jiabin7c0205e2019-09-05 10:26:04 -07001857 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001858 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabin7c0205e2019-09-05 10:26:04 -07001859 ASSERT_EQ(INVALID_OPERATION, ret);
1860
jiabinf4eb15a2019-08-28 15:31:47 -07001861 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1862 ASSERT_EQ(INVALID_OPERATION, ret);
1863}
1864
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001865struct DPTestParam {
1866 DPTestParam(const std::vector<AudioMixMatchCriterion>& mixCriteria,
1867 bool expected_match = false)
1868 : mixCriteria(mixCriteria), attributes(defaultAttr), session(AUDIO_SESSION_NONE),
1869 expected_match(expected_match) {}
1870
1871 DPTestParam& withUsage(audio_usage_t usage) {
1872 attributes.usage = usage;
1873 return *this;
1874 }
1875
1876 DPTestParam& withTags(const char *tags) {
1877 std::strncpy(attributes.tags, tags, sizeof(attributes.tags));
1878 return *this;
1879 }
1880
1881 DPTestParam& withSource(audio_source_t source) {
1882 attributes.source = source;
1883 return *this;
1884 }
1885
1886 DPTestParam& withSessionId(audio_session_t sessionId) {
1887 session = sessionId;
1888 return *this;
1889 }
1890
1891 std::vector<AudioMixMatchCriterion> mixCriteria;
1892 audio_attributes_t attributes;
1893 audio_session_t session;
1894 bool expected_match;
1895};
1896
jiabinf4eb15a2019-08-28 15:31:47 -07001897class AudioPolicyManagerTestDPPlaybackReRouting : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001898 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07001899protected:
1900 void SetUp() override;
jiabinf4eb15a2019-08-28 15:31:47 -07001901};
1902
1903void AudioPolicyManagerTestDPPlaybackReRouting::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001904 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07001905
1906 mTracker.reset(new RecordingActivityTracker());
1907
1908 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1909 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1910 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001911 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001912
1913 DPTestParam param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00001914 ASSERT_NO_FATAL_FAILURE(
1915 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1916 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria,
1917 param.session));
jiabinf4eb15a2019-08-28 15:31:47 -07001918}
1919
jiabinf4eb15a2019-08-28 15:31:47 -07001920TEST_P(AudioPolicyManagerTestDPPlaybackReRouting, PlaybackReRouting) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001921 const DPTestParam param = GetParam();
1922 const audio_attributes_t& attr = param.attributes;
jiabinf4eb15a2019-08-28 15:31:47 -07001923
jiabin7c0205e2019-09-05 10:26:04 -07001924 audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07001925 getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11001926 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001927 attr, param.session);
1928 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07001929 EXPECT_EQ(mInjectionPort.id, playbackRoutedPortId);
1930 } else {
1931 EXPECT_NE(mInjectionPort.id, playbackRoutedPortId);
1932 }
1933}
1934
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001935const std::vector<AudioMixMatchCriterion> USAGE_MEDIA_ALARM_CRITERIA = {
1936 createUsageCriterion(AUDIO_USAGE_MEDIA),
1937 createUsageCriterion(AUDIO_USAGE_ALARM)
1938};
jiabinf4eb15a2019-08-28 15:31:47 -07001939
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001940INSTANTIATE_TEST_SUITE_P(
1941 PlaybackReroutingUsageMatch,
1942 AudioPolicyManagerTestDPPlaybackReRouting,
1943 testing::Values(
1944 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1945 .withUsage(AUDIO_USAGE_MEDIA),
1946 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1947 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=other"),
1948 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1949 .withUsage(AUDIO_USAGE_ALARM),
1950 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1951 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION),
1952 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1953 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING),
1954 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1955 .withUsage(AUDIO_USAGE_NOTIFICATION),
1956 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1957 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE),
1958 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1959 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST),
1960 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1961 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT),
1962 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1963 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED),
1964 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1965 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT),
1966 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1967 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY),
1968 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1969 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE),
1970 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1971 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION),
1972 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1973 .withUsage(AUDIO_USAGE_GAME),
1974 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1975 .withUsage(AUDIO_USAGE_ASSISTANT)));
jiabinf4eb15a2019-08-28 15:31:47 -07001976
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001977INSTANTIATE_TEST_SUITE_P(
1978 PlaybackReroutingAddressPriorityMatch,
1979 AudioPolicyManagerTestDPPlaybackReRouting,
1980 testing::Values(
1981 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1982 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=remote_submix_media"),
1983 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1984 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION).withTags("addr=remote_submix_media"),
1985 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1986 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING)
1987 .withTags("addr=remote_submix_media"),
1988 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1989 .withUsage(AUDIO_USAGE_ALARM)
1990 .withTags("addr=remote_submix_media"),
1991 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1992 .withUsage(AUDIO_USAGE_NOTIFICATION)
1993 .withTags("addr=remote_submix_media"),
1994 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1995 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE)
1996 .withTags("addr=remote_submix_media"),
1997 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1998 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST)
1999 .withTags("addr=remote_submix_media"),
2000 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2001 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
2002 .withTags("addr=remote_submix_media"),
2003 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2004 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED)
2005 .withTags("addr=remote_submix_media"),
2006 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2007 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT)
2008 .withTags("addr=remote_submix_media"),
2009 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2010 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY)
2011 .withTags("addr=remote_submix_media"),
2012 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2013 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
2014 .withTags("addr=remote_submix_media"),
2015 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2016 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION)
2017 .withTags("addr=remote_submix_media"),
2018 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2019 .withUsage(AUDIO_USAGE_GAME)
2020 .withTags("addr=remote_submix_media"),
2021 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2022 .withUsage(AUDIO_USAGE_VIRTUAL_SOURCE)
2023 .withTags("addr=remote_submix_media"),
2024 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2025 .withUsage(AUDIO_USAGE_ASSISTANT)
Jan Sebechlebskybc56bcd2022-09-26 13:15:19 +02002026 .withTags("addr=remote_submix_media"),
2027 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2028 .withUsage(AUDIO_USAGE_ASSISTANT)
2029 .withTags("sometag;addr=remote_submix_media;othertag=somevalue"),
2030 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2031 .withUsage(AUDIO_USAGE_ASSISTANT)
2032 .withTags("addr=remote_submix_media;othertag"),
2033 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2034 .withUsage(AUDIO_USAGE_ASSISTANT)
2035 .withTags("sometag;othertag;addr=remote_submix_media")));
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002036
2037static constexpr audio_session_t TEST_SESSION_ID = static_cast<audio_session_t>(42);
2038static constexpr audio_session_t OTHER_SESSION_ID = static_cast<audio_session_t>(77);
2039
2040INSTANTIATE_TEST_SUITE_P(
2041 PlaybackReRoutingWithSessionId,
2042 AudioPolicyManagerTestDPPlaybackReRouting,
2043 testing::Values(
2044 // Mix is matched because the session id matches the one specified by the mix rule.
2045 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2046 /*expected_match=*/ true)
2047 .withSessionId(TEST_SESSION_ID),
2048 // Mix is not matched because the session id doesn't match the one specified
2049 // by the mix rule.
2050 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2051 /*expected_match=*/ false)
2052 .withSessionId(OTHER_SESSION_ID),
2053 // Mix is matched, the session id doesn't match the one specified by rule,
2054 // but there's address specified in the tags which takes precedence.
2055 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2056 /*expected_match=*/ true)
2057 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2058 // Mix is matched, both the session id and the usage match ones specified by mix rule.
2059 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2060 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2061 /*expected_match=*/ true)
2062 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA),
2063 // Mix is not matched, the session id matches the one specified by mix rule,
2064 // but usage does not.
2065 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2066 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2067 /*expected_match=*/ false)
2068 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_GAME),
2069 // Mix is not matched, the usage matches the one specified by mix rule,
2070 // but the session id is excluded.
2071 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID, /*exclude=*/ true),
2072 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2073 /*expected_match=*/ false)
2074 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA)));
jiabinf4eb15a2019-08-28 15:31:47 -07002075
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002076struct DPMmapTestParam {
2077 DPMmapTestParam(int mixRouteFlags, audio_devices_t deviceType, const std::string& deviceAddress)
2078 : mixRouteFlags(mixRouteFlags), deviceType(deviceType), deviceAddress(deviceAddress) {}
2079
2080 int mixRouteFlags;
2081 audio_devices_t deviceType;
2082 std::string deviceAddress;
2083};
2084
2085class AudioPolicyManagerTestMMapPlaybackRerouting
2086 : public AudioPolicyManagerTestDynamicPolicy,
2087 public ::testing::WithParamInterface<DPMmapTestParam> {
2088 protected:
2089 void SetUp() override {
2090 AudioPolicyManagerTestDynamicPolicy::SetUp();
2091 audioConfig = AUDIO_CONFIG_INITIALIZER;
2092 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2093 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2094 audioConfig.sample_rate = k48000SamplingRate;
2095 }
2096
2097 audio_config_t audioConfig;
2098 audio_io_handle_t mOutput;
2099 audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
2100 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebskyb3d3f622023-07-13 11:09:15 +02002101 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002102 AudioPolicyInterface::output_type_t mOutputType;
2103 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
2104 bool mIsSpatialized;
2105 bool mIsBitPerfect;
2106};
2107
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002108TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting, MmapPlaybackStreamMatchingLoopbackDapMixFails) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002109 // Add mix matching the test uid.
2110 const int testUid = 12345;
2111 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002112 ASSERT_NO_FATAL_FAILURE(
2113 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2114 param.deviceType, param.deviceAddress, audioConfig,
2115 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002116
jiabin24ff57a2023-11-27 21:06:51 +00002117 // Getting output for matching uid and mmap-ed stream should fail.
2118 audio_output_flags_t outputFlags =
2119 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002120 ASSERT_EQ(INVALID_OPERATION,
2121 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2122 createAttributionSourceState(testUid), &audioConfig,
2123 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2124 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2125}
2126
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002127TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting,
2128 NonMmapPlaybackStreamMatchingLoopbackDapMixSucceeds) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002129 // Add mix matching the test uid.
2130 const int testUid = 12345;
2131 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002132 ASSERT_NO_FATAL_FAILURE(
2133 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2134 param.deviceType,param.deviceAddress, audioConfig,
2135 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002136
jiabin24ff57a2023-11-27 21:06:51 +00002137 // Getting output for matching uid should succeed for non-mmaped stream.
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002138 audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2139 ASSERT_EQ(NO_ERROR,
2140 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2141 createAttributionSourceState(testUid), &audioConfig,
2142 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2143 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2144}
2145
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002146TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002147 MmapPlaybackStreamMatchingRenderDapMixSupportingMmapSucceeds) {
jiabin24ff57a2023-11-27 21:06:51 +00002148 const std::string usbAddress = "card=1;device=0";
2149 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2150 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2151 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
2152 audio_port_v7 usbDevicePort;
2153 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_USB_DEVICE,
2154 usbAddress, &usbDevicePort));
2155
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002156 // Add render-only mix matching the test uid.
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002157 const int testUid = 12345;
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002158 // test_audio_policy_configuration.xml declares mmap-capable mix port
2159 // for AUDIO_DEVICE_OUT_USB_DEVICE.
jiabin24ff57a2023-11-27 21:06:51 +00002160 ASSERT_EQ(NO_ERROR,
2161 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2162 AUDIO_DEVICE_OUT_USB_DEVICE, /*mixAddress=*/"",
2163 audioConfig, {createUidCriterion(testUid)}));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002164
jiabin24ff57a2023-11-27 21:06:51 +00002165 static const audio_output_flags_t mmapDirectFlags =
2166 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
2167 // Getting output for matching uid should succeed for mmaped stream, because matched mix
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002168 // redirects to mmap capable device.
jiabin24ff57a2023-11-27 21:06:51 +00002169 audio_output_flags_t outputFlags = mmapDirectFlags;
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002170 ASSERT_EQ(NO_ERROR,
2171 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2172 createAttributionSourceState(testUid), &audioConfig,
2173 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2174 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
jiabin24ff57a2023-11-27 21:06:51 +00002175 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2176 auto outputDesc = mManager->getOutputs().valueFor(mOutput);
2177 ASSERT_NE(nullptr, outputDesc);
2178 ASSERT_EQ(mmapDirectFlags, outputDesc->getFlags().output);
2179
2180 // After releasing the client, the output is closed. APM should reselect output for the policy
2181 // mix.
2182 mManager->releaseOutput(mPortId);
2183 ASSERT_EQ(nullptr, mManager->getOutputs().valueFor(mOutput));
2184 outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2185 mPortId = AUDIO_PORT_HANDLE_NONE;
2186 ASSERT_EQ(NO_ERROR,
2187 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2188 createAttributionSourceState(testUid), &audioConfig,
2189 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2190 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2191 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2192 outputDesc = mManager->getOutputs().valueFor(mOutput);
2193 ASSERT_NE(nullptr, outputDesc);
2194 ASSERT_NE(mmapDirectFlags, outputDesc->getFlags().output);
2195
2196 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2197 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2198 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002199}
2200
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002201TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
2202 MmapPlaybackStreamMatchingRenderDapMixNotSupportingMmapFails) {
2203 // Add render-only mix matching the test uid.
2204 const int testUid = 12345;
2205 // Per test_audio_policy_configuration.xml AUDIO_DEVICE_OUT_SPEAKER doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002206 ASSERT_EQ(NO_ERROR,
2207 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2208 AUDIO_DEVICE_OUT_SPEAKER, /*mixAddress=*/"", audioConfig,
2209 {createUidCriterion(testUid)}));
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002210
jiabin24ff57a2023-11-27 21:06:51 +00002211 // Getting output for matching uid should fail for mmaped stream, because
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002212 // matched mix redirects to device which doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002213 audio_output_flags_t outputFlags =
2214 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002215 ASSERT_EQ(INVALID_OPERATION,
2216 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2217 createAttributionSourceState(testUid), &audioConfig,
2218 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2219 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2220}
2221
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002222INSTANTIATE_TEST_SUITE_P(
2223 MmapPlaybackRerouting, AudioPolicyManagerTestMMapPlaybackRerouting,
2224 testing::Values(DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2225 /*deviceAddress=*/"remote_submix_media"),
2226 DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
2227 AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
jiabin1ca6c6f2023-09-22 17:25:59 +00002228 /*deviceAddress=*/"remote_submix_media"),
2229 DPMmapTestParam(MIX_ROUTE_FLAG_RENDER, AUDIO_DEVICE_OUT_SPEAKER,
2230 /*deviceAddress=*/"")));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002231
jiabinf4eb15a2019-08-28 15:31:47 -07002232class AudioPolicyManagerTestDPMixRecordInjection : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002233 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07002234protected:
2235 void SetUp() override;
2236 void TearDown() override;
2237
2238 std::unique_ptr<RecordingActivityTracker> mTracker;
jiabin19cdba52020-11-24 11:28:58 -08002239 struct audio_port_v7 mExtractionPort;
jiabinf4eb15a2019-08-28 15:31:47 -07002240 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
2241};
2242
2243void AudioPolicyManagerTestDPMixRecordInjection::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07002244 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07002245
2246 mTracker.reset(new RecordingActivityTracker());
2247
2248 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2249 audioConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
2250 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002251 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002252
2253 DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002254 status_t ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002255 AUDIO_DEVICE_IN_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria);
jiabinf4eb15a2019-08-28 15:31:47 -07002256 ASSERT_EQ(NO_ERROR, ret);
2257
jiabin19cdba52020-11-24 11:28:58 -08002258 struct audio_port_v7 injectionPort;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002259 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2260 mMixAddress, &injectionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002261
2262 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2263 audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
Mikhail Naganov55773032020-10-01 15:08:13 -07002264 audio_attributes_t attr =
2265 {AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
jiabinf4eb15a2019-08-28 15:31:47 -07002266 std::string tags = std::string("addr=") + mMixAddress;
2267 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
2268 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002269 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, &mPortId, attr);
jiabinf4eb15a2019-08-28 15:31:47 -07002270 ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
2271 ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
2272
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002273 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
2274 mMixAddress, &mExtractionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002275}
2276
2277void AudioPolicyManagerTestDPMixRecordInjection::TearDown() {
2278 mManager->stopOutput(mPortId);
2279 AudioPolicyManagerTestDynamicPolicy::TearDown();
2280}
2281
jiabinf4eb15a2019-08-28 15:31:47 -07002282TEST_P(AudioPolicyManagerTestDPMixRecordInjection, RecordingInjection) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002283 const DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002284
jiabin7c0205e2019-09-05 10:26:04 -07002285 audio_port_handle_t captureRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07002286 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02002287 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2288 getInputForAttr(param.attributes, &input, param.session, mTracker->getRiid(),
2289 &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
2290 k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002291 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07002292 EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
2293 } else {
2294 EXPECT_NE(mExtractionPort.id, captureRoutedPortId);
2295 }
2296}
2297
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002298const std::vector<AudioMixMatchCriterion> SOURCE_CAM_MIC_VOICE_CRITERIA = {
2299 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
2300 createCapturePresetCriterion(AUDIO_SOURCE_MIC),
2301 createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
2302};
2303
jiabinf4eb15a2019-08-28 15:31:47 -07002304// No address priority rule for remote recording, address is a "don't care"
2305INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002306 RecordInjectionSource,
jiabinf4eb15a2019-08-28 15:31:47 -07002307 AudioPolicyManagerTestDPMixRecordInjection,
2308 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002309 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2310 .withSource(AUDIO_SOURCE_CAMCORDER),
2311 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2312 .withSource(AUDIO_SOURCE_CAMCORDER)
2313 .withTags("addr=remote_submix_media"),
2314 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2315 .withSource(AUDIO_SOURCE_MIC),
2316 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2317 .withSource(AUDIO_SOURCE_MIC)
2318 .withTags("addr=remote_submix_media"),
2319 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2320 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION),
2321 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2322 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION)
2323 .withTags("addr=remote_submix_media"),
2324 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2325 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION),
2326 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2327 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION)
2328 .withTags("addr=remote_submix_media"),
2329 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2330 .withSource(AUDIO_SOURCE_HOTWORD),
2331 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2332 .withSource(AUDIO_SOURCE_HOTWORD)
2333 .withTags("addr=remote_submix_media")));
jiabinf4eb15a2019-08-28 15:31:47 -07002334
jiabinf4eb15a2019-08-28 15:31:47 -07002335INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002336 RecordInjectionWithSessionId,
jiabinf4eb15a2019-08-28 15:31:47 -07002337 AudioPolicyManagerTestDPMixRecordInjection,
2338 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002339 // Mix is matched because the session id matches the one specified by the mix rule.
2340 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2341 /*expected_match=*/ true)
2342 .withSessionId(TEST_SESSION_ID),
2343 // Mix is not matched because the session id doesn't match the one specified
2344 // by the mix rule.
2345 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2346 /*expected_match=*/ false)
2347 .withSessionId(OTHER_SESSION_ID),
2348 // Mix is not matched, the session id doesn't match the one specified by rule,
2349 // but tand address specified in the tags is ignored for recorder mix.
2350 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2351 /*expected_match=*/ false)
2352 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2353 // Mix is matched, both the session id and the source match ones specified by mix rule
2354 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2355 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2356 /*expected_match=*/ true)
2357 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_CAMCORDER),
2358 // Mix is not matched, the session id matches the one specified by mix rule,
2359 // but source does not.
2360 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2361 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2362 /*expected_match=*/ false)
2363 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC),
2364 // Mix is not matched, the source matches the one specified by mix rule,
2365 // but the session id is excluded.
2366 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID,
2367 /*exclude=*/ true),
2368 createCapturePresetCriterion(AUDIO_SOURCE_MIC)},
2369 /*expected_match=*/ false)
2370 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC)));
jiabin43848a52019-09-05 14:07:25 -07002371
2372using DeviceConnectionTestParams =
2373 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/>;
2374
2375class AudioPolicyManagerTestDeviceConnection : public AudioPolicyManagerTestWithConfigurationFile,
2376 public testing::WithParamInterface<DeviceConnectionTestParams> {
2377};
2378
2379TEST_F(AudioPolicyManagerTestDeviceConnection, InitSuccess) {
2380 // SetUp must finish with no assertions.
2381}
2382
2383TEST_F(AudioPolicyManagerTestDeviceConnection, Dump) {
2384 dumpToLog();
2385}
2386
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002387TEST_F(AudioPolicyManagerTestDeviceConnection, RoutingUpdate) {
2388 mClient->resetRoutingUpdatedCounter();
2389 // Connecting a valid output device with valid parameters should trigger a routing update
2390 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2391 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002392 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002393 ASSERT_EQ(1, mClient->getRoutingUpdatedCounter());
2394
2395 // Disconnecting a connected device should succeed and trigger a routing update
2396 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2397 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002398 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002399 ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
2400
2401 // Disconnecting a disconnected device should fail and not trigger a routing update
2402 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2403 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
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(2, mClient->getRoutingUpdatedCounter());
2406
2407 // Changing force use should trigger an update
2408 auto config = mManager->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA);
2409 auto newConfig = config == AUDIO_POLICY_FORCE_BT_A2DP ?
2410 AUDIO_POLICY_FORCE_NONE : AUDIO_POLICY_FORCE_BT_A2DP;
2411 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, newConfig);
2412 ASSERT_EQ(3, mClient->getRoutingUpdatedCounter());
2413}
2414
jiabin43848a52019-09-05 14:07:25 -07002415TEST_P(AudioPolicyManagerTestDeviceConnection, SetDeviceConnectionState) {
2416 const audio_devices_t type = std::get<0>(GetParam());
2417 const std::string name = std::get<1>(GetParam());
2418 const std::string address = std::get<2>(GetParam());
2419
2420 if (type == AUDIO_DEVICE_OUT_HDMI) {
2421 // Set device connection state failed due to no device descriptor found
2422 // For HDMI case, it is easier to simulate device descriptor not found error
Mikhail Naganov83caee02021-10-05 15:52:01 -07002423 // by using an encoded format which isn't listed in the 'encodedFormats'
2424 // attribute for this devicePort.
jiabin43848a52019-09-05 14:07:25 -07002425 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2426 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2427 address.c_str(), name.c_str(), AUDIO_FORMAT_MAT_2_1));
2428 }
2429 // Connect with valid parameters should succeed
2430 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2431 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2432 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2433 // Try to connect with the same device again should fail
2434 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2435 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2436 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2437 // Disconnect the connected device should succeed
2438 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2439 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2440 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2441 // Disconnect device that is not connected should fail
2442 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2443 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2444 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2445 // Try to set device connection state with a invalid connection state should fail
2446 ASSERT_EQ(BAD_VALUE, mManager->setDeviceConnectionState(
2447 type, AUDIO_POLICY_DEVICE_STATE_CNT,
2448 "", "", AUDIO_FORMAT_DEFAULT));
2449}
2450
2451TEST_P(AudioPolicyManagerTestDeviceConnection, ExplicitlyRoutingAfterConnection) {
2452 const audio_devices_t type = std::get<0>(GetParam());
2453 const std::string name = std::get<1>(GetParam());
2454 const std::string address = std::get<2>(GetParam());
2455
2456 // Connect device to do explicitly routing test
2457 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2458 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2459 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2460
jiabin19cdba52020-11-24 11:28:58 -08002461 audio_port_v7 devicePort;
jiabin43848a52019-09-05 14:07:25 -07002462 const audio_port_role_t role = audio_is_output_device(type)
2463 ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002464 ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
jiabin43848a52019-09-05 14:07:25 -07002465
2466 audio_port_handle_t routedPortId = devicePort.id;
jiabin43848a52019-09-05 14:07:25 -07002467 // Try start input or output according to the device type
2468 if (audio_is_output_devices(type)) {
2469 getOutputForAttr(&routedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002470 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002471 } else if (audio_is_input_device(type)) {
2472 RecordingActivityTracker tracker;
François Gaffie6ebbce02023-07-19 13:27:53 +02002473 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2474 getInputForAttr({}, &input, AUDIO_SESSION_NONE, tracker.getRiid(), &routedPortId,
2475 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate,
2476 AUDIO_INPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002477 }
2478 ASSERT_EQ(devicePort.id, routedPortId);
2479
2480 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2481 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2482 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2483}
2484
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002485android::media::audio::common::ExtraAudioDescriptor make_ExtraAudioDescriptor(
2486 android::media::audio::common::AudioStandard audioStandard,
2487 android::media::audio::common::AudioEncapsulationType audioEncapsulationType) {
2488 android::media::audio::common::ExtraAudioDescriptor result;
2489 result.standard = audioStandard;
2490 result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
2491 result.encapsulationType = audioEncapsulationType;
2492 return result;
2493}
2494
2495TEST_P(AudioPolicyManagerTestDeviceConnection, PassingExtraAudioDescriptors) {
2496 const audio_devices_t type = std::get<0>(GetParam());
2497 if (!audio_device_is_digital(type)) {
2498 // EADs are used only for HDMI devices.
2499 GTEST_SKIP() << "Not a digital device type: " << audio_device_to_string(type);
2500 }
2501 const std::string name = std::get<1>(GetParam());
2502 const std::string address = std::get<2>(GetParam());
Atneya Nair638a6e42022-12-18 16:45:15 -08002503 android::media::AudioPortFw audioPort;
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002504 ASSERT_EQ(NO_ERROR,
2505 mManager->deviceToAudioPort(type, address.c_str(), name.c_str(), &audioPort));
2506 android::media::audio::common::AudioPort& port = audioPort.hal;
2507 port.extraAudioDescriptors.push_back(make_ExtraAudioDescriptor(
2508 android::media::audio::common::AudioStandard::EDID,
2509 android::media::audio::common::AudioEncapsulationType::IEC61937));
2510 const size_t lastConnectedDevicePortCount = mClient->getConnectedDevicePortCount();
2511 const size_t lastDisconnectedDevicePortCount = mClient->getDisconnectedDevicePortCount();
2512 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2513 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, port, AUDIO_FORMAT_DEFAULT));
2514 EXPECT_EQ(lastConnectedDevicePortCount + 1, mClient->getConnectedDevicePortCount());
2515 EXPECT_EQ(lastDisconnectedDevicePortCount, mClient->getDisconnectedDevicePortCount());
2516 const audio_port_v7* devicePort = mClient->getLastConnectedDevicePort();
2517 EXPECT_EQ(port.extraAudioDescriptors.size(), devicePort->num_extra_audio_descriptors);
2518 EXPECT_EQ(AUDIO_STANDARD_EDID, devicePort->extra_audio_descriptors[0].standard);
2519 EXPECT_EQ(AUDIO_ENCAPSULATION_TYPE_IEC61937,
2520 devicePort->extra_audio_descriptors[0].encapsulation_type);
2521 EXPECT_NE(0, devicePort->extra_audio_descriptors[0].descriptor[0]);
2522}
2523
jiabin43848a52019-09-05 14:07:25 -07002524INSTANTIATE_TEST_CASE_P(
2525 DeviceConnectionState,
2526 AudioPolicyManagerTestDeviceConnection,
2527 testing::Values(
2528 DeviceConnectionTestParams({AUDIO_DEVICE_IN_HDMI, "test_in_hdmi",
2529 "audio_policy_test_in_hdmi"}),
2530 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_HDMI, "test_out_hdmi",
2531 "audio_policy_test_out_hdmi"}),
2532 DeviceConnectionTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "bt_hfp_in",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002533 "00:11:22:33:44:55"}),
jiabin43848a52019-09-05 14:07:25 -07002534 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "bt_hfp_out",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002535 "00:11:22:33:44:55"})
jiabin43848a52019-09-05 14:07:25 -07002536 )
2537 );
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07002538
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002539namespace {
2540
2541class AudioPolicyManagerTestClientOpenFails : public AudioPolicyManagerTestClient {
2542 public:
2543 status_t openOutput(audio_module_handle_t module,
2544 audio_io_handle_t *output,
2545 audio_config_t * halConfig,
2546 audio_config_base_t * mixerConfig,
2547 const sp<DeviceDescriptorBase>& device,
2548 uint32_t * latencyMs,
Dean Wheatleydfb67b82024-01-23 09:36:29 +11002549 audio_output_flags_t *flags,
Haofan Wangb75aa6a2024-07-09 23:06:58 -07002550 audio_attributes_t attributes) override {
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002551 return mSimulateFailure ? BAD_VALUE :
2552 AudioPolicyManagerTestClient::openOutput(
Haofan Wangb75aa6a2024-07-09 23:06:58 -07002553 module, output, halConfig, mixerConfig, device, latencyMs, flags,
2554 attributes);
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002555 }
2556
2557 status_t openInput(audio_module_handle_t module,
2558 audio_io_handle_t *input,
2559 audio_config_t * config,
2560 audio_devices_t * device,
2561 const String8 & address,
2562 audio_source_t source,
2563 audio_input_flags_t flags) override {
2564 return mSimulateFailure ? BAD_VALUE :
2565 AudioPolicyManagerTestClient::openInput(
2566 module, input, config, device, address, source, flags);
2567 }
2568
2569 void setSimulateFailure(bool simulateFailure) { mSimulateFailure = simulateFailure; }
2570
Ping Tsai2a5a5242024-08-16 13:39:10 +08002571 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2572 if (status != NO_ERROR) {
2573 // simulate device connect status
2574 mSimulateBroadcastDeviceStatus[device] = status;
2575 } else {
2576 // remove device connection fixed status
2577 mSimulateBroadcastDeviceStatus.erase(device);
2578 }
2579 }
2580
2581 status_t setDeviceConnectedState(const struct audio_port_v7* port,
2582 media::DeviceConnectedState state) override {
2583 if (mSimulateBroadcastDeviceStatus.find(port->ext.device.type) !=
2584 mSimulateBroadcastDeviceStatus.end()) {
2585 // If a simulated status exists, return a status value
2586 return mSimulateBroadcastDeviceStatus[port->ext.device.type];
2587 }
2588 return AudioPolicyManagerTestClient::setDeviceConnectedState(port, state);
2589 }
2590
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002591 private:
2592 bool mSimulateFailure = false;
Ping Tsai2a5a5242024-08-16 13:39:10 +08002593 std::map<audio_devices_t, status_t> mSimulateBroadcastDeviceStatus;
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002594};
2595
2596} // namespace
2597
2598using DeviceConnectionWithFormatTestParams =
2599 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/,
2600 audio_format_t /*format*/>;
2601
2602class AudioPolicyManagerTestDeviceConnectionFailed :
2603 public AudioPolicyManagerTestWithConfigurationFile,
2604 public testing::WithParamInterface<DeviceConnectionWithFormatTestParams> {
2605 protected:
2606 std::string getConfigFile() override { return sBluetoothConfig; }
2607 AudioPolicyManagerTestClient* getClient() override {
2608 mFullClient = new AudioPolicyManagerTestClientOpenFails;
2609 return mFullClient;
2610 }
2611 void setSimulateOpenFailure(bool simulateFailure) {
2612 mFullClient->setSimulateFailure(simulateFailure); }
2613
Ping Tsai2a5a5242024-08-16 13:39:10 +08002614 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2615 mFullClient->setSimulateBroadcastDeviceStatus(device, status); }
2616
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002617 static const std::string sBluetoothConfig;
2618
2619 private:
2620 AudioPolicyManagerTestClientOpenFails* mFullClient;
2621};
2622
2623const std::string AudioPolicyManagerTestDeviceConnectionFailed::sBluetoothConfig =
2624 AudioPolicyManagerTestDeviceConnectionFailed::sExecutableDir +
2625 "test_audio_policy_configuration_bluetooth.xml";
2626
2627TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, SetDeviceConnectedStateHasAddress) {
2628 const audio_devices_t type = std::get<0>(GetParam());
2629 const std::string name = std::get<1>(GetParam());
2630 const std::string address = std::get<2>(GetParam());
2631 const audio_format_t format = std::get<3>(GetParam());
2632
2633 EXPECT_EQ(0, mClient->getConnectedDevicePortCount());
2634 EXPECT_EQ(0, mClient->getDisconnectedDevicePortCount());
2635
2636 setSimulateOpenFailure(true);
2637 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2638 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2639 address.c_str(), name.c_str(), format));
2640
2641 // Since the failure happens when opening input/output, the device must be connected
2642 // first and then disconnected.
2643 EXPECT_EQ(1, mClient->getConnectedDevicePortCount());
2644 EXPECT_EQ(1, mClient->getDisconnectedDevicePortCount());
2645
2646 if (mClient->getConnectedDevicePortCount() > 0) {
2647 auto port = mClient->getLastConnectedDevicePort();
2648 EXPECT_EQ(type, port->ext.device.type);
2649 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2650 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2651 }
2652 if (mClient->getDisconnectedDevicePortCount() > 0) {
2653 auto port = mClient->getLastDisconnectedDevicePort();
2654 EXPECT_EQ(type, port->ext.device.type);
2655 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2656 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2657 }
2658}
2659
Ping Tsai2a5a5242024-08-16 13:39:10 +08002660TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, BroadcastDeviceFailure) {
2661 const audio_devices_t type = std::get<0>(GetParam());
2662 const std::string name = std::get<1>(GetParam());
2663 const std::string address = std::get<2>(GetParam());
2664 const audio_format_t format = std::get<3>(GetParam());
2665
2666 // simulate broadcastDeviceConnectionState return failure
2667 setSimulateBroadcastDeviceStatus(type, INVALID_OPERATION);
2668 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2669 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2670 address.c_str(), name.c_str(), format));
2671
2672 // if broadcast is fail, device should not be added to available devices list
2673 if (audio_is_output_device(type)) {
2674 auto availableDevices = mManager->getAvailableOutputDevices();
2675 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2676 } else if (audio_is_input_device(type)) {
2677 auto availableDevices = mManager->getAvailableInputDevices();
2678 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2679 }
2680
2681 setSimulateBroadcastDeviceStatus(type, NO_ERROR);
2682}
2683
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002684INSTANTIATE_TEST_CASE_P(
2685 DeviceConnectionFailure,
2686 AudioPolicyManagerTestDeviceConnectionFailed,
2687 testing::Values(
2688 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
2689 "bt_hfp_in", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2690 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO,
2691 "bt_hfp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2692 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2693 "bt_a2dp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2694 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2695 "bt_a2dp_out", "00:11:22:33:44:66", AUDIO_FORMAT_LDAC})
2696 )
2697 );
2698
Dean Wheatleyd082f472022-02-04 11:10:48 +11002699class AudioPolicyManagerCarTest : public AudioPolicyManagerTestDynamicPolicy {
2700protected:
2701 std::string getConfigFile() override { return sCarConfig; }
2702
2703 static const std::string sCarConfig;
Oscar Azucena873d10f2023-01-12 18:34:42 -08002704 static const std::string sCarBusMediaOutput;
2705 static const std::string sCarBusNavigationOutput;
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002706 static const std::string sCarRearZoneOneOutput;
2707 static const std::string sCarRearZoneTwoOutput;
jiabin24ff57a2023-11-27 21:06:51 +00002708 static const std::string sCarBusMmapOutput;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002709};
2710
2711const std::string AudioPolicyManagerCarTest::sCarConfig =
2712 AudioPolicyManagerCarTest::sExecutableDir + "test_car_ap_atmos_offload_configuration.xml";
2713
Oscar Azucena873d10f2023-01-12 18:34:42 -08002714const std::string AudioPolicyManagerCarTest::sCarBusMediaOutput = "bus0_media_out";
2715
2716const std::string AudioPolicyManagerCarTest::sCarBusNavigationOutput = "bus1_navigation_out";
2717
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002718const std::string AudioPolicyManagerCarTest::sCarRearZoneOneOutput = "bus100_audio_zone_1";
2719
2720const std::string AudioPolicyManagerCarTest::sCarRearZoneTwoOutput = "bus200_audio_zone_2";
2721
jiabin24ff57a2023-11-27 21:06:51 +00002722const std::string AudioPolicyManagerCarTest::sCarBusMmapOutput = "bus8_mmap_out";
2723
Dean Wheatleyd082f472022-02-04 11:10:48 +11002724TEST_F(AudioPolicyManagerCarTest, InitSuccess) {
2725 // SetUp must finish with no assertions.
2726}
2727
2728TEST_F(AudioPolicyManagerCarTest, Dump) {
2729 dumpToLog();
2730}
2731
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002732TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAtmosOutputAfterRegisteringPolicyMix) {
Dean Wheatleyd082f472022-02-04 11:10:48 +11002733 status_t ret;
2734 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002735 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Oscar Azucena873d10f2023-01-12 18:34:42 -08002736 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig);
Dean Wheatleyd082f472022-02-04 11:10:48 +11002737 ASSERT_EQ(NO_ERROR, ret);
2738
2739 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2740 audio_io_handle_t output;
2741 audio_port_handle_t portId;
2742 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_E_AC3_JOC, AUDIO_CHANNEL_OUT_5POINT1,
2743 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2744 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2745 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
2746 ASSERT_NE(nullptr, outDesc.get());
2747 ASSERT_EQ(AUDIO_FORMAT_E_AC3_JOC, outDesc->getFormat());
2748 ASSERT_EQ(AUDIO_CHANNEL_OUT_5POINT1, outDesc->getChannelMask());
2749 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002750
2751 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2752 output = AUDIO_IO_HANDLE_NONE;
2753 portId = AUDIO_PORT_HANDLE_NONE;
2754 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
2755 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2756 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2757 outDesc = mManager->getOutputs().valueFor(output);
2758 ASSERT_NE(nullptr, outDesc.get());
2759 ASSERT_EQ(AUDIO_FORMAT_PCM_16_BIT, outDesc->getFormat());
2760 ASSERT_EQ(AUDIO_CHANNEL_OUT_7POINT1POINT4, outDesc->getChannelMask());
2761 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyd082f472022-02-04 11:10:48 +11002762}
2763
Oscar Azucena873d10f2023-01-12 18:34:42 -08002764TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAfterRegisteringPolicyMix) {
2765 status_t ret;
2766 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2767 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2768 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2769 audioConfig.sample_rate = k48000SamplingRate;
2770 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2771 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2772 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2773 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2774 ASSERT_EQ(NO_ERROR, ret);
2775 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2776 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2777 /*exclude=*/ false)};
2778 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2779 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2780 ASSERT_EQ(NO_ERROR, ret);
2781 audio_port_v7 mediaDevicePort;
2782 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2783 sCarBusMediaOutput, &mediaDevicePort));
2784 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2785 audio_io_handle_t output;
2786 audio_port_handle_t portId;
2787 const audio_attributes_t mediaAttribute = {
2788 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2789 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2790
2791 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2792 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2793
2794 ASSERT_EQ(mediaDevicePort.id, selectedDeviceId);
2795}
2796
2797TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterRegisteringPolicyMix) {
2798 status_t ret;
2799 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2800 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2801 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2802 audioConfig.sample_rate = k48000SamplingRate;
2803 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2804 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2805 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2806 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2807 ASSERT_EQ(NO_ERROR, ret);
2808 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2809 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2810 /*exclude=*/ false)};
2811 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2812 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2813 ASSERT_EQ(NO_ERROR, ret);
2814 audio_port_v7 navDevicePort;
2815 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2816 sCarBusNavigationOutput, &navDevicePort));
2817 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2818 audio_io_handle_t output;
2819 audio_port_handle_t portId;
2820 const audio_attributes_t mediaAttribute = {
2821 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2822 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2823
2824 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2825 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2826
2827 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2828}
2829
2830TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterUserAffinities) {
2831 status_t ret;
2832 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2833 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2834 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2835 audioConfig.sample_rate = k48000SamplingRate;
2836 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2837 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2838 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2839 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2840 ASSERT_EQ(NO_ERROR, ret);
2841 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2842 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2843 /*exclude=*/ false)};
2844 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2845 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2846 ASSERT_EQ(NO_ERROR, ret);
2847 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2848 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002849 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002850 audio_port_v7 navDevicePort;
2851 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2852 sCarBusNavigationOutput, &navDevicePort));
2853 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2854 audio_io_handle_t output;
2855 audio_port_handle_t portId;
2856 const audio_attributes_t mediaAttribute = {
2857 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2858 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2859
2860 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2861 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2862
2863 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2864}
2865
2866TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithExcludeUserIdCriteria) {
2867 status_t ret;
2868 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2869 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2870 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2871 audioConfig.sample_rate = k48000SamplingRate;
2872 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2873 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2874 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2875 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2876 ASSERT_EQ(NO_ERROR, ret);
2877 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2878 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2879 /*exclude=*/ false),
2880 createUserIdCriterion(/* userId */ 0, /* exclude */ true)};
2881 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2882 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2883 ASSERT_EQ(NO_ERROR, ret);
2884 audio_port_v7 navDevicePort;
2885 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2886 sCarBusNavigationOutput, &navDevicePort));
2887 audio_io_handle_t output;
2888 audio_port_handle_t portId;
2889 const audio_attributes_t navigationAttribute = {
2890 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2891 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2892 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2893
2894 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2895 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, navigationAttribute);
2896
2897 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2898}
2899
2900TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputExcludeUserIdCriteria) {
2901 status_t ret;
2902 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2903 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2904 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2905 audioConfig.sample_rate = k48000SamplingRate;
2906 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2907 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2908 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2909 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2910 ASSERT_EQ(NO_ERROR, ret);
2911 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2912 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2913 /*exclude=*/ false),
2914 createUserIdCriterion(0 /* userId */, /* exclude */ true)};
2915 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2916 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2917 ASSERT_EQ(NO_ERROR, ret);
2918 audio_port_v7 navDevicePort;
2919 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2920 sCarBusNavigationOutput, &navDevicePort));
2921 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2922 audio_io_handle_t output;
2923 audio_port_handle_t portId;
2924 const audio_attributes_t mediaAttribute = {
2925 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2926 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2927
2928 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2929 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2930
2931 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2932}
2933
2934TEST_F(AudioPolicyManagerCarTest,
2935 GetOutputForAttrWithMatchingMixAndSelectedOutputAfterUserAffinities) {
2936 status_t ret;
2937 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2938 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2939 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2940 audioConfig.sample_rate = k48000SamplingRate;
2941 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2942 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2943 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2944 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2945 ASSERT_EQ(NO_ERROR, ret);
2946 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2947 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2948 /*exclude=*/ false)};
2949 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2950 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2951 ASSERT_EQ(NO_ERROR, ret);
2952 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2953 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
2954 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002955 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002956 audio_port_v7 navDevicePort;
2957 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2958 sCarBusNavigationOutput, &navDevicePort));
2959 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2960 audio_io_handle_t output;
2961 audio_port_handle_t portId;
2962 const audio_attributes_t mediaAttribute = {
2963 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2964 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2965
2966 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2967 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2968
2969 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2970}
2971
2972TEST_F(AudioPolicyManagerCarTest,
2973 GetOutputForAttrWithNoMatchingMaxAndSelectedOutputAfterUserAffinities) {
2974 status_t ret;
2975 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2976 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2977 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2978 audioConfig.sample_rate = k48000SamplingRate;
2979 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2980 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2981 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2982 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2983 ASSERT_EQ(NO_ERROR, ret);
2984 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2985 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2986 /*exclude=*/ false)};
2987 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2988 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2989 ASSERT_EQ(NO_ERROR, ret);
2990 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2991 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
2992 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002993 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002994 audio_port_v7 navDevicePort;
2995 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2996 sCarBusNavigationOutput, &navDevicePort));
2997 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2998 audio_io_handle_t output;
2999 audio_port_handle_t portId;
3000 const audio_attributes_t alarmAttribute = {
3001 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3002 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3003
3004 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3005 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3006
3007 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3008}
3009
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003010TEST_F(AudioPolicyManagerCarTest,
3011 GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
3012 status_t ret;
3013 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3014 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3015 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3016 audioConfig.sample_rate = k48000SamplingRate;
3017 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3018 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3019 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3020 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3021 ASSERT_EQ(NO_ERROR, ret);
3022 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3023 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3024 ASSERT_EQ(NO_ERROR, ret);
3025 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3026 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3027 ASSERT_EQ(NO_ERROR, ret);
3028 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3029 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3030 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3031 audio_port_v7 primaryZoneDevicePort;
3032 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3033 sCarBusMediaOutput, &primaryZoneDevicePort));
3034 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3035 audio_io_handle_t output;
3036 audio_port_handle_t portId;
3037 const audio_attributes_t mediaAttribute = {
3038 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3039 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3040 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3041
3042 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3043 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3044 AUDIO_SESSION_NONE, user11AppUid);
3045
3046 ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceId);
3047}
3048
3049TEST_F(AudioPolicyManagerCarTest,
3050 GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
3051 status_t ret;
3052 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3053 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3054 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3055 audioConfig.sample_rate = k48000SamplingRate;
3056 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3057 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3058 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3059 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3060 ASSERT_EQ(NO_ERROR, ret);
3061 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3062 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3063 ASSERT_EQ(NO_ERROR, ret);
3064 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3065 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3066 ASSERT_EQ(NO_ERROR, ret);
3067 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3068 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3069 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3070 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3071 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3072 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3073 audio_port_v7 secondaryZoneDevicePort;
3074 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3075 sCarRearZoneOneOutput, &secondaryZoneDevicePort));
3076 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3077 audio_io_handle_t output;
3078 audio_port_handle_t portId;
3079 const audio_attributes_t mediaAttribute = {
3080 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3081 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3082 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3083
3084 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3085 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3086 AUDIO_SESSION_NONE, user11AppUid);
3087
3088 ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceId);
3089}
3090
3091TEST_F(AudioPolicyManagerCarTest,
3092 GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
3093 status_t ret;
3094 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3095 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3096 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3097 audioConfig.sample_rate = k48000SamplingRate;
3098 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3099 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3100 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3101 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3102 ASSERT_EQ(NO_ERROR, ret);
3103 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3104 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3105 ASSERT_EQ(NO_ERROR, ret);
3106 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3107 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3108 ASSERT_EQ(NO_ERROR, ret);
3109 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3110 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3111 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3112 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3113 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3114 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3115 const AudioDeviceTypeAddr tertiaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput);
3116 const AudioDeviceTypeAddrVector tertiaryZoneDevices = {tertiaryOutputDevice};
3117 mManager->setUserIdDeviceAffinities(/* userId */ 15, tertiaryZoneDevices);
3118 audio_port_v7 tertiaryZoneDevicePort;
3119 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3120 sCarRearZoneTwoOutput, &tertiaryZoneDevicePort));
3121 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3122 audio_io_handle_t output;
3123 audio_port_handle_t portId;
3124 const audio_attributes_t mediaAttribute = {
3125 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3126 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3127 uid_t user15AppUid = multiuser_get_uid(/* user_id */ 15, /* app_id */ 12345);
3128
3129 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3130 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3131 AUDIO_SESSION_NONE, user15AppUid);
3132
3133 ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceId);
3134}
3135
Oscar Azucena873d10f2023-01-12 18:34:42 -08003136TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithNoMatchingMix) {
3137 status_t ret;
3138 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3139 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3140 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3141 audioConfig.sample_rate = k48000SamplingRate;
3142 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3143 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3144 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3145 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3146 ASSERT_EQ(NO_ERROR, ret);
3147 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
3148 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
3149 /*exclude=*/ false)};
3150 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3151 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
3152 ASSERT_EQ(NO_ERROR, ret);
3153 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3154 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
3155 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003156 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08003157 audio_port_v7 navDevicePort;
3158 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3159 sCarBusNavigationOutput, &navDevicePort));
3160 audio_port_handle_t selectedDeviceId = navDevicePort.id;
3161 audio_io_handle_t output;
3162 audio_port_handle_t portId;
3163 const audio_attributes_t alarmAttribute = {
3164 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3165 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3166
3167 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3168 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3169
3170 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3171}
3172
jiabin24ff57a2023-11-27 21:06:51 +00003173TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrForMMapWithPolicyMatched) {
3174 status_t ret;
3175 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3176 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3177 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3178 audioConfig.sample_rate = k48000SamplingRate;
3179 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3180 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3181 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3182 AUDIO_DEVICE_OUT_BUS, sCarBusMmapOutput, audioConfig, mediaMatchCriteria);
3183 ASSERT_EQ(NO_ERROR, ret);
3184 ASSERT_EQ(NO_ERROR, ret);
3185 audio_port_v7 mmapDevicePort;
3186 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3187 sCarBusMmapOutput, &mmapDevicePort));
3188 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3189 audio_io_handle_t output;
3190 audio_port_handle_t portId;
3191 const audio_attributes_t mediaAttribute = {
3192 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3193 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3194
3195 getOutputForAttr(
3196 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3197 k48000SamplingRate,
3198 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT),
3199 &output, &portId, mediaAttribute);
3200
3201 ASSERT_EQ(mmapDevicePort.id, selectedDeviceId);
3202}
3203
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003204class AudioPolicyManagerTVTest : public AudioPolicyManagerTestWithConfigurationFile {
3205protected:
3206 std::string getConfigFile() override { return sTvConfig; }
3207 void testHDMIPortSelection(audio_output_flags_t flags, const char* expectedMixPortName);
3208
3209 static const std::string sTvConfig;
3210};
3211
3212const std::string AudioPolicyManagerTVTest::sTvConfig =
3213 AudioPolicyManagerTVTest::sExecutableDir + "test_tv_apm_configuration.xml";
3214
3215// SwAudioOutputDescriptor doesn't populate flags so check against the port name.
3216void AudioPolicyManagerTVTest::testHDMIPortSelection(
3217 audio_output_flags_t flags, const char* expectedMixPortName) {
3218 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3219 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3220 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3221 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3222 audio_io_handle_t output;
3223 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +11003224 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3225 k48000SamplingRate, flags, &output, &portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003226 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3227 ASSERT_NE(nullptr, outDesc.get());
jiabin19cdba52020-11-24 11:28:58 -08003228 audio_port_v7 port = {};
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003229 outDesc->toAudioPort(&port);
3230 mManager->releaseOutput(portId);
3231 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3232 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3233 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3234 ASSERT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3235 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3236 ASSERT_STREQ(expectedMixPortName, port.name);
3237}
3238
3239TEST_F(AudioPolicyManagerTVTest, InitSuccess) {
3240 // SetUp must finish with no assertions.
3241}
3242
3243TEST_F(AudioPolicyManagerTVTest, Dump) {
3244 dumpToLog();
3245}
3246
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003247TEST_F(AudioPolicyManagerTVTest, MatchNoFlags) {
3248 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_NONE, "primary output");
3249}
3250
3251TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectNoHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003252 // b/140447125: The selected port must not have HW AV Sync flag (see the config file).
3253 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_DIRECT, "direct");
3254}
3255
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003256TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003257 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3258 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
3259 "tunnel");
3260}
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003261
3262TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectMMapNoIrq) {
3263 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3264 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3265 "low latency");
3266}
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003267
Mikhail Naganov285c1732024-09-05 17:26:50 -07003268class AudioPolicyManagerPhoneTest : public AudioPolicyManagerTestWithConfigurationFile {
3269protected:
3270 std::string getConfigFile() override { return sPhoneConfig; }
3271 void testOutputMixPortSelectionForAttr(audio_output_flags_t flags, audio_format_t format,
3272 int samplingRate, bool isMusic, const char* expectedMixPortName);
3273 void testOutputMixPortSelectionForStream(
3274 audio_stream_type_t stream, const char* expectedMixPortName);
3275 void verifyMixPortNameAndFlags(audio_io_handle_t output, const char* expectedMixPortName);
3276
3277 static const std::string sPhoneConfig;
3278 static const std::map<std::string, audio_output_flags_t> sMixPortFlags;
3279};
3280
3281const std::string AudioPolicyManagerPhoneTest::sPhoneConfig =
3282 AudioPolicyManagerPhoneTest::sExecutableDir + "test_phone_apm_configuration.xml";
3283
3284// Must be in sync with the contents of the sPhoneConfig file.
3285const std::map<std::string, audio_output_flags_t> AudioPolicyManagerPhoneTest::sMixPortFlags = {
3286 {"primary output",
3287 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_FAST)},
3288 {"direct", AUDIO_OUTPUT_FLAG_DIRECT},
3289 {"deep buffer", AUDIO_OUTPUT_FLAG_DEEP_BUFFER},
3290 {"compressed_offload",
3291 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3292 AUDIO_OUTPUT_FLAG_NON_BLOCKING |
3293 AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD)},
3294 {"raw", (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_FAST)},
3295 {"mmap_no_irq_out",
3296 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)},
3297 {"voip_rx", AUDIO_OUTPUT_FLAG_VOIP_RX},
3298};
3299
3300void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForAttr(
3301 audio_output_flags_t flags, audio_format_t format, int samplingRate, bool isMusic,
3302 const char* expectedMixPortName) {
3303 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3304 audio_io_handle_t output;
3305 audio_port_handle_t portId;
3306 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3307 if (isMusic) {
3308 attr.content_type = AUDIO_CONTENT_TYPE_MUSIC;
3309 attr.usage = AUDIO_USAGE_MEDIA;
3310 }
3311 getOutputForAttr(&selectedDeviceId, format, AUDIO_CHANNEL_OUT_STEREO, samplingRate, flags,
3312 &output, &portId, attr);
3313 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3314 mManager->releaseOutput(portId);
3315}
3316
3317void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForStream(
3318 audio_stream_type_t stream, const char* expectedMixPortName) {
3319 audio_io_handle_t output = mManager->getOutput(stream);
3320 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3321}
3322
3323void AudioPolicyManagerPhoneTest::verifyMixPortNameAndFlags(audio_io_handle_t output,
3324 const char* expectedMixPortName) {
3325 ALOGI("%s: checking output %d", __func__, output);
3326 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3327 ASSERT_NE(nullptr, outDesc.get());
3328 audio_port_v7 port = {};
3329 outDesc->toAudioPort(&port);
3330 EXPECT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3331 EXPECT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3332 ASSERT_STREQ(expectedMixPortName, port.name);
3333
3334 auto iter = sMixPortFlags.find(port.name);
3335 ASSERT_NE(iter, sMixPortFlags.end()) << "\"" << port.name << "\" is not in sMixPortFlags";
3336 auto actualFlags = mClient->getOpenOutputFlags(output);
3337 ASSERT_TRUE(actualFlags.has_value()) << "\"" << port.name << "\" was not opened via client";
3338 EXPECT_EQ(*actualFlags, iter->second);
3339}
3340
3341TEST_F(AudioPolicyManagerPhoneTest, InitSuccess) {
3342 // SetUp must finish with no assertions.
3343}
3344
3345enum {
3346 MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER,
3347 MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3348 MIX_PORT_ATTR_FLAGS_PARAMETER,
3349 MIX_PORT_ATTR_FORMAT_PARAMETER,
3350 MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER,
3351};
3352using MixPortSelectionForAttr =
3353 std::tuple<const char*, const char*, audio_output_flags_t, audio_format_t, int>;
3354
3355class AudioPolicyManagerOutputMixPortForAttrSelectionTest
3356 : public AudioPolicyManagerPhoneTest,
3357 public testing::WithParamInterface<MixPortSelectionForAttr> {
3358};
3359
3360// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3361// Instead, just run the same selection twice while altering the deep buffer for media setting.
3362TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags) {
3363 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3364 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3365 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3366 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3367 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3368 false /*isMusic*/,
3369 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3370}
3371TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_Music) {
3372 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3373 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3374 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3375 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3376 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3377 true /*isMusic*/,
3378 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3379}
3380TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia) {
3381 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3382 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3383 ASSERT_NO_FATAL_FAILURE(
3384 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3385 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3386 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3387 false /*isMusic*/,
3388 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3389 GetParam()) ?: fallbackName));
3390}
3391TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia_Music) {
3392 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3393 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3394 ASSERT_NO_FATAL_FAILURE(
3395 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3396 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3397 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3398 true /*isMusic*/,
3399 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3400 GetParam()) ?: fallbackName));
3401}
3402
3403INSTANTIATE_TEST_CASE_P(AudioPolicyManagerOutputMixPortForAttrSelection,
3404 AudioPolicyManagerOutputMixPortForAttrSelectionTest,
3405 ::testing::Values(
3406 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3407 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3408 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3409 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3410 // Note: this goes to "direct" because 384000 > SAMPLE_RATE_HZ_MAX (192000)
3411 std::make_tuple("direct", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3412 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3413 std::make_tuple("primary output", nullptr, AUDIO_OUTPUT_FLAG_FAST,
3414 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3415 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3416 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k96000SamplingRate),
3417 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3418 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3419 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3420 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3421 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3422 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3423 std::make_tuple("compressed_offload", nullptr,
3424 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3425 AUDIO_OUTPUT_FLAG_NON_BLOCKING),
3426 AUDIO_FORMAT_MP3, AudioPolicyManagerTest::k48000SamplingRate),
3427 std::make_tuple("raw", nullptr,
3428 AUDIO_OUTPUT_FLAG_RAW, AUDIO_FORMAT_PCM_32_BIT,
3429 AudioPolicyManagerTest::k48000SamplingRate),
3430 std::make_tuple("mmap_no_irq_out", nullptr,
3431 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3432 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3433 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3434 std::make_tuple("mmap_no_irq_out", nullptr,
3435 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3436 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3437 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3438 std::make_tuple("voip_rx", nullptr, AUDIO_OUTPUT_FLAG_VOIP_RX,
3439 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate)),
3440 [](const ::testing::TestParamInfo<MixPortSelectionForAttr>& info) {
3441 static const std::string flagPrefix = "AUDIO_OUTPUT_FLAG_";
3442 static const std::string formatPrefix = "AUDIO_FORMAT_";
3443 std::string flags;
3444 TypeConverter<OutputFlagTraits>::maskToString(
3445 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(info.param), flags, "__");
3446 size_t index = 0;
3447 while (true) {
3448 index = flags.rfind(flagPrefix);
3449 if (index == std::string::npos) break;
3450 flags.erase(index, flagPrefix.length());
3451 }
3452 std::string format;
3453 TypeConverter<FormatTraits>::toString(
3454 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(info.param), format);
3455 if (size_t index = format.find(formatPrefix); index != std::string::npos) {
3456 format.erase(index, formatPrefix.length());
3457 }
3458 return flags + "__" + format + "__" +
3459 std::to_string(std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(info.param));
3460 }
3461);
3462
3463
3464enum {
3465 MIX_PORT_STRM_EXPECTED_NAME_PARAMETER,
3466 MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3467 MIX_PORT_STRM_STREAM_PARAMETER,
3468};
3469using MixPortSelectionForStream =
3470 std::tuple<const char*, const char*, audio_stream_type_t>;
3471
3472class AudioPolicyManagerOutputMixPortForStreamSelectionTest
3473 : public AudioPolicyManagerPhoneTest,
3474 public testing::WithParamInterface<MixPortSelectionForStream> {
3475};
3476
3477// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3478// Instead, just run the same selection twice while altering the deep buffer for media setting.
3479TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_NoDBFM) {
3480 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3481 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3482 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3483 std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam())));
3484}
3485TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_WithDBFM) {
3486 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3487 const char* fallbackName = std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam());
3488 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3489 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3490 std::get<MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3491 GetParam()) ?: fallbackName));
3492}
3493
3494INSTANTIATE_TEST_CASE_P(
3495 AudioPolicyManagerOutputMixPortForStreamSelection,
3496 AudioPolicyManagerOutputMixPortForStreamSelectionTest,
3497 ::testing::Values(std::make_tuple("primary output", nullptr, AUDIO_STREAM_DEFAULT),
3498 std::make_tuple("primary output", nullptr, AUDIO_STREAM_SYSTEM),
3499 std::make_tuple("primary output", nullptr, AUDIO_STREAM_RING),
3500 std::make_tuple("primary output", "deep buffer", AUDIO_STREAM_MUSIC),
3501 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ALARM),
3502 std::make_tuple("primary output", nullptr, AUDIO_STREAM_NOTIFICATION),
3503 std::make_tuple("primary output", nullptr, AUDIO_STREAM_BLUETOOTH_SCO),
3504 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ENFORCED_AUDIBLE),
3505 std::make_tuple("primary output", nullptr, AUDIO_STREAM_DTMF),
3506 std::make_tuple("primary output", nullptr, AUDIO_STREAM_TTS),
3507 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ACCESSIBILITY),
3508 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ASSISTANT)),
3509 [](const ::testing::TestParamInfo<MixPortSelectionForStream>& info) {
3510 static const std::string streamPrefix = "AUDIO_STREAM_";
3511 std::string stream;
3512 TypeConverter<StreamTraits>::toString(
3513 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(info.param), stream);
3514 if (size_t index = stream.find(streamPrefix); index != std::string::npos) {
3515 stream.erase(index, streamPrefix.length());
3516 }
3517 return stream;
3518 }
3519);
3520
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003521class AudioPolicyManagerDynamicHwModulesTest : public AudioPolicyManagerTestWithConfigurationFile {
3522protected:
3523 void SetUpManagerConfig() override;
3524};
3525
3526void AudioPolicyManagerDynamicHwModulesTest::SetUpManagerConfig() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07003527 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig());
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003528 // Only allow successful opening of "primary" hw module during APM initialization.
3529 mClient->swapAllowedModuleNames({"primary"});
3530}
3531
3532TEST_F(AudioPolicyManagerDynamicHwModulesTest, InitSuccess) {
3533 // SetUp must finish with no assertions.
3534}
3535
3536TEST_F(AudioPolicyManagerDynamicHwModulesTest, DynamicAddition) {
3537 const auto handleBefore = mClient->peekNextModuleHandle();
3538 mManager->onNewAudioModulesAvailable();
3539 ASSERT_EQ(handleBefore, mClient->peekNextModuleHandle());
3540 // Reset module loading restrictions.
3541 mClient->swapAllowedModuleNames();
3542 mManager->onNewAudioModulesAvailable();
3543 const auto handleAfter = mClient->peekNextModuleHandle();
3544 ASSERT_GT(handleAfter, handleBefore);
3545 mManager->onNewAudioModulesAvailable();
3546 ASSERT_EQ(handleAfter, mClient->peekNextModuleHandle());
3547}
3548
3549TEST_F(AudioPolicyManagerDynamicHwModulesTest, AddedDeviceAvailable) {
3550 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, mManager->getDeviceConnectionState(
3551 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3552 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3553 mManager->onNewAudioModulesAvailable();
3554 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE, mManager->getDeviceConnectionState(
3555 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3556}
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003557
3558TEST_F(AudioPolicyManagerDynamicHwModulesTest, ListAddedAudioPorts) {
3559 ASSERT_FALSE(
3560 findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
3561 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3562 mManager->onNewAudioModulesAvailable();
jiabin19cdba52020-11-24 11:28:58 -08003563 struct audio_port_v7 port;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003564 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
3565}
3566
3567TEST_F(AudioPolicyManagerDynamicHwModulesTest, ClientIsUpdated) {
3568 const size_t prevAudioPortListUpdateCount = mClient->getAudioPortListUpdateCount();
3569 const uint32_t prevAudioPortGeneration = mManager->getAudioPortGeneration();
3570 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3571 mManager->onNewAudioModulesAvailable();
3572 EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
3573 EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
3574}
Jiabin Huang3b98d322020-09-03 17:54:16 +00003575
3576using DevicesRoleForCapturePresetParam = std::tuple<audio_source_t, device_role_t>;
3577
3578class AudioPolicyManagerDevicesRoleForCapturePresetTest
3579 : public AudioPolicyManagerTestWithConfigurationFile,
3580 public testing::WithParamInterface<DevicesRoleForCapturePresetParam> {
3581protected:
3582 // The `inputDevice` and `inputDevice2` indicate the audio devices type to be used for setting
3583 // device role. They must be declared in the test_audio_policy_configuration.xml
3584 AudioDeviceTypeAddr inputDevice = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
3585 AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_HDMI, "");
3586};
3587
3588TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCapturePreset) {
3589 const audio_source_t audioSource = std::get<0>(GetParam());
3590 const device_role_t role = std::get<1>(GetParam());
3591
3592 // Test invalid device when setting
3593 const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
3594 const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
3595 ASSERT_EQ(BAD_VALUE,
3596 mManager->setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3597 ASSERT_EQ(BAD_VALUE,
3598 mManager->addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3599 AudioDeviceTypeAddrVector devices;
3600 ASSERT_EQ(NAME_NOT_FOUND,
3601 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3602 ASSERT_TRUE(devices.empty());
3603 ASSERT_EQ(BAD_VALUE,
3604 mManager->removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3605
3606 // Without setting, call get/remove/clear must fail
3607 ASSERT_EQ(NAME_NOT_FOUND,
3608 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3609 ASSERT_EQ(NAME_NOT_FOUND,
3610 mManager->removeDevicesRoleForCapturePreset(audioSource, role, devices));
3611 ASSERT_EQ(NAME_NOT_FOUND,
3612 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3613
3614 // Test set/get devices role
3615 const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
3616 ASSERT_EQ(NO_ERROR,
3617 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3618 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3619 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice));
3620
3621 // Test setting will change the previously set devices
3622 const AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
3623 ASSERT_EQ(NO_ERROR,
3624 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
3625 devices.clear();
3626 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3627 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3628
3629 // Test add devices
3630 ASSERT_EQ(NO_ERROR,
3631 mManager->addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3632 devices.clear();
3633 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3634 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice, inputDevice2));
3635
3636 // Test remove devices
3637 ASSERT_EQ(NO_ERROR,
3638 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3639 devices.clear();
3640 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3641 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3642
3643 // Test remove devices that are not set as the device role
3644 ASSERT_EQ(BAD_VALUE,
3645 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3646
3647 // Test clear devices
3648 ASSERT_EQ(NO_ERROR,
3649 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3650 devices.clear();
3651 ASSERT_EQ(NAME_NOT_FOUND,
3652 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3653}
3654
jiabin14662b52023-03-06 21:35:29 +00003655TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) {
3656 const audio_source_t source = AUDIO_SOURCE_MIC;
3657 const device_role_t role = DEVICE_ROLE_PREFERRED;
3658 const std::string address = "card=1;device=0";
3659 const std::string deviceName = "randomName";
3660
3661 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3662 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3663 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3664 auto availableDevices = mManager->getAvailableInputDevices();
3665 ASSERT_GT(availableDevices.size(), 1);
3666
3667 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3668 attr.source = source;
3669 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003670 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3671 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003672 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003673 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003674 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3675 ASSERT_NE(nullptr, selectedDevice);
3676
3677 sp<DeviceDescriptor> preferredDevice = nullptr;
3678 for (const auto& device : availableDevices) {
3679 if (device != selectedDevice) {
3680 preferredDevice = device;
3681 break;
3682 }
3683 }
3684 ASSERT_NE(nullptr, preferredDevice);
3685 // After setting preferred device for capture preset, the selected device for input should be
3686 // the preferred device.
3687 ASSERT_EQ(NO_ERROR,
3688 mManager->setDevicesRoleForCapturePreset(source, role,
3689 {preferredDevice->getDeviceTypeAddr()}));
3690 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003691 input = AUDIO_PORT_HANDLE_NONE;
3692 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003693 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003694 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003695 ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3696
3697 // After clearing preferred device for capture preset, the selected device for input should be
3698 // the same as original one.
3699 ASSERT_EQ(NO_ERROR,
3700 mManager->clearDevicesRoleForCapturePreset(source, role));
3701 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003702 input = AUDIO_PORT_HANDLE_NONE;
3703 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003704 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003705 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003706 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3707
3708 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3709 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3710 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3711}
3712
3713TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) {
3714 const audio_source_t source = AUDIO_SOURCE_MIC;
3715 const device_role_t role = DEVICE_ROLE_DISABLED;
3716 const std::string address = "card=1;device=0";
3717 const std::string deviceName = "randomName";
3718
3719 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3720 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3721 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3722 auto availableDevices = mManager->getAvailableInputDevices();
3723 ASSERT_GT(availableDevices.size(), 1);
3724
3725 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3726 attr.source = source;
3727 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003728 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3729 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003730 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003731 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003732 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3733 ASSERT_NE(nullptr, selectedDevice);
3734
3735 // After setting disabled device for capture preset, the disabled device must not be
3736 // selected for input.
3737 ASSERT_EQ(NO_ERROR,
3738 mManager->setDevicesRoleForCapturePreset(source, role,
3739 {selectedDevice->getDeviceTypeAddr()}));
3740 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003741 input = AUDIO_PORT_HANDLE_NONE;
3742 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
3743 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003744 AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003745 ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3746
3747 // After clearing disabled device for capture preset, the selected device for input should be
3748 // the original one.
3749 ASSERT_EQ(NO_ERROR,
3750 mManager->clearDevicesRoleForCapturePreset(source, role));
3751 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003752 input = AUDIO_PORT_HANDLE_NONE;
3753 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003754 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003755 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003756 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3757
3758 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3759 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3760 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3761}
3762
Jiabin Huang3b98d322020-09-03 17:54:16 +00003763INSTANTIATE_TEST_CASE_P(
3764 DevicesRoleForCapturePresetOperation,
3765 AudioPolicyManagerDevicesRoleForCapturePresetTest,
3766 testing::Values(
3767 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_MIC, DEVICE_ROLE_PREFERRED}),
3768 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_UPLINK,
3769 DEVICE_ROLE_PREFERRED}),
3770 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_DOWNLINK,
3771 DEVICE_ROLE_PREFERRED}),
3772 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_CALL, DEVICE_ROLE_PREFERRED}),
3773 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_CAMCORDER, DEVICE_ROLE_PREFERRED}),
3774 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_RECOGNITION,
3775 DEVICE_ROLE_PREFERRED}),
3776 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_COMMUNICATION,
3777 DEVICE_ROLE_PREFERRED}),
3778 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_REMOTE_SUBMIX,
3779 DEVICE_ROLE_PREFERRED}),
3780 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_UNPROCESSED, DEVICE_ROLE_PREFERRED}),
3781 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_PERFORMANCE,
3782 DEVICE_ROLE_PREFERRED}),
3783 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_ECHO_REFERENCE,
3784 DEVICE_ROLE_PREFERRED}),
3785 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_FM_TUNER, DEVICE_ROLE_PREFERRED}),
3786 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_HOTWORD, DEVICE_ROLE_PREFERRED})
3787 )
3788 );
François Gaffie6ebbce02023-07-19 13:27:53 +02003789
3790
3791const effect_descriptor_t TEST_EFFECT_DESC = {
3792 {0xf2a4bb20, 0x0c3c, 0x11e3, 0x8b07, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
3793 {0xff93e360, 0x0c3c, 0x11e3, 0x8a97, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
3794 EFFECT_CONTROL_API_VERSION,
3795 EFFECT_FLAG_TYPE_PRE_PROC,
3796 0,
3797 1,
3798 "APM test Effect",
3799 "The Android Open Source Project",
3800};
3801
3802class AudioPolicyManagerPreProcEffectTest : public AudioPolicyManagerTestWithConfigurationFile {
3803};
3804
3805TEST_F(AudioPolicyManagerPreProcEffectTest, DeviceDisconnectWhileClientActive) {
3806 const audio_source_t source = AUDIO_SOURCE_MIC;
3807 const std::string address = "BUS00_MIC";
3808 const std::string deviceName = "randomName";
3809 audio_port_handle_t portId;
3810 audio_devices_t type = AUDIO_DEVICE_IN_BUS;
3811
3812 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(type,
3813 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(),
3814 AUDIO_FORMAT_DEFAULT));
3815 auto availableDevices = mManager->getAvailableInputDevices();
3816 ASSERT_GT(availableDevices.size(), 1);
3817
3818 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3819 attr.source = source;
3820 audio_session_t session = TEST_SESSION_ID;
3821 audio_io_handle_t inputClientHandle = 777;
3822 int effectId = 666;
3823 audio_port_v7 devicePort;
3824 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3825
3826 audio_port_handle_t routedPortId = devicePort.id;
3827 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3828 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003829 k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId));
François Gaffie6ebbce02023-07-19 13:27:53 +02003830 ASSERT_EQ(devicePort.id, routedPortId);
3831 auto selectedDevice = availableDevices.getDeviceFromId(routedPortId);
3832 ASSERT_NE(nullptr, selectedDevice);
3833
3834 // Add a pre processing effect on the input client session
3835 ASSERT_EQ(NO_ERROR, mManager->registerEffect(&TEST_EFFECT_DESC, inputClientHandle,
3836 PRODUCT_STRATEGY_NONE, session, effectId));
3837
3838 ASSERT_EQ(NO_ERROR, mManager->startInput(portId));
3839
3840 // Force a device disconnection to close the input, no crash expected of APM
3841 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3842 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3843 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3844
3845 // Reconnect the device
3846 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3847 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3848 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3849
3850 inputClientHandle += 1;
3851 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3852 routedPortId = devicePort.id;
3853
3854 // Reconnect the client changing voluntarily the io, but keeping the session to get the
3855 // effect attached again
3856 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3857 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003858 k48000SamplingRate));
François Gaffie6ebbce02023-07-19 13:27:53 +02003859
3860 // unregister effect should succeed since effect shall have been restore on the client session
3861 ASSERT_EQ(NO_ERROR, mManager->unregisterEffect(effectId));
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07003862}
jiabin220eea12024-05-17 17:55:20 +00003863
3864class AudioPolicyManagerTestBitPerfectBase : public AudioPolicyManagerTestWithConfigurationFile {
3865protected:
3866 void SetUp() override;
3867 void TearDown() override;
3868
3869 void startBitPerfectOutput();
3870 void reset();
3871 void getBitPerfectOutput(status_t expected);
3872
3873 const audio_format_t mBitPerfectFormat = AUDIO_FORMAT_PCM_16_BIT;
3874 const audio_channel_mask_t mBitPerfectChannelMask = AUDIO_CHANNEL_OUT_STEREO;
3875 const uint32_t mBitPerfectSampleRate = 48000;
3876 const uid_t mUid = 1234;
3877 audio_port_handle_t mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3878
3879 audio_io_handle_t mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
3880 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3881 audio_port_handle_t mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
3882
3883 static constexpr audio_attributes_t sMediaAttr = {
3884 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
3885 .usage = AUDIO_USAGE_MEDIA,
3886 };
3887};
3888
3889void AudioPolicyManagerTestBitPerfectBase::SetUp() {
3890 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUp());
3891
3892 mClient->addSupportedFormat(mBitPerfectFormat);
3893 mClient->addSupportedChannelMask(mBitPerfectChannelMask);
3894 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3895 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3896 "", "", AUDIO_FORMAT_DEFAULT));
3897 auto devices = mManager->getAvailableOutputDevices();
3898 mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3899 for (auto device : devices) {
3900 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
3901 mUsbPortId = device->getId();
3902 break;
3903 }
3904 }
3905 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, mUsbPortId);
3906
3907 std::vector<audio_mixer_attributes_t> mixerAttributes;
3908 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(mUsbPortId, mixerAttributes));
3909 EXPECT_GT(mixerAttributes.size(), 0);
3910 size_t bitPerfectIndex = 0;
3911 for (; bitPerfectIndex < mixerAttributes.size(); ++bitPerfectIndex) {
3912 if (mixerAttributes[bitPerfectIndex].mixer_behavior == AUDIO_MIXER_BEHAVIOR_BIT_PERFECT) {
3913 break;
3914 }
3915 }
3916 EXPECT_LT(bitPerfectIndex, mixerAttributes.size());
3917 EXPECT_EQ(mBitPerfectFormat, mixerAttributes[bitPerfectIndex].config.format);
3918 EXPECT_EQ(mBitPerfectChannelMask, mixerAttributes[bitPerfectIndex].config.channel_mask);
3919 EXPECT_EQ(mBitPerfectSampleRate, mixerAttributes[bitPerfectIndex].config.sample_rate);
3920 EXPECT_EQ(NO_ERROR,
3921 mManager->setPreferredMixerAttributes(
3922 &sMediaAttr, mUsbPortId, mUid, &mixerAttributes[bitPerfectIndex]));
3923}
3924
3925void AudioPolicyManagerTestBitPerfectBase::TearDown() {
3926 EXPECT_EQ(NO_ERROR,
3927 mManager->clearPreferredMixerAttributes(&sMediaAttr, mUsbPortId, mUid));
3928 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3929 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3930 "", "", AUDIO_FORMAT_LDAC));
3931
3932 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::TearDown());
3933}
3934
3935void AudioPolicyManagerTestBitPerfectBase::startBitPerfectOutput() {
3936 reset();
3937 bool isBitPerfect;
3938
3939 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3940 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3941 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3942 status_t status = mManager->startOutput(mBitPerfectPortId);
3943 if (status == DEAD_OBJECT) {
3944 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3945 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3946 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3947 status = mManager->startOutput(mBitPerfectPortId);
3948 }
3949 EXPECT_EQ(NO_ERROR, status);
3950 EXPECT_TRUE(isBitPerfect);
3951 EXPECT_NE(AUDIO_IO_HANDLE_NONE, mBitPerfectOutput);
3952 const auto bitPerfectOutputDesc = mManager->getOutputs().valueFor(mBitPerfectOutput);
3953 EXPECT_NE(nullptr, bitPerfectOutputDesc);
3954 EXPECT_EQ(AUDIO_OUTPUT_FLAG_BIT_PERFECT,
3955 bitPerfectOutputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
3956};
3957
3958void AudioPolicyManagerTestBitPerfectBase::reset() {
3959 mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
3960 mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3961 mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
3962}
3963
3964void AudioPolicyManagerTestBitPerfectBase::getBitPerfectOutput(status_t expected) {
3965 reset();
3966 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
3967 AttributionSourceState attributionSource = createAttributionSourceState(mUid);
3968 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3969 config.sample_rate = mBitPerfectSampleRate;
3970 config.channel_mask = mBitPerfectChannelMask;
3971 config.format = mBitPerfectFormat;
3972 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_BIT_PERFECT;
3973 AudioPolicyInterface::output_type_t outputType;
3974 bool isSpatialized;
3975 bool isBitPerfect;
3976 EXPECT_EQ(expected,
3977 mManager->getOutputForAttr(&sMediaAttr, &mBitPerfectOutput, AUDIO_SESSION_NONE,
3978 &stream, attributionSource, &config, &flags,
3979 &mSelectedDeviceId, &mBitPerfectPortId, {}, &outputType,
3980 &isSpatialized, &isBitPerfect));
3981}
3982
3983class AudioPolicyManagerTestBitPerfect : public AudioPolicyManagerTestBitPerfectBase {
3984};
3985
3986TEST_F(AudioPolicyManagerTestBitPerfect, UseBitPerfectOutput) {
3987 const uid_t anotherUid = 5678;
3988 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3989 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3990 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
3991 bool isBitPerfect;
3992
3993 // When there is no active bit-perfect playback, the output selection will follow default
3994 // routing strategy.
3995 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
3996 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
3997 AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3998 EXPECT_FALSE(isBitPerfect);
3999 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
4000 const auto outputDesc = mManager->getOutputs().valueFor(output);
4001 EXPECT_NE(nullptr, outputDesc);
4002 EXPECT_NE(AUDIO_OUTPUT_FLAG_BIT_PERFECT, outputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
4003
4004 // Start bit-perfect playback
4005 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4006
4007 // If the playback is from preferred mixer attributes owner but the request doesn't match
4008 // preferred mixer attributes, it will not be bit-perfect.
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_EQ(mBitPerfectOutput, output);
4014
4015 // When bit-perfect playback is active, all other playback will be routed to bit-perfect output.
4016 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4017 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4018 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4019 EXPECT_FALSE(isBitPerfect);
4020 EXPECT_EQ(mBitPerfectOutput, output);
4021
4022 // When bit-pefect playback is active, dtmf will also be routed to bit-perfect output.
4023 const audio_attributes_t dtmfAttr = {
4024 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
4025 .usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
4026 };
4027 audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
4028 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4029 portId = AUDIO_PORT_HANDLE_NONE;
4030 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4031 48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
4032 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4033 EXPECT_FALSE(isBitPerfect);
4034 EXPECT_EQ(mBitPerfectOutput, dtmfOutput);
4035
4036 // When configuration matches preferred mixer attributes, which is bit-perfect, but the client
4037 // is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
4038 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4039 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4040 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4041 EXPECT_FALSE(isBitPerfect);
4042 EXPECT_EQ(mBitPerfectOutput, output);
4043}
4044
4045TEST_F_WITH_FLAGS(
4046 AudioPolicyManagerTestBitPerfect,
4047 InternalMuteWhenBitPerfectCLientIsActive,
4048 REQUIRES_FLAGS_ENABLED(
4049 ACONFIG_FLAG(com::android::media::audioserver,
4050 fix_concurrent_playback_behavior_with_bit_perfect_client))
4051) {
4052 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4053
4054 // When bit-perfect playback is active, the system sound will be routed to bit-perfect output.
4055 // The system sound will be muted internally in this case. The bit-perfect client will be
4056 // played normally.
4057 const uint32_t anotherSampleRate = 44100;
4058 audio_port_handle_t systemSoundPortId = AUDIO_PORT_HANDLE_NONE;
4059 audio_io_handle_t systemSoundOutput = AUDIO_IO_HANDLE_NONE;
4060 const audio_attributes_t systemSoundAttr = {
4061 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4062 .usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION,
4063 };
4064 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4065 bool isBitPerfect;
4066 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4067 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &systemSoundOutput,
4068 &systemSoundPortId, systemSoundAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4069 EXPECT_FALSE(isBitPerfect);
4070 EXPECT_EQ(mBitPerfectOutput, systemSoundOutput);
4071 EXPECT_EQ(NO_ERROR, mManager->startOutput(systemSoundPortId));
4072 EXPECT_TRUE(mClient->getTrackInternalMute(systemSoundPortId));
4073 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4074 EXPECT_EQ(NO_ERROR, mManager->stopOutput(systemSoundPortId));
4075 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4076
4077 // When bit-perfect playback is active, the notification will be routed to bit-perfect output.
4078 // The notification sound will be played normally while the bit-perfect client will be muted
4079 // internally.
4080 audio_port_handle_t notificationPortId = AUDIO_PORT_HANDLE_NONE;
4081 audio_io_handle_t notificationOutput = AUDIO_IO_HANDLE_NONE;
4082 const audio_attributes_t notificationAttr = {
4083 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4084 .usage = AUDIO_USAGE_NOTIFICATION,
4085 };
4086 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4087 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &notificationOutput,
4088 &notificationPortId, notificationAttr, AUDIO_SESSION_NONE, mUid,
4089 &isBitPerfect);
4090 EXPECT_FALSE(isBitPerfect);
4091 EXPECT_EQ(mBitPerfectOutput, notificationOutput);
4092 EXPECT_EQ(NO_ERROR, mManager->startOutput(notificationPortId));
4093 EXPECT_FALSE(mClient->getTrackInternalMute(notificationPortId));
4094 EXPECT_TRUE(mClient->getTrackInternalMute(mBitPerfectPortId));
4095 EXPECT_EQ(NO_ERROR, mManager->stopOutput(notificationPortId));
4096 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4097
4098 EXPECT_EQ(NO_ERROR, mManager->stopOutput(mBitPerfectPortId));
4099}
4100
4101class AudioPolicyManagerTestBitPerfectPhoneMode : public AudioPolicyManagerTestBitPerfectBase,
4102 public testing::WithParamInterface<audio_mode_t> {
4103};
4104
4105TEST_P(AudioPolicyManagerTestBitPerfectPhoneMode, RejectBitPerfectWhenPhoneModeIsNotNormal) {
4106 if (!com::android::media::audioserver::
4107 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4108 GTEST_SKIP()
4109 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4110 }
4111
4112 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4113
4114 audio_mode_t mode = GetParam();
4115 mManager->setPhoneState(mode);
4116 // When the phone mode is not normal, the bit-perfect output will be reopned
4117 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4118
4119 // When the phone mode is not normal, the bit-perfect output will be closed.
4120 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4121
4122 mManager->setPhoneState(AUDIO_MODE_NORMAL);
4123}
4124
4125INSTANTIATE_TEST_CASE_P(
4126 PhoneMode,
4127 AudioPolicyManagerTestBitPerfectPhoneMode,
4128 testing::Values(AUDIO_MODE_IN_CALL,
4129 AUDIO_MODE_RINGTONE,
4130 AUDIO_MODE_IN_COMMUNICATION,
4131 AUDIO_MODE_CALL_SCREEN)
4132);
4133
4134class AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive :
4135 public AudioPolicyManagerTestBitPerfectBase,
4136 public testing::WithParamInterface<audio_usage_t> {
4137};
4138
4139TEST_P(AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4140 RejectBitPerfectWhenHigherPriorityUseCaseIsActive) {
4141 if (!com::android::media::audioserver::
4142 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4143 GTEST_SKIP()
4144 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4145 }
4146
4147 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4148
4149 audio_attributes_t attr = {
4150 .usage = GetParam(),
4151 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN
4152 };
4153 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4154 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
4155 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4156 ASSERT_NO_FATAL_FAILURE(
4157 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4158 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, attr));
4159 EXPECT_NE(mBitPerfectOutput, output);
4160 EXPECT_EQ(NO_ERROR, mManager->startOutput(portId));
4161 // When a high priority use case is active, the bit-perfect output will be closed.
4162 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4163
4164 // When any higher priority use case is active, the bit-perfect request will be rejected.
4165 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4166}
4167
4168INSTANTIATE_TEST_CASE_P(
4169 HigherPriorityUseCases,
4170 AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4171 testing::Values(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4172 AUDIO_USAGE_ALARM)
4173);