blob: 6974a0bf379d63a2e89c6bd9f9ce0a499e37bf0b [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"
Mikhail Naganov7f7344a2024-09-06 10:23:24 -070047#include "test_execution_tracer.h"
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080048
49using namespace android;
Jiabin Huang3b98d322020-09-03 17:54:16 +000050using testing::UnorderedElementsAre;
Marvin Raminbdefaf02023-11-01 09:10:32 +010051using testing::IsEmpty;
Svet Ganov3e5f14f2021-05-13 22:51:08 +000052using android::content::AttributionSourceState;
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080053
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020054namespace {
55
56AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
57 AudioMixMatchCriterion criterion;
58 criterion.mValue.mUid = uid;
59 criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
60 return criterion;
61}
62
Oscar Azucena873d10f2023-01-12 18:34:42 -080063AudioMixMatchCriterion createUserIdCriterion(int userId, bool exclude = false) {
64 AudioMixMatchCriterion criterion;
65 criterion.mValue.mUserId = userId;
66 criterion.mRule = exclude ? RULE_EXCLUDE_USERID : RULE_MATCH_USERID;
67 return criterion;
68}
69
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +020070AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
71 AudioMixMatchCriterion criterion;
72 criterion.mValue.mUsage = usage;
73 criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
74 return criterion;
75}
76
77AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
78 AudioMixMatchCriterion criterion;
79 criterion.mValue.mSource = source;
80 criterion.mRule = exclude ?
81 RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
82 return criterion;
83}
84
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +020085AudioMixMatchCriterion createSessionIdCriterion(audio_session_t session, bool exclude = false) {
86 AudioMixMatchCriterion criterion;
87 criterion.mValue.mAudioSessionId = session;
88 criterion.mRule = exclude ?
89 RULE_EXCLUDE_AUDIO_SESSION_ID : RULE_MATCH_AUDIO_SESSION_ID;
90 return criterion;
91}
92
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +020093// TODO b/182392769: use attribution source util
94AttributionSourceState createAttributionSourceState(uid_t uid) {
95 AttributionSourceState attributionSourceState;
96 attributionSourceState.uid = uid;
97 attributionSourceState.token = sp<BBinder>::make();
98 return attributionSourceState;
99}
100
jiabin66acc432024-02-06 00:57:36 +0000101bool equals(const audio_config_base_t& config1, const audio_config_base_t& config2) {
102 return config1.format == config2.format
103 && config1.sample_rate == config2.sample_rate
104 && config1.channel_mask == config2.channel_mask;
105}
106
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +0200107} // namespace
108
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700109TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
110 auto config = AudioPolicyConfig::createWritableForTests();
111 EXPECT_TRUE(config->getSource().empty());
112 EXPECT_TRUE(config->getHwModules().isEmpty());
113 EXPECT_TRUE(config->getInputDevices().isEmpty());
114 EXPECT_TRUE(config->getOutputDevices().isEmpty());
115}
116
117TEST(AudioPolicyConfigTest, FallbackToDefault) {
118 auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
119 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
120 EXPECT_EQ(AudioPolicyConfig::kDefaultConfigSource, config->getSource());
121}
122
123TEST(AudioPolicyConfigTest, LoadForTests) {
124 {
125 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(
126 base::GetExecutableDirectory() + "/test_invalid_audio_policy_configuration.xml");
127 EXPECT_FALSE(result.ok());
128 }
129 {
130 const std::string source =
131 base::GetExecutableDirectory() + "/test_audio_policy_configuration.xml";
132 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(source);
133 ASSERT_TRUE(result.ok());
134 EXPECT_EQ(source, result.value()->getSource());
135 EXPECT_FALSE(result.value()->getHwModules().isEmpty());
136 EXPECT_FALSE(result.value()->getInputDevices().isEmpty());
137 EXPECT_FALSE(result.value()->getOutputDevices().isEmpty());
138 }
139}
140
Mikhail Naganov47835552019-05-14 10:32:51 -0700141TEST(AudioPolicyManagerTestInit, EngineFailure) {
142 AudioPolicyTestClient client;
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700143 auto config = AudioPolicyConfig::createWritableForTests();
144 config->setDefault();
145 config->setEngineLibraryNameSuffix("non-existent");
146 AudioPolicyTestManager manager(config, &client);
Mikhail Naganov47835552019-05-14 10:32:51 -0700147 ASSERT_EQ(NO_INIT, manager.initialize());
148 ASSERT_EQ(NO_INIT, manager.initCheck());
149}
150
151TEST(AudioPolicyManagerTestInit, ClientFailure) {
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800152 AudioPolicyTestClient client;
153 AudioPolicyTestManager manager(&client);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800154 // Since the default client fails to open anything,
155 // APM should indicate that the initialization didn't succeed.
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800156 ASSERT_EQ(NO_INIT, manager.initialize());
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800157 ASSERT_EQ(NO_INIT, manager.initCheck());
158}
159
160
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800161class PatchCountCheck {
162 public:
163 explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
164 : mClient{client},
165 mInitialCount{mClient->getActivePatchesCount()} {}
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800166 int deltaFromSnapshot() const {
167 size_t currentCount = mClient->getActivePatchesCount();
168 if (mInitialCount <= currentCount) {
169 return currentCount - mInitialCount;
170 } else {
171 return -(static_cast<int>(mInitialCount - currentCount));
172 }
173 }
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800174 private:
175 const AudioPolicyManagerTestClient *mClient;
176 const size_t mInitialCount;
177};
178
Mikhail Naganov04a86632017-12-15 18:01:42 -0800179class AudioPolicyManagerTest : public testing::Test {
Mikhail Naganov285c1732024-09-05 17:26:50 -0700180 public:
181 constexpr static uint32_t k384000SamplingRate = 384000;
182 constexpr static uint32_t k48000SamplingRate = 48000;
183 constexpr static uint32_t k96000SamplingRate = 96000;
184
Mikhail Naganov04a86632017-12-15 18:01:42 -0800185 protected:
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800186 void SetUp() override;
187 void TearDown() override;
jiabin7c0205e2019-09-05 10:26:04 -0700188 virtual void SetUpManagerConfig();
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800189 virtual std::string getEngineConfigFilePath() const { return sTestEngineConfig; }
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800190
191 void dumpToLog();
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700192 // When explicit routing is needed, selectedDeviceId needs to be set as the wanted port
193 // id. Otherwise, selectedDeviceId needs to be initialized as AUDIO_PORT_HANDLE_NONE.
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800194 void getOutputForAttr(
195 audio_port_handle_t *selectedDeviceId,
196 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700197 audio_channel_mask_t channelMask,
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800198 int sampleRate,
199 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700200 audio_io_handle_t *output = nullptr,
jiabinf4eb15a2019-08-28 15:31:47 -0700201 audio_port_handle_t *portId = nullptr,
Mikhail Naganov285c1732024-09-05 17:26:50 -0700202 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER,
jiabin3ff8d7d2022-12-13 06:27:44 +0000203 audio_session_t session = AUDIO_SESSION_NONE,
jiabin5eaf0962022-12-20 20:11:38 +0000204 int uid = 0,
205 bool* isBitPerfect = nullptr);
jiabinf4eb15a2019-08-28 15:31:47 -0700206 void getInputForAttr(
207 const audio_attributes_t &attr,
François Gaffie6ebbce02023-07-19 13:27:53 +0200208 audio_io_handle_t *input,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200209 audio_session_t session,
jiabinf4eb15a2019-08-28 15:31:47 -0700210 audio_unique_id_t riid,
211 audio_port_handle_t *selectedDeviceId,
212 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700213 audio_channel_mask_t channelMask,
jiabinf4eb15a2019-08-28 15:31:47 -0700214 int sampleRate,
215 audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100216 audio_port_handle_t *portId = nullptr,
217 uint32_t *virtualDeviceId = nullptr);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800218 PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
Mikhail Naganov04a86632017-12-15 18:01:42 -0800219
Mikhail Naganov0805de12022-02-15 23:00:07 +0000220 void getAudioPorts(audio_port_type_t type, audio_port_role_t role,
221 std::vector<audio_port_v7>* ports);
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700222 // Tries to find a device port. If 'foundPort' isn't nullptr,
223 // will generate a failure if the port hasn't been found.
224 bool findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
jiabin19cdba52020-11-24 11:28:58 -0800225 const std::string &address, audio_port_v7 *foundPort);
jiabin7c0205e2019-09-05 10:26:04 -0700226 static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
Kriti Dangef6be8f2020-11-05 11:58:19 +0100227 virtual AudioPolicyManagerTestClient* getClient() { return new AudioPolicyManagerTestClient; }
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800228 void verifyBuiltInStrategyIdsAreValid();
jiabinf4eb15a2019-08-28 15:31:47 -0700229
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700230 sp<AudioPolicyConfig> mConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800231 std::unique_ptr<AudioPolicyManagerTestClient> mClient;
232 std::unique_ptr<AudioPolicyTestManager> mManager;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100233
jiabind9f7fbd2024-09-10 23:07:04 +0000234 static const std::string sTestEngineConfig;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800235};
236
jiabind9f7fbd2024-09-10 23:07:04 +0000237const std::string AudioPolicyManagerTest::sTestEngineConfig =
238 base::GetExecutableDirectory() + "/engine/test_audio_policy_engine_configuration.xml";
239
Mikhail Naganov04a86632017-12-15 18:01:42 -0800240void AudioPolicyManagerTest::SetUp() {
Kriti Dangef6be8f2020-11-05 11:58:19 +0100241 mClient.reset(getClient());
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700242 ASSERT_NO_FATAL_FAILURE(SetUpManagerConfig()); // Subclasses may want to customize the config.
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800243 mManager.reset(new AudioPolicyTestManager(mConfig, mClient.get(), getEngineConfigFilePath()));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800244 ASSERT_EQ(NO_ERROR, mManager->initialize());
245 ASSERT_EQ(NO_ERROR, mManager->initCheck());
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800246}
Mikhail Naganov04a86632017-12-15 18:01:42 -0800247
248void AudioPolicyManagerTest::TearDown() {
249 mManager.reset();
250 mClient.reset();
251}
252
jiabin7c0205e2019-09-05 10:26:04 -0700253void AudioPolicyManagerTest::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700254 mConfig = AudioPolicyConfig::createWritableForTests();
255 mConfig->setDefault();
jiabin7c0205e2019-09-05 10:26:04 -0700256}
257
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800258void AudioPolicyManagerTest::dumpToLog() {
Mikhail Naganov21b43362018-06-04 10:37:09 -0700259 int pipefd[2];
260 ASSERT_NE(-1, pipe(pipefd));
261 pid_t cpid = fork();
262 ASSERT_NE(-1, cpid);
263 if (cpid == 0) {
264 // Child process reads from the pipe and logs.
265 close(pipefd[1]);
266 std::string line;
267 char buf;
268 while (read(pipefd[0], &buf, sizeof(buf)) > 0) {
269 if (buf != '\n') {
270 line += buf;
271 } else {
272 ALOGI("%s", line.c_str());
273 line = "";
274 }
275 }
276 if (!line.empty()) ALOGI("%s", line.c_str());
277 close(pipefd[0]);
278 _exit(EXIT_SUCCESS);
279 } else {
280 // Parent does the dump and checks the status code.
281 close(pipefd[0]);
282 ASSERT_EQ(NO_ERROR, mManager->dump(pipefd[1]));
283 close(pipefd[1]);
284 wait(NULL); // Wait for the child to exit.
285 }
286}
287
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800288void AudioPolicyManagerTest::getOutputForAttr(
289 audio_port_handle_t *selectedDeviceId,
290 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700291 audio_channel_mask_t channelMask,
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800292 int sampleRate,
293 audio_output_flags_t flags,
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700294 audio_io_handle_t *output,
jiabinf4eb15a2019-08-28 15:31:47 -0700295 audio_port_handle_t *portId,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200296 audio_attributes_t attr,
jiabin3ff8d7d2022-12-13 06:27:44 +0000297 audio_session_t session,
jiabin5eaf0962022-12-20 20:11:38 +0000298 int uid,
299 bool* isBitPerfect) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700300 audio_io_handle_t localOutput;
301 if (!output) output = &localOutput;
302 *output = AUDIO_IO_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800303 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
304 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
305 config.sample_rate = sampleRate;
306 config.channel_mask = channelMask;
307 config.format = format;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800308 audio_port_handle_t localPortId;
309 if (!portId) portId = &localPortId;
310 *portId = AUDIO_PORT_HANDLE_NONE;
Eric Laurent8a1095a2019-11-08 14:44:16 -0800311 AudioPolicyInterface::output_type_t outputType;
Eric Laurentb0a7bc92022-04-05 15:06:08 +0200312 bool isSpatialized;
jiabin5eaf0962022-12-20 20:11:38 +0000313 bool isBitPerfectInternal;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200314 AttributionSourceState attributionSource = createAttributionSourceState(uid);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800315 ASSERT_EQ(OK, mManager->getOutputForAttr(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200316 &attr, output, session, &stream, attributionSource, &config, &flags,
jiabin5eaf0962022-12-20 20:11:38 +0000317 selectedDeviceId, portId, {}, &outputType, &isSpatialized,
318 isBitPerfect == nullptr ? &isBitPerfectInternal : isBitPerfect));
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800319 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -0700320 ASSERT_NE(AUDIO_IO_HANDLE_NONE, *output);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800321}
322
jiabinf4eb15a2019-08-28 15:31:47 -0700323void AudioPolicyManagerTest::getInputForAttr(
324 const audio_attributes_t &attr,
François Gaffie6ebbce02023-07-19 13:27:53 +0200325 audio_io_handle_t *input,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +0200326 const audio_session_t session,
jiabinf4eb15a2019-08-28 15:31:47 -0700327 audio_unique_id_t riid,
328 audio_port_handle_t *selectedDeviceId,
329 audio_format_t format,
Mikhail Naganov55773032020-10-01 15:08:13 -0700330 audio_channel_mask_t channelMask,
jiabinf4eb15a2019-08-28 15:31:47 -0700331 int sampleRate,
332 audio_input_flags_t flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100333 audio_port_handle_t *portId,
334 uint32_t *virtualDeviceId) {
jiabinf4eb15a2019-08-28 15:31:47 -0700335 audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
336 config.sample_rate = sampleRate;
337 config.channel_mask = channelMask;
338 config.format = format;
jiabinf4eb15a2019-08-28 15:31:47 -0700339 audio_port_handle_t localPortId;
340 if (!portId) portId = &localPortId;
341 *portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +0100342 if (!virtualDeviceId) virtualDeviceId = 0;
jiabinf4eb15a2019-08-28 15:31:47 -0700343 AudioPolicyInterface::input_type_t inputType;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +0200344 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
jiabinf4eb15a2019-08-28 15:31:47 -0700345 ASSERT_EQ(OK, mManager->getInputForAttr(
François Gaffie6ebbce02023-07-19 13:27:53 +0200346 &attr, input, riid, session, attributionSource, &config, flags,
Marvin Ramine5a122d2023-12-07 13:57:59 +0100347 selectedDeviceId, &inputType, portId, virtualDeviceId));
jiabinf4eb15a2019-08-28 15:31:47 -0700348 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
349}
350
Mikhail Naganov0805de12022-02-15 23:00:07 +0000351void AudioPolicyManagerTest::getAudioPorts(audio_port_type_t type, audio_port_role_t role,
352 std::vector<audio_port_v7>* ports) {
jiabinf4eb15a2019-08-28 15:31:47 -0700353 uint32_t numPorts = 0;
354 uint32_t generation1;
355 status_t ret;
356
Mikhail Naganov0805de12022-02-15 23:00:07 +0000357 ret = mManager->listAudioPorts(role, type, &numPorts, nullptr, &generation1);
358 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
jiabinf4eb15a2019-08-28 15:31:47 -0700359
360 uint32_t generation2;
Mikhail Naganov0805de12022-02-15 23:00:07 +0000361 ports->resize(numPorts);
362 ret = mManager->listAudioPorts(role, type, &numPorts, ports->data(), &generation2);
363 ASSERT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
364 ASSERT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
365}
366
367bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
368 audio_devices_t deviceType, const std::string &address, audio_port_v7 *foundPort) {
369 std::vector<audio_port_v7> ports;
370 getAudioPorts(AUDIO_PORT_TYPE_DEVICE, role, &ports);
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700371 if (HasFailure()) return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700372
373 for (const auto &port : ports) {
374 if (port.role == role && port.ext.device.type == deviceType &&
375 (strncmp(port.ext.device.address, address.c_str(),
376 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700377 if (foundPort) *foundPort = port;
378 return true;
jiabinf4eb15a2019-08-28 15:31:47 -0700379 }
380 }
Mikhail Naganovd0e2c742020-03-25 15:59:59 -0700381 if (foundPort) {
382 ADD_FAILURE() << "Device port with role " << role << " and address "
383 << address << " not found";
384 }
385 return false;
jiabinf4eb15a2019-08-28 15:31:47 -0700386}
387
jiabin7c0205e2019-09-05 10:26:04 -0700388audio_port_handle_t AudioPolicyManagerTest::getDeviceIdFromPatch(
389 const struct audio_patch* patch) {
390 // The logic here is the same as the one in AudioIoDescriptor.
391 // Note this function is aim to get routed device id for test.
392 // In that case, device to device patch is not expected here.
393 if (patch->num_sources != 0 && patch->num_sinks != 0) {
394 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
395 return patch->sinks[0].id;
396 } else {
397 return patch->sources[0].id;
398 }
399 }
400 return AUDIO_PORT_HANDLE_NONE;
401}
402
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800403void AudioPolicyManagerTest::verifyBuiltInStrategyIdsAreValid() {
404 AudioProductStrategyVector strategies;
405 ASSERT_EQ(NO_ERROR, mManager->listAudioProductStrategies(strategies));
406 for (const auto& strategy : strategies) {
407 // Since ids are unsigned, this will also cover the case when the id is 'NONE' which is -1.
408 EXPECT_LT(strategy.getId(),
409 media::audio::common::AudioHalProductStrategy::VENDOR_STRATEGY_ID_START)
410 << strategy.getName();
411 }
412}
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800413
414TEST_F(AudioPolicyManagerTest, InitSuccess) {
415 // SetUp must finish with no assertions.
416}
417
418TEST_F(AudioPolicyManagerTest, Dump) {
419 dumpToLog();
420}
421
Mikhail Naganov04a86632017-12-15 18:01:42 -0800422TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
423 audio_patch patch{};
424 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800425 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganov04a86632017-12-15 18:01:42 -0800426 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
427 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
428 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
429 patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
430 patch.num_sinks = 1;
431 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
432 patch.num_sources = 1;
433 patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
434 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
435 patch.num_sources = 2;
436 patch.num_sinks = 1;
437 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
438 patch = {};
439 patch.num_sources = 1;
440 patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
441 patch.num_sinks = 1;
442 patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
443 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
444 patch = {};
445 patch.num_sources = 1;
446 patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
447 patch.num_sinks = 1;
448 patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
449 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
450 // Verify that the handle is left unchanged.
451 ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800452 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800453}
454
455TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
Mikhail Naganov04a86632017-12-15 18:01:42 -0800456 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
457 uid_t uid = 42;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800458 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000459 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
Mikhail Naganovdc769682018-05-04 15:34:08 -0700460 PatchBuilder patchBuilder;
Mikhail Naganovc0d04982020-03-02 21:02:28 +0000461 patchBuilder.addSource(mManager->getAvailableInputDevices()[0]).
Mikhail Naganovdc769682018-05-04 15:34:08 -0700462 addSink(mManager->getConfig().getDefaultOutputDevice());
463 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800464 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800465 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800466}
467
468// TODO: Add patch creation tests that involve already existing patch
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800469
Mikhail Naganovbada1f52024-12-03 16:20:10 -0800470TEST_F(AudioPolicyManagerTest, BuiltInStrategyIdsAreValid) {
471 verifyBuiltInStrategyIdsAreValid();
472}
473
474class AudioPolicyManagerTestWithDefaultEngineConfig : public AudioPolicyManagerTest {
475 protected:
476 // The APM will use the default engine config from EngineDefaultConfig.h.
477 std::string getEngineConfigFilePath() const override { return ""; }
478};
479
480TEST_F(AudioPolicyManagerTestWithDefaultEngineConfig, BuiltInStrategyIdsAreValid) {
481 verifyBuiltInStrategyIdsAreValid();
482}
483
Michael Chan6fb34492020-12-08 15:44:49 +1100484enum
485{
486 MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX = 0,
487 MSD_AUDIO_PATCH_COUNT_NAME_INDEX = 1
488};
489using MsdAudioPatchCountSpecification = std::tuple<size_t, std::string>;
490
491class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest,
492 public ::testing::WithParamInterface<MsdAudioPatchCountSpecification> {
493 public:
494 AudioPolicyManagerTestMsd();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800495 protected:
jiabin7c0205e2019-09-05 10:26:04 -0700496 void SetUpManagerConfig() override;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800497 void TearDown() override;
Dorin Drimus94d94412022-02-02 09:05:02 +0100498 AudioProfileVector getDirectProfilesForAttributes(const audio_attributes_t& attr);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800499
500 sp<DeviceDescriptor> mMsdOutputDevice;
501 sp<DeviceDescriptor> mMsdInputDevice;
Eric Laurent74c38dc2020-12-23 18:19:44 +0100502 sp<DeviceDescriptor> mDefaultOutputDevice;
Michael Chan6fb34492020-12-08 15:44:49 +1100503
504 const size_t mExpectedAudioPatchCount;
505 sp<DeviceDescriptor> mSpdifDevice;
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100506
507 sp<DeviceDescriptor> mHdmiInputDevice;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800508};
509
Michael Chan6fb34492020-12-08 15:44:49 +1100510AudioPolicyManagerTestMsd::AudioPolicyManagerTestMsd()
511 : mExpectedAudioPatchCount(std::get<MSD_AUDIO_PATCH_COUNT_NUM_AUDIO_PATCHES_INDEX>(
512 GetParam())) {}
513
514INSTANTIATE_TEST_CASE_P(
515 MsdAudioPatchCount,
516 AudioPolicyManagerTestMsd,
517 ::testing::Values(
Eric Laurent0ca09402024-05-16 17:48:59 +0000518 MsdAudioPatchCountSpecification(2u, "single"),
519 MsdAudioPatchCountSpecification(3u, "dual")
Michael Chan6fb34492020-12-08 15:44:49 +1100520 ),
521 [](const ::testing::TestParamInfo<MsdAudioPatchCountSpecification> &info) {
522 return std::get<MSD_AUDIO_PATCH_COUNT_NAME_INDEX>(info.param); }
523);
524
jiabin7c0205e2019-09-05 10:26:04 -0700525void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800526 // TODO: Consider using Serializer to load part of the config from a string.
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -0700527 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700528 mConfig->getHwModules().getModuleFromName(
529 AUDIO_HARDWARE_MODULE_ID_PRIMARY)->setHalVersion(3, 0);
530
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800531 mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
532 sp<AudioProfile> pcmOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100533 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800534 sp<AudioProfile> ac3OutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100535 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100536 sp<AudioProfile> iec958OutputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100537 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800538 mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
539 mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100540 mMsdOutputDevice->addAudioProfile(iec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800541 mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
542 // Match output profile from AudioPolicyConfig::setDefault.
543 sp<AudioProfile> pcmInputProfile = new AudioProfile(
544 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
545 mMsdInputDevice->addAudioProfile(pcmInputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700546 mConfig->addDevice(mMsdOutputDevice);
547 mConfig->addDevice(mMsdInputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800548
Eric Laurent0ca09402024-05-16 17:48:59 +0000549 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100550 // Add SPDIF device with PCM output profile as a second device for dual MSD audio patching.
551 mSpdifDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPDIF);
552 mSpdifDevice->addAudioProfile(pcmOutputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700553 mConfig->addDevice(mSpdifDevice);
Michael Chan6fb34492020-12-08 15:44:49 +1100554
555 sp<OutputProfile> spdifOutputProfile = new OutputProfile("spdif output");
556 spdifOutputProfile->addAudioProfile(pcmOutputProfile);
557 spdifOutputProfile->addSupportedDevice(mSpdifDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700558 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Michael Chan6fb34492020-12-08 15:44:49 +1100559 addOutputProfile(spdifOutputProfile);
560 }
561
Mikhail Naganovccd149c2024-09-26 14:16:13 -0700562 sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 3 /*halVersionMajor*/);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700563 HwModuleCollection modules = mConfig->getHwModules();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800564 modules.add(msdModule);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700565 mConfig->setHwModules(modules);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800566
jiabin5740f082019-08-19 15:08:30 -0700567 sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800568 msdOutputProfile->addAudioProfile(pcmOutputProfile);
569 msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
570 msdModule->addOutputProfile(msdOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700571 sp<OutputProfile> msdCompressedOutputProfile = new OutputProfile("msd compressed input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800572 msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
573 msdCompressedOutputProfile->setFlags(
574 AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
575 AUDIO_OUTPUT_FLAG_NON_BLOCKING);
576 msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
577 msdModule->addOutputProfile(msdCompressedOutputProfile);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100578 sp<OutputProfile> msdIec958OutputProfile = new OutputProfile("msd iec958 input");
579 msdIec958OutputProfile->addAudioProfile(iec958OutputProfile);
580 msdIec958OutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
581 msdIec958OutputProfile->addSupportedDevice(mMsdOutputDevice);
582 msdModule->addOutputProfile(msdIec958OutputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800583
jiabin5740f082019-08-19 15:08:30 -0700584 sp<InputProfile> msdInputProfile = new InputProfile("msd output");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800585 msdInputProfile->addAudioProfile(pcmInputProfile);
586 msdInputProfile->addSupportedDevice(mMsdInputDevice);
587 msdModule->addInputProfile(msdInputProfile);
588
589 // Add a profile with another encoding to the default device to test routing
590 // of streams that are not supported by MSD.
591 sp<AudioProfile> dtsOutputProfile = new AudioProfile(
Dean Wheatleyd082f472022-02-04 11:10:48 +1100592 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700593 mConfig->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
jiabin5740f082019-08-19 15:08:30 -0700594 sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800595 primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
596 primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700597 primaryEncodedOutputProfile->addSupportedDevice(mConfig->getDefaultOutputDevice());
598 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800599 addOutputProfile(primaryEncodedOutputProfile);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100600
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700601 mDefaultOutputDevice = mConfig->getDefaultOutputDevice();
Eric Laurent0ca09402024-05-16 17:48:59 +0000602 if (mExpectedAudioPatchCount == 3) {
Michael Chan6fb34492020-12-08 15:44:49 +1100603 mSpdifDevice->addAudioProfile(dtsOutputProfile);
604 primaryEncodedOutputProfile->addSupportedDevice(mSpdifDevice);
605 }
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100606
607 // Add HDMI input device with IEC60958 profile for HDMI in -> MSD patching.
608 mHdmiInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_HDMI);
609 sp<AudioProfile> iec958InputProfile = new AudioProfile(
Dean Wheatley16809da2022-12-09 14:55:46 +1100610 AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100611 mHdmiInputDevice->addAudioProfile(iec958InputProfile);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700612 mConfig->addDevice(mHdmiInputDevice);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100613 sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
614 hdmiInputProfile->addAudioProfile(iec958InputProfile);
615 hdmiInputProfile->setFlags(AUDIO_INPUT_FLAG_DIRECT);
616 hdmiInputProfile->addSupportedDevice(mHdmiInputDevice);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700617 mConfig->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100618 addInputProfile(hdmiInputProfile);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800619}
620
621void AudioPolicyManagerTestMsd::TearDown() {
622 mMsdOutputDevice.clear();
623 mMsdInputDevice.clear();
Eric Laurent74c38dc2020-12-23 18:19:44 +0100624 mDefaultOutputDevice.clear();
Michael Chan6fb34492020-12-08 15:44:49 +1100625 mSpdifDevice.clear();
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100626 mHdmiInputDevice.clear();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800627 AudioPolicyManagerTest::TearDown();
628}
629
Dorin Drimus94d94412022-02-02 09:05:02 +0100630AudioProfileVector AudioPolicyManagerTestMsd::getDirectProfilesForAttributes(
631 const audio_attributes_t& attr) {
632 AudioProfileVector audioProfilesVector;
633 mManager->getDirectProfilesForAttributes(&attr, audioProfilesVector);
634 return audioProfilesVector;
635}
636
Michael Chan6fb34492020-12-08 15:44:49 +1100637TEST_P(AudioPolicyManagerTestMsd, InitSuccess) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800638 ASSERT_TRUE(mMsdOutputDevice);
639 ASSERT_TRUE(mMsdInputDevice);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100640 ASSERT_TRUE(mDefaultOutputDevice);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800641}
642
Michael Chan6fb34492020-12-08 15:44:49 +1100643TEST_P(AudioPolicyManagerTestMsd, Dump) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800644 dumpToLog();
645}
646
Michael Chan6fb34492020-12-08 15:44:49 +1100647TEST_P(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800648 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800649 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
650 AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Eric Laurent0ca09402024-05-16 17:48:59 +0000651 ASSERT_EQ(mExpectedAudioPatchCount -1 , patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800652}
653
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100654TEST_P(AudioPolicyManagerTestMsd, PatchCreationSetReleaseMsdOutputPatches) {
Michael Chan6fb34492020-12-08 15:44:49 +1100655 const PatchCountCheck patchCount = snapshotPatchCount();
656 DeviceVector devices = mManager->getAvailableOutputDevices();
657 // Remove MSD output device to avoid patching to itself
658 devices.remove(mMsdOutputDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000659 ASSERT_EQ(mExpectedAudioPatchCount -1 , devices.size());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100660 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000661 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Michael Chan6fb34492020-12-08 15:44:49 +1100662 // Dual patch: exercise creating one new audio patch and reusing another existing audio patch.
663 DeviceVector singleDevice(devices[0]);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100664 mManager->releaseMsdOutputPatches(singleDevice);
Eric Laurent0ca09402024-05-16 17:48:59 +0000665 ASSERT_EQ(mExpectedAudioPatchCount - 2, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100666 mManager->setMsdOutputPatches(&devices);
Eric Laurent0ca09402024-05-16 17:48:59 +0000667 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100668 mManager->releaseMsdOutputPatches(devices);
Michael Chan6fb34492020-12-08 15:44:49 +1100669 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
670}
671
672TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800673 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700674 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100675 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
676 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100677 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100678 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800679}
680
Michael Chan6fb34492020-12-08 15:44:49 +1100681TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800682 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700683 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800684 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100685 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100686 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000687 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800688}
689
Michael Chan6fb34492020-12-08 15:44:49 +1100690TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800691 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700692 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100693 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
694 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100695 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100696 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
697 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800698 getOutputForAttr(&selectedDeviceId,
Dean Wheatleyd082f472022-02-04 11:10:48 +1100699 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100700 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100701 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800702}
703
Michael Chan6fb34492020-12-08 15:44:49 +1100704TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800705 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700706 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100707 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
708 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800709 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000710 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800711}
712
Michael Chan6fb34492020-12-08 15:44:49 +1100713TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800714 // Switch between formats that are supported and not supported by MSD.
715 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800716 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700717 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
718 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100719 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
720 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100721 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Michael Chan6fb34492020-12-08 15:44:49 +1100722 ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800723 mManager->releaseOutput(portId);
Eric Laurent0ca09402024-05-16 17:48:59 +0000724 ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800725 }
726 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800727 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700728 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
729 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100730 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
731 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800732 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000733 ASSERT_EQ(-static_cast<int>(mExpectedAudioPatchCount) + 2, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800734 mManager->releaseOutput(portId);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800735 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800736 }
737 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800738 const PatchCountCheck patchCount = snapshotPatchCount();
jiabin7c0205e2019-09-05 10:26:04 -0700739 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Dean Wheatleyd082f472022-02-04 11:10:48 +1100740 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
741 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent74c38dc2020-12-23 18:19:44 +0100742 ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
Eric Laurent0ca09402024-05-16 17:48:59 +0000743 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800744 }
745}
jiabinf4eb15a2019-08-28 15:31:47 -0700746
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100747TEST_P(AudioPolicyManagerTestMsd, PatchCreationFromHdmiInToMsd) {
748 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
749 uid_t uid = 42;
750 const PatchCountCheck patchCount = snapshotPatchCount();
751 ASSERT_FALSE(mManager->getAvailableInputDevices().isEmpty());
752 PatchBuilder patchBuilder;
753 patchBuilder.
754 addSource(mManager->getAvailableInputDevices().
755 getDevice(AUDIO_DEVICE_IN_HDMI, String8(""), AUDIO_FORMAT_DEFAULT)).
756 addSink(mManager->getAvailableOutputDevices().
757 getDevice(AUDIO_DEVICE_OUT_BUS, String8(""), AUDIO_FORMAT_DEFAULT));
758 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
759 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
760 AudioPatchCollection patches = mManager->getAudioPatches();
761 sp<AudioPatch> patch = patches.valueFor(handle);
762 ASSERT_EQ(1, patch->mPatch.num_sources);
763 ASSERT_EQ(1, patch->mPatch.num_sinks);
764 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, patch->mPatch.sources[0].role);
765 ASSERT_EQ(AUDIO_PORT_ROLE_SINK, patch->mPatch.sinks[0].role);
766 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sources[0].format);
767 ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sinks[0].format);
Dean Wheatley16809da2022-12-09 14:55:46 +1100768 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sources[0].channel_mask);
769 ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sinks[0].channel_mask);
Dean Wheatleyd082f472022-02-04 11:10:48 +1100770 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sources[0].sample_rate);
771 ASSERT_EQ(k48000SamplingRate, patch->mPatch.sinks[0].sample_rate);
Dean Wheatley8bee85a2021-02-10 16:02:23 +1100772 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
773}
774
Dorin Drimus94d94412022-02-02 09:05:02 +0100775TEST_P(AudioPolicyManagerTestMsd, GetDirectProfilesForAttributesWithMsd) {
776 const audio_attributes_t attr = {
777 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
778 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
779
780 // count expected direct profiles for the default device
781 int countDirectProfilesPrimary = 0;
782 const auto& primary = mManager->getConfig().getHwModules()
783 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700784 for (const auto& outputProfile : primary->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100785 if (outputProfile->asAudioPort()->isDirectOutput()) {
786 countDirectProfilesPrimary += outputProfile->asAudioPort()->getAudioProfiles().size();
787 }
788 }
789
790 // count expected direct profiles for the msd device
791 int countDirectProfilesMsd = 0;
792 const auto& msd = mManager->getConfig().getHwModules()
793 .getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700794 for (const auto& outputProfile : msd->getOutputProfiles()) {
Dorin Drimus94d94412022-02-02 09:05:02 +0100795 if (outputProfile->asAudioPort()->isDirectOutput()) {
796 countDirectProfilesMsd += outputProfile->asAudioPort()->getAudioProfiles().size();
797 }
798 }
799
800 // before setting up MSD audio patches we only have the primary hal direct profiles
801 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
802
803 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
804 // Remove MSD output device to avoid patching to itself
805 outputDevices.remove(mMsdOutputDevice);
806 mManager->setMsdOutputPatches(&outputDevices);
807
808 // after setting up MSD audio patches the MSD direct profiles are added
809 ASSERT_EQ(countDirectProfilesPrimary + countDirectProfilesMsd,
810 getDirectProfilesForAttributes(attr).size());
811
812 mManager->releaseMsdOutputPatches(outputDevices);
813 // releasing the MSD audio patches gets us back to the primary hal direct profiles only
814 ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
815}
816
Dorin Drimusecc9f422022-03-09 17:57:40 +0100817TEST_P(AudioPolicyManagerTestMsd, IsDirectPlaybackSupportedWithMsd) {
818 const audio_attributes_t attr = {
819 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
820 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
821
822 audio_config_base_t directConfig = AUDIO_CONFIG_BASE_INITIALIZER;
823 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700824 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100825 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
826
827 audio_config_base_t nonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
828 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700829 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100830 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
831
832 audio_config_base_t nonExistentConfig = AUDIO_CONFIG_BASE_INITIALIZER;
833 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700834 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100835 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
836
837 audio_config_base_t msdDirectConfig1 = AUDIO_CONFIG_BASE_INITIALIZER;
838 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700839 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100840 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
841
842 audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
843 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700844 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100845 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusecc9f422022-03-09 17:57:40 +0100846
847 audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
848 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
849 msdNonDirectConfig.sample_rate = 96000;
850 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
851
852 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
853 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
854 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
855 // before setting MSD patches the direct MSD configs return false
856 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
857 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
858 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
859
860 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
861 // Remove MSD output device to avoid patching to itself
862 outputDevices.remove(mMsdOutputDevice);
863 mManager->setMsdOutputPatches(&outputDevices);
864
865 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
866 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
867 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
868 // after setting MSD patches the direct MSD configs return true
869 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
870 ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
871 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
872
873 mManager->releaseMsdOutputPatches(outputDevices);
874
875 ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
876 ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
877 ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
878 // AFTER releasing MSD patches the direct MSD configs return false
879 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
880 ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
881 ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
882}
883
Dorin Drimusfae3c642022-03-17 18:36:30 +0100884TEST_P(AudioPolicyManagerTestMsd, GetDirectPlaybackSupportWithMsd) {
885 const audio_attributes_t attr = {
886 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
887 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
888
889 audio_config_t directConfig = AUDIO_CONFIG_INITIALIZER;
890 directConfig.format = AUDIO_FORMAT_DTS;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700891 directConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100892 directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
893
894 audio_config_t nonDirectConfig = AUDIO_CONFIG_INITIALIZER;
895 nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700896 nonDirectConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100897 nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
898
899 audio_config_t nonExistentConfig = AUDIO_CONFIG_INITIALIZER;
900 nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700901 nonExistentConfig.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100902 nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
903
904 audio_config_t msdDirectConfig1 = AUDIO_CONFIG_INITIALIZER;
905 msdDirectConfig1.format = AUDIO_FORMAT_AC3;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700906 msdDirectConfig1.sample_rate = k48000SamplingRate;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100907 msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
908
909 audio_config_t msdDirectConfig2 = AUDIO_CONFIG_INITIALIZER;
910 msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
Mikhail Naganov285c1732024-09-05 17:26:50 -0700911 msdDirectConfig2.sample_rate = k48000SamplingRate;
Dean Wheatley16809da2022-12-09 14:55:46 +1100912 msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
Dorin Drimusfae3c642022-03-17 18:36:30 +0100913
914 audio_config_t msdNonDirectConfig = AUDIO_CONFIG_INITIALIZER;
915 msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
916 msdNonDirectConfig.sample_rate = 96000;
917 msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
918
919 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
920 mManager->getDirectPlaybackSupport(&attr, &directConfig));
921 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
922 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
923 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
924 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
925 // before setting MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
926 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
927 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
928 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
929 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
930 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
931 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
932
933 DeviceVector outputDevices = mManager->getAvailableOutputDevices();
934 // Remove MSD output device to avoid patching to itself
935 outputDevices.remove(mMsdOutputDevice);
936 mManager->setMsdOutputPatches(&outputDevices);
937
938 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
939 mManager->getDirectPlaybackSupport(&attr, &directConfig));
940 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
941 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
942 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
943 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
944 // after setting MSD patches the direct MSD configs return values according to their flags
945 ASSERT_EQ(AUDIO_DIRECT_OFFLOAD_SUPPORTED,
946 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
947 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
948 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
949 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
950 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
951
952 mManager->releaseMsdOutputPatches(outputDevices);
953
954 ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
955 mManager->getDirectPlaybackSupport(&attr, &directConfig));
956 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
957 mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
958 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
959 mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
960 // after releasing MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
961 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
962 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
963 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
964 mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
965 ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
966 mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
967}
968
jiabin7c0205e2019-09-05 10:26:04 -0700969class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
970protected:
971 void SetUpManagerConfig() override;
972 virtual std::string getConfigFile() { return sDefaultConfig; }
973
974 static const std::string sExecutableDir;
975 static const std::string sDefaultConfig;
976};
977
978const std::string AudioPolicyManagerTestWithConfigurationFile::sExecutableDir =
979 base::GetExecutableDirectory() + "/";
980
981const std::string AudioPolicyManagerTestWithConfigurationFile::sDefaultConfig =
982 sExecutableDir + "test_audio_policy_configuration.xml";
983
984void AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig() {
Mikhail Naganov68e3f642023-04-28 13:06:32 -0700985 auto result = AudioPolicyConfig::loadFromCustomXmlConfigForTests(getConfigFile());
986 ASSERT_TRUE(result.ok());
987 mConfig = result.value();
jiabin7c0205e2019-09-05 10:26:04 -0700988}
989
990TEST_F(AudioPolicyManagerTestWithConfigurationFile, InitSuccess) {
991 // SetUp must finish with no assertions.
992}
993
994TEST_F(AudioPolicyManagerTestWithConfigurationFile, Dump) {
995 dumpToLog();
996}
997
Mikhail Naganov0805de12022-02-15 23:00:07 +0000998TEST_F(AudioPolicyManagerTestWithConfigurationFile, ListAudioPortsHasFlags) {
999 // Create an input for VOIP TX because it's not opened automatically like outputs are.
1000 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1001 audio_port_handle_t mixPortId = AUDIO_PORT_HANDLE_NONE;
1002 audio_source_t source = AUDIO_SOURCE_VOICE_COMMUNICATION;
François Gaffie6ebbce02023-07-19 13:27:53 +02001003 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source,
1004 AUDIO_FLAG_NONE, ""};
1005 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1006 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
1007 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
1008 AUDIO_CHANNEL_IN_MONO, 8000, AUDIO_INPUT_FLAG_VOIP_TX,
1009 &mixPortId));
Mikhail Naganov0805de12022-02-15 23:00:07 +00001010
1011 std::vector<audio_port_v7> ports;
1012 ASSERT_NO_FATAL_FAILURE(
1013 getAudioPorts(AUDIO_PORT_TYPE_MIX, AUDIO_PORT_ROLE_NONE, &ports));
1014 EXPECT_NE(0, ports.size());
1015 bool hasFlags = false, foundPrimary = false, foundVoipRx = false, foundVoipTx = false;
1016 for (const auto& port : ports) {
1017 if ((port.active_config.config_mask & AUDIO_PORT_CONFIG_FLAGS) != 0) {
1018 hasFlags = true;
1019 if (port.role == AUDIO_PORT_ROLE_SOURCE) {
1020 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
1021 foundPrimary = true;
1022 }
1023 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
1024 foundVoipRx = true;
1025 }
1026 } else if (port.role == AUDIO_PORT_ROLE_SINK) {
1027 if ((port.active_config.flags.input & AUDIO_INPUT_FLAG_VOIP_TX) != 0) {
1028 foundVoipTx = true;
1029 }
1030 }
1031 }
1032 }
1033 EXPECT_TRUE(hasFlags);
1034 EXPECT_TRUE(foundPrimary);
1035 EXPECT_TRUE(foundVoipRx);
1036 EXPECT_TRUE(foundVoipTx);
1037}
1038
Ram Mohan M594558d2022-06-14 14:42:44 +05301039TEST_F(AudioPolicyManagerTestWithConfigurationFile, HandleDeviceConfigChange) {
1040 {
1041 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1042
1043 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1044 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1045 "", "", AUDIO_FORMAT_LDAC));
1046 const auto currCounter = mClient->getRoutingUpdatedCounter();
1047 EXPECT_GT(currCounter, prevCounter);
1048 }
1049 {
1050 const auto prevCounter = mClient->getRoutingUpdatedCounter();
1051 // Update device configuration
1052 EXPECT_EQ(NO_ERROR, mManager->handleDeviceConfigChange(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1053 "" /*address*/, "" /*name*/,
1054 AUDIO_FORMAT_AAC));
1055
1056 // As mClient marks isReconfigA2dpSupported to false, device state needs to be toggled for
1057 // config changes to take effect
1058 const auto currCounter = mClient->getRoutingUpdatedCounter();
1059 EXPECT_GT(currCounter, prevCounter);
1060 }
1061}
1062
jiabina84c3d32022-12-02 18:59:55 +00001063TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferredMixerAttributes) {
1064 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1065 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1066 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1067 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1068 "", "", AUDIO_FORMAT_DEFAULT));
1069 auto devices = mManager->getAvailableOutputDevices();
1070 audio_port_handle_t maxPortId = 0;
1071 audio_port_handle_t speakerPortId;
1072 audio_port_handle_t usbPortId;
1073 for (auto device : devices) {
1074 maxPortId = std::max(maxPortId, device->getId());
1075 if (device->type() == AUDIO_DEVICE_OUT_SPEAKER) {
1076 speakerPortId = device->getId();
1077 } else if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1078 usbPortId = device->getId();
1079 }
1080 }
1081
1082 const uid_t uid = 1234;
1083 const uid_t otherUid = 4321;
1084 const audio_attributes_t mediaAttr = {
1085 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1086 .usage = AUDIO_USAGE_MEDIA,
1087 };
1088 const audio_attributes_t alarmAttr = {
1089 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
1090 .usage = AUDIO_USAGE_ALARM,
1091 };
1092
1093 std::vector<audio_mixer_attributes_t> mixerAttributes;
1094 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1095 for (const auto attrToSet : mixerAttributes) {
1096 audio_mixer_attributes_t attrFromQuery = AUDIO_MIXER_ATTRIBUTES_INITIALIZER;
1097
1098 // The given device is not available
1099 EXPECT_EQ(BAD_VALUE,
1100 mManager->setPreferredMixerAttributes(
1101 &mediaAttr, maxPortId + 1, uid, &attrToSet));
1102 // The only allowed device is USB
1103 EXPECT_EQ(BAD_VALUE,
1104 mManager->setPreferredMixerAttributes(
1105 &mediaAttr, speakerPortId, uid, &attrToSet));
1106 // The only allowed usage is media
1107 EXPECT_EQ(BAD_VALUE,
1108 mManager->setPreferredMixerAttributes(&alarmAttr, usbPortId, uid, &attrToSet));
1109 // Nothing set yet, must get null when query
1110 EXPECT_EQ(NAME_NOT_FOUND,
1111 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1112 EXPECT_EQ(NO_ERROR,
1113 mManager->setPreferredMixerAttributes(
1114 &mediaAttr, usbPortId, uid, &attrToSet));
1115 EXPECT_EQ(NO_ERROR,
1116 mManager->getPreferredMixerAttributes(&mediaAttr, usbPortId, &attrFromQuery));
1117 EXPECT_EQ(attrToSet.config.format, attrFromQuery.config.format);
1118 EXPECT_EQ(attrToSet.config.sample_rate, attrFromQuery.config.sample_rate);
1119 EXPECT_EQ(attrToSet.config.channel_mask, attrFromQuery.config.channel_mask);
1120 EXPECT_EQ(attrToSet.mixer_behavior, attrFromQuery.mixer_behavior);
1121 EXPECT_EQ(NAME_NOT_FOUND,
1122 mManager->clearPreferredMixerAttributes(&mediaAttr, speakerPortId, uid));
1123 EXPECT_EQ(PERMISSION_DENIED,
1124 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, otherUid));
1125 EXPECT_EQ(NO_ERROR,
1126 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1127 }
1128
1129 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1130 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1131 "", "", AUDIO_FORMAT_LDAC));
1132}
1133
jiabin3ff8d7d2022-12-13 06:27:44 +00001134TEST_F(AudioPolicyManagerTestWithConfigurationFile, RoutingChangedWithPreferredMixerAttributes) {
1135 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1136 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
1137 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1138 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1139 "", "", AUDIO_FORMAT_DEFAULT));
1140 auto devices = mManager->getAvailableOutputDevices();
1141 audio_port_handle_t usbPortId = AUDIO_PORT_HANDLE_NONE;
1142 for (auto device : devices) {
1143 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
1144 usbPortId = device->getId();
1145 break;
1146 }
1147 }
1148 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, usbPortId);
1149
1150 const uid_t uid = 1234;
1151 const audio_attributes_t mediaAttr = {
1152 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
1153 .usage = AUDIO_USAGE_MEDIA,
1154 };
1155
1156 std::vector<audio_mixer_attributes_t> mixerAttributes;
1157 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(usbPortId, mixerAttributes));
1158 EXPECT_GT(mixerAttributes.size(), 0);
1159 EXPECT_EQ(NO_ERROR,
1160 mManager->setPreferredMixerAttributes(
1161 &mediaAttr, usbPortId, uid, &mixerAttributes[0]));
1162
1163 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
1164 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1165 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
1166 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07001167 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001168 AUDIO_SESSION_NONE, uid);
1169 status_t status = mManager->startOutput(portId);
1170 if (status == DEAD_OBJECT) {
1171 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07001172 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
jiabin3ff8d7d2022-12-13 06:27:44 +00001173 AUDIO_SESSION_NONE, uid);
1174 status = mManager->startOutput(portId);
1175 }
1176 EXPECT_EQ(NO_ERROR, status);
1177 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
1178 EXPECT_NE(nullptr, mManager->getOutputs().valueFor(output));
1179 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1180 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1181 "", "", AUDIO_FORMAT_LDAC));
1182 // When BT device is connected, it will be selected as media device and trigger routing changed.
1183 // When this happens, existing output that is opened with preferred mixer attributes will be
1184 // closed and reopened with default config.
1185 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(output));
1186
1187 EXPECT_EQ(NO_ERROR,
1188 mManager->clearPreferredMixerAttributes(&mediaAttr, usbPortId, uid));
1189
1190 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
1191 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1192 "", "", AUDIO_FORMAT_LDAC));
1193 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
1194 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1195 "", "", AUDIO_FORMAT_LDAC));
1196}
1197
jiabin66acc432024-02-06 00:57:36 +00001198TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferExactConfigForInput) {
1199 const audio_channel_mask_t deviceChannelMask = AUDIO_CHANNEL_IN_3POINT1;
1200 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1201 mClient->addSupportedChannelMask(deviceChannelMask);
1202 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1203 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1204 "", "", AUDIO_FORMAT_DEFAULT));
1205
1206 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1207 audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1208 AUDIO_SOURCE_VOICE_COMMUNICATION,AUDIO_FLAG_NONE, ""};
1209 AudioPolicyInterface::input_type_t inputType;
1210 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1211 AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
1212 audio_config_base_t requestedConfig = {
Mikhail Naganov285c1732024-09-05 17:26:50 -07001213 .sample_rate = k48000SamplingRate,
jiabin66acc432024-02-06 00:57:36 +00001214 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1215 .format = AUDIO_FORMAT_PCM_16_BIT,
jiabin66acc432024-02-06 00:57:36 +00001216 };
1217 audio_config_base_t config = requestedConfig;
1218 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
Marvin Ramine5a122d2023-12-07 13:57:59 +01001219 uint32_t *virtualDeviceId = 0;
jiabin66acc432024-02-06 00:57:36 +00001220 ASSERT_EQ(OK, mManager->getInputForAttr(
1221 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1222 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001223 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001224 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1225 ASSERT_TRUE(equals(requestedConfig, config));
1226
1227 attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
1228 AUDIO_SOURCE_VOICE_COMMUNICATION, AUDIO_FLAG_NONE, ""};
1229 requestedConfig.channel_mask = deviceChannelMask;
1230 config = requestedConfig;
1231 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1232 input = AUDIO_PORT_HANDLE_NONE;
1233 portId = AUDIO_PORT_HANDLE_NONE;
1234 ASSERT_EQ(OK, mManager->getInputForAttr(
1235 &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
1236 AUDIO_INPUT_FLAG_NONE,
Marvin Ramine5a122d2023-12-07 13:57:59 +01001237 &selectedDeviceId, &inputType, &portId, virtualDeviceId));
jiabin66acc432024-02-06 00:57:36 +00001238 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
1239 ASSERT_TRUE(equals(requestedConfig, config));
1240
1241 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1242 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1243 "", "", AUDIO_FORMAT_DEFAULT));
1244}
1245
Mikhail Naganovc66ffc12024-05-30 16:56:25 -07001246TEST_F(AudioPolicyManagerTestWithConfigurationFile, CheckInputsForDeviceClosesStreams) {
1247 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1248 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1249 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1250 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1251 // Since 'checkInputsForDevice' is called as part of the 'setDeviceConnectionState',
1252 // call it directly here, as we need to ensure that it does not keep all intermediate
1253 // streams opened, as it may cause a rejection from the HAL based on the cap.
1254 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1255 sp<DeviceDescriptor> device = mManager->getHwModules().getDeviceDescriptor(
1256 AUDIO_DEVICE_IN_USB_DEVICE, "", "", AUDIO_FORMAT_DEFAULT, true /*allowToCreate*/);
1257 ASSERT_NE(nullptr, device.get());
1258 EXPECT_EQ(NO_ERROR,
1259 mManager->checkInputsForDevice(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
1260 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1261}
1262
1263TEST_F(AudioPolicyManagerTestWithConfigurationFile, SetDeviceConnectionStateClosesStreams) {
1264 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
1265 mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
1266 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
1267 mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
1268 const size_t streamCountBefore = mClient->getOpenedInputsCount();
1269 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
1270 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1271 "", "", AUDIO_FORMAT_DEFAULT));
1272 EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
1273}
1274
jiabin7c0205e2019-09-05 10:26:04 -07001275class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
jiabinf4eb15a2019-08-28 15:31:47 -07001276protected:
jiabinf4eb15a2019-08-28 15:31:47 -07001277 void TearDown() override;
1278
1279 status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
1280 std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001281 const std::vector<AudioMixMatchCriterion>& matchCriteria);
Marvin Raminbdefaf02023-11-01 09:10:32 +01001282
Marvin Raminabd9b892023-11-17 16:36:27 +01001283 status_t addPolicyMix(const AudioMix& mix);
1284
1285 status_t removePolicyMixes(const Vector<AudioMix>& mixes);
1286
Marvin Raminbdefaf02023-11-01 09:10:32 +01001287 std::vector<AudioMix> getRegisteredPolicyMixes();
jiabinf4eb15a2019-08-28 15:31:47 -07001288 void clearPolicyMix();
jiabin24ff57a2023-11-27 21:06:51 +00001289 void addPolicyMixAndStartInputForLoopback(
1290 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1291 const audio_config_t& audioConfig,
1292 const std::vector<AudioMixMatchCriterion>& matchCriteria,
1293 audio_session_t session=AUDIO_SESSION_NONE,
1294 audio_config_base_t config=DEFAULT_INPUT_CONFIG,
1295 audio_input_flags_t inputFlags=AUDIO_INPUT_FLAG_NONE);
jiabinf4eb15a2019-08-28 15:31:47 -07001296
1297 Vector<AudioMix> mAudioMixes;
jiabinf4eb15a2019-08-28 15:31:47 -07001298 const std::string mMixAddress = "remote_submix_media";
jiabin24ff57a2023-11-27 21:06:51 +00001299
1300 audio_port_handle_t mLoopbackInputPortId = AUDIO_PORT_HANDLE_NONE;
1301 std::unique_ptr<RecordingActivityTracker> mTracker;
1302 struct audio_port_v7 mInjectionPort;
1303
1304 constexpr static const audio_config_base_t DEFAULT_INPUT_CONFIG = {
1305 .sample_rate = k48000SamplingRate,
1306 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
1307 .format = AUDIO_FORMAT_PCM_16_BIT
1308 };
jiabinf4eb15a2019-08-28 15:31:47 -07001309};
1310
jiabinf4eb15a2019-08-28 15:31:47 -07001311void AudioPolicyManagerTestDynamicPolicy::TearDown() {
jiabin24ff57a2023-11-27 21:06:51 +00001312 clearPolicyMix();
jiabin7c0205e2019-09-05 10:26:04 -07001313 AudioPolicyManagerTestWithConfigurationFile::TearDown();
jiabinf4eb15a2019-08-28 15:31:47 -07001314}
1315
1316status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
1317 audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001318 const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
1319 AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
jiabinf4eb15a2019-08-28 15:31:47 -07001320 String8(mixAddress.c_str()), 0);
1321 myAudioMix.mDeviceType = deviceType;
Marvin Ramin0783e202024-03-05 12:45:50 +01001322 myAudioMix.mToken = sp<BBinder>::make();
jiabinf4eb15a2019-08-28 15:31:47 -07001323 // Clear mAudioMix before add new one to make sure we don't add already exist mixes.
1324 mAudioMixes.clear();
Marvin Raminabd9b892023-11-17 16:36:27 +01001325 return addPolicyMix(myAudioMix);
1326}
1327
1328status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(const AudioMix& mix) {
1329 mAudioMixes.add(mix);
jiabinf4eb15a2019-08-28 15:31:47 -07001330
1331 // As the policy mixes registration may fail at some case,
1332 // caller need to check the returned status.
1333 status_t ret = mManager->registerPolicyMixes(mAudioMixes);
1334 return ret;
1335}
1336
Marvin Raminabd9b892023-11-17 16:36:27 +01001337status_t AudioPolicyManagerTestDynamicPolicy::removePolicyMixes(const Vector<AudioMix>& mixes) {
1338 status_t ret = mManager->unregisterPolicyMixes(mixes);
1339 return ret;
1340}
1341
Marvin Raminbdefaf02023-11-01 09:10:32 +01001342std::vector<AudioMix> AudioPolicyManagerTestDynamicPolicy::getRegisteredPolicyMixes() {
1343 std::vector<AudioMix> audioMixes;
1344 if (mManager != nullptr) {
1345 status_t ret = mManager->getRegisteredPolicyMixes(audioMixes);
1346 EXPECT_EQ(NO_ERROR, ret);
1347 }
1348 return audioMixes;
1349}
1350
jiabinf4eb15a2019-08-28 15:31:47 -07001351void AudioPolicyManagerTestDynamicPolicy::clearPolicyMix() {
1352 if (mManager != nullptr) {
jiabin24ff57a2023-11-27 21:06:51 +00001353 mManager->stopInput(mLoopbackInputPortId);
jiabinf4eb15a2019-08-28 15:31:47 -07001354 mManager->unregisterPolicyMixes(mAudioMixes);
1355 }
1356 mAudioMixes.clear();
1357}
1358
jiabin24ff57a2023-11-27 21:06:51 +00001359void AudioPolicyManagerTestDynamicPolicy::addPolicyMixAndStartInputForLoopback(
1360 int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
1361 const audio_config_t& audioConfig,
1362 const std::vector<AudioMixMatchCriterion>& matchCriteria, audio_session_t session,
1363 audio_config_base_t config, audio_input_flags_t inputFlags) {
1364 ASSERT_EQ(NO_ERROR,
1365 addPolicyMix(mixType, mixFlag, deviceType, mixAddress, audioConfig, matchCriteria));
1366 if ((mixFlag & MIX_ROUTE_FLAG_LOOP_BACK) != MIX_ROUTE_FLAG_LOOP_BACK) {
1367 return;
1368 }
1369
1370 mTracker.reset(new RecordingActivityTracker());
1371 struct audio_port_v7 extractionPort;
1372 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1373 mixAddress, &extractionPort));
1374 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
1375 audio_source_t source = AUDIO_SOURCE_REMOTE_SUBMIX;
1376 audio_attributes_t attr = {
1377 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, source, AUDIO_FLAG_NONE, ""};
1378 std::string tags = "addr=" + mMixAddress;
1379 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
1380 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
1381 ASSERT_NO_FATAL_FAILURE(
1382 getInputForAttr(attr, &input, session, mTracker->getRiid(),
1383 &selectedDeviceId, config.format, config.channel_mask,
1384 config.sample_rate, inputFlags, &mLoopbackInputPortId));
1385 ASSERT_EQ(NO_ERROR, mManager->startInput(mLoopbackInputPortId));
1386 ASSERT_EQ(extractionPort.id, selectedDeviceId);
1387
1388 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1389 mMixAddress, &mInjectionPort));
1390}
1391
jiabinf4eb15a2019-08-28 15:31:47 -07001392TEST_F(AudioPolicyManagerTestDynamicPolicy, InitSuccess) {
jiabin7c0205e2019-09-05 10:26:04 -07001393 // SetUp must finish with no assertions
jiabinf4eb15a2019-08-28 15:31:47 -07001394}
1395
1396TEST_F(AudioPolicyManagerTestDynamicPolicy, Dump) {
1397 dumpToLog();
1398}
1399
1400TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyMixes) {
1401 status_t ret;
1402 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1403
1404 // Only capture of playback is allowed in LOOP_BACK &RENDER mode
1405 ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001406 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001407 ASSERT_EQ(INVALID_OPERATION, ret);
1408
1409 // Fail due to the device is already connected.
1410 clearPolicyMix();
1411 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001412 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001413 ASSERT_EQ(INVALID_OPERATION, ret);
1414
1415 // The first time to register policy mixes with valid parameter should succeed.
1416 clearPolicyMix();
1417 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1418 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001419 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001420 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001421 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001422 ASSERT_EQ(NO_ERROR, ret);
1423 // Registering the same policy mixes should fail.
1424 ret = mManager->registerPolicyMixes(mAudioMixes);
1425 ASSERT_EQ(INVALID_OPERATION, ret);
1426
jiabinf4eb15a2019-08-28 15:31:47 -07001427 // Registration should fail due to device not found.
1428 // Note that earpiece is not present in the test configuration file.
1429 // This will need to be updated if earpiece is added in the test configuration file.
jiabin7c0205e2019-09-05 10:26:04 -07001430 clearPolicyMix();
jiabinf4eb15a2019-08-28 15:31:47 -07001431 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001432 AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001433 ASSERT_EQ(INVALID_OPERATION, ret);
1434
1435 // Registration should fail due to output not found.
1436 clearPolicyMix();
1437 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001438 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001439 ASSERT_EQ(INVALID_OPERATION, ret);
1440
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001441 // The first time to register valid loopback policy mix should succeed.
jiabinf4eb15a2019-08-28 15:31:47 -07001442 clearPolicyMix();
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001443 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1444 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001445 ASSERT_EQ(NO_ERROR, ret);
Jan Sebechlebskycd33d8d2023-06-07 10:45:50 +02001446 // Registering the render policy for the loopback address should succeed.
1447 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
1448 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "addr", audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001449 ASSERT_EQ(INVALID_OPERATION, ret);
1450}
1451
1452TEST_F(AudioPolicyManagerTestDynamicPolicy, UnregisterPolicyMixes) {
1453 status_t ret;
1454 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1455
1456 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1457 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001458 audioConfig.sample_rate = k48000SamplingRate;
jiabinf4eb15a2019-08-28 15:31:47 -07001459 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001460 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
jiabinf4eb15a2019-08-28 15:31:47 -07001461 ASSERT_EQ(NO_ERROR, ret);
1462
1463 // After successfully registering policy mixes, it should be able to unregister.
1464 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1465 ASSERT_EQ(NO_ERROR, ret);
1466
1467 // After unregistering policy mixes successfully, it should fail unregistering
1468 // the same policy mixes as they are not registered.
1469 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1470 ASSERT_EQ(INVALID_OPERATION, ret);
jiabin7c0205e2019-09-05 10:26:04 -07001471}
jiabinf4eb15a2019-08-28 15:31:47 -07001472
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001473TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
1474 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1475 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1476 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1477 audioConfig.sample_rate = k48000SamplingRate;
1478
1479 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1480 createUidCriterion(/*uid=*/42),
1481 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1482 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1483 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1484 mixMatchCriteria);
1485 ASSERT_EQ(NO_ERROR, ret);
1486}
1487
1488TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
1489 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1490 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1491 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1492 audioConfig.sample_rate = k48000SamplingRate;
1493
1494 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1495 createUidCriterion(/*uid=*/42),
1496 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1497 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1498 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1499 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1500 mixMatchCriteria);
1501 ASSERT_EQ(INVALID_OPERATION, ret);
1502}
1503
Marvin Raminbdefaf02023-11-01 09:10:32 +01001504TEST_F_WITH_FLAGS(
1505 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminabd9b892023-11-17 16:36:27 +01001506 RegisterInvalidMixesDoesNotImpactPriorMixes,
1507 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1508 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1509) {
1510 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1511 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1512 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1513 audioConfig.sample_rate = k48000SamplingRate;
1514
1515 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1516 createUidCriterion(/*uid=*/42),
1517 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1518 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1519 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1520 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1521
1522 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001523 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001524
1525 ASSERT_EQ(NO_ERROR, ret);
1526
1527 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1528 ASSERT_EQ(1, registeredMixes.size());
1529
1530 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1531 createUidCriterion(/*uid=*/42),
1532 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1533 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1534
1535 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1536 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1537 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1538
Marvin Ramin0783e202024-03-05 12:45:50 +01001539 ret = addPolicyMix(invalidAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001540
1541 ASSERT_EQ(INVALID_OPERATION, ret);
1542
1543 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1544 ASSERT_EQ(registeredMixes.size(), remainingMixes.size());
1545}
1546
1547TEST_F_WITH_FLAGS(
1548 AudioPolicyManagerTestDynamicPolicy,
1549 UnregisterInvalidMixesReturnsError,
1550 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
1551 ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
1552) {
1553 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1554 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1555 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1556 audioConfig.sample_rate = k48000SamplingRate;
1557
1558 std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
1559 createUidCriterion(/*uid=*/42),
1560 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1561 AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1562 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
1563 validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1564
1565 mAudioMixes.clear();
Marvin Ramin0783e202024-03-05 12:45:50 +01001566 status_t ret = addPolicyMix(validAudioMix);
Marvin Raminabd9b892023-11-17 16:36:27 +01001567
1568 ASSERT_EQ(NO_ERROR, ret);
1569
1570 std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
1571 ASSERT_EQ(1, registeredMixes.size());
1572
1573 std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
1574 createUidCriterion(/*uid=*/42),
1575 createUidCriterion(/*uid=*/1235, /*exclude=*/true),
1576 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1577
1578 AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
1579 MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
Marvin Ramin0783e202024-03-05 12:45:50 +01001580 invalidAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Marvin Raminabd9b892023-11-17 16:36:27 +01001581
1582 Vector<AudioMix> mixes;
1583 mixes.add(invalidAudioMix);
1584 mixes.add(validAudioMix);
1585 ret = removePolicyMixes(mixes);
1586
1587 ASSERT_EQ(INVALID_OPERATION, ret);
1588
1589 std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
1590 EXPECT_THAT(remainingMixes, IsEmpty());
1591}
1592
1593TEST_F_WITH_FLAGS(
1594 AudioPolicyManagerTestDynamicPolicy,
Marvin Raminbdefaf02023-11-01 09:10:32 +01001595 GetRegisteredPolicyMixes,
1596 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1597) {
1598 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1599 EXPECT_THAT(mixes, IsEmpty());
1600}
1601
1602TEST_F_WITH_FLAGS(AudioPolicyManagerTestDynamicPolicy,
1603 AddPolicyMixAndVerifyGetRegisteredPolicyMixes,
1604 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
1605) {
1606 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1607 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1608 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
1609 audioConfig.sample_rate = k48000SamplingRate;
1610
1611 std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
1612 createUidCriterion(/*uid=*/42),
1613 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
1614 status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1615 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
1616 mixMatchCriteria);
1617 ASSERT_EQ(NO_ERROR, ret);
1618
1619 std::vector<AudioMix> mixes = getRegisteredPolicyMixes();
1620 ASSERT_EQ(mixes.size(), 1);
1621
1622 const AudioMix& mix = mixes[0];
1623 ASSERT_EQ(mix.mCriteria.size(), mixMatchCriteria.size());
1624 for (uint32_t i = 0; i < mixMatchCriteria.size(); i++) {
1625 EXPECT_EQ(mix.mCriteria[i].mRule, mixMatchCriteria[i].mRule);
1626 EXPECT_EQ(mix.mCriteria[i].mValue.mUsage, mixMatchCriteria[i].mValue.mUsage);
1627 }
1628 EXPECT_EQ(mix.mDeviceType, AUDIO_DEVICE_OUT_REMOTE_SUBMIX);
1629 EXPECT_EQ(mix.mRouteFlags, MIX_ROUTE_FLAG_LOOP_BACK);
1630 EXPECT_EQ(mix.mMixType, MIX_TYPE_PLAYERS);
1631 EXPECT_EQ(mix.mFormat.channel_mask, audioConfig.channel_mask);
1632 EXPECT_EQ(mix.mFormat.format, audioConfig.format);
1633 EXPECT_EQ(mix.mFormat.sample_rate, audioConfig.sample_rate);
1634 EXPECT_EQ(mix.mFormat.frame_count, audioConfig.frame_count);
1635}
1636
Kriti Dangef6be8f2020-11-05 11:58:19 +01001637class AudioPolicyManagerTestForHdmi
Mikhail Naganov18885d32021-10-01 13:03:09 -07001638 : public AudioPolicyManagerTestWithConfigurationFile,
1639 public testing::WithParamInterface<audio_format_t> {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001640protected:
1641 void SetUp() override;
1642 std::string getConfigFile() override { return sTvConfig; }
Kriti Dang6537def2021-03-02 13:46:59 +01001643 std::map<audio_format_t, bool> getSurroundFormatsHelper();
1644 std::vector<audio_format_t> getReportedSurroundFormatsHelper();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001645 std::unordered_set<audio_format_t> getFormatsFromPorts();
Kriti Dangef6be8f2020-11-05 11:58:19 +01001646 void TearDown() override;
1647
1648 static const std::string sTvConfig;
1649
1650};
1651
1652const std::string AudioPolicyManagerTestForHdmi::sTvConfig =
1653 AudioPolicyManagerTestForHdmi::sExecutableDir +
1654 "test_settop_box_surround_configuration.xml";
1655
1656void AudioPolicyManagerTestForHdmi::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001657 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUp());
Mikhail Naganov83caee02021-10-05 15:52:01 -07001658 mClient->addSupportedFormat(AUDIO_FORMAT_AC3);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001659 mClient->addSupportedFormat(AUDIO_FORMAT_E_AC3);
jiabin12537fc2023-10-12 17:56:08 +00001660 mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001661 mManager->setDeviceConnectionState(
1662 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1663 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1664}
1665
1666void AudioPolicyManagerTestForHdmi::TearDown() {
1667 mManager->setDeviceConnectionState(
1668 AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1669 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT);
1670 AudioPolicyManagerTest::TearDown();
1671}
1672
1673std::map<audio_format_t, bool>
Kriti Dang6537def2021-03-02 13:46:59 +01001674 AudioPolicyManagerTestForHdmi::getSurroundFormatsHelper() {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001675 unsigned int numSurroundFormats = 0;
1676 std::map<audio_format_t, bool> surroundFormatsMap;
1677 status_t ret = mManager->getSurroundFormats(
1678 &numSurroundFormats, nullptr /* surroundFormats */,
Kriti Dang6537def2021-03-02 13:46:59 +01001679 nullptr /* surroundFormatsEnabled */);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001680 EXPECT_EQ(NO_ERROR, ret);
1681 if (ret != NO_ERROR) {
1682 return surroundFormatsMap;
1683 }
1684 audio_format_t surroundFormats[numSurroundFormats];
1685 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1686 bool surroundFormatsEnabled[numSurroundFormats];
1687 memset(surroundFormatsEnabled, 0, sizeof(bool) * numSurroundFormats);
1688 ret = mManager->getSurroundFormats(
Kriti Dang6537def2021-03-02 13:46:59 +01001689 &numSurroundFormats, surroundFormats, surroundFormatsEnabled);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001690 EXPECT_EQ(NO_ERROR, ret);
1691 if (ret != NO_ERROR) {
1692 return surroundFormatsMap;
1693 }
1694 for (int i = 0; i< numSurroundFormats; i++) {
1695 surroundFormatsMap[surroundFormats[i]] = surroundFormatsEnabled[i];
1696 }
1697 return surroundFormatsMap;
1698}
1699
Kriti Dang6537def2021-03-02 13:46:59 +01001700std::vector<audio_format_t> AudioPolicyManagerTestForHdmi::getReportedSurroundFormatsHelper() {
1701 unsigned int numSurroundFormats = 0;
1702 std::vector<audio_format_t> surroundFormatsVector;
1703 status_t ret = mManager->getReportedSurroundFormats(
1704 &numSurroundFormats, nullptr /* surroundFormats */);
1705 EXPECT_EQ(NO_ERROR, ret);
1706 if (ret != NO_ERROR) {
1707 return surroundFormatsVector;
1708 }
1709 audio_format_t surroundFormats[numSurroundFormats];
1710 memset(surroundFormats, 0, sizeof(audio_format_t) * numSurroundFormats);
1711 ret = mManager->getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
1712 EXPECT_EQ(NO_ERROR, ret);
1713 if (ret != NO_ERROR) {
1714 return surroundFormatsVector;
1715 }
1716 for (const auto &surroundFormat : surroundFormats) {
1717 surroundFormatsVector.push_back(surroundFormat);
1718 }
1719 return surroundFormatsVector;
1720}
1721
Kriti Dangef6be8f2020-11-05 11:58:19 +01001722std::unordered_set<audio_format_t>
1723 AudioPolicyManagerTestForHdmi::getFormatsFromPorts() {
1724 uint32_t numPorts = 0;
1725 uint32_t generation1;
1726 status_t ret;
1727 std::unordered_set<audio_format_t> formats;
1728 ret = mManager->listAudioPorts(
1729 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
1730 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1731 if (ret != NO_ERROR) {
1732 return formats;
1733 }
jiabin19cdba52020-11-24 11:28:58 -08001734 struct audio_port_v7 ports[numPorts];
Kriti Dangef6be8f2020-11-05 11:58:19 +01001735 ret = mManager->listAudioPorts(
1736 AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation1);
1737 EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
1738 if (ret != NO_ERROR) {
1739 return formats;
1740 }
1741 for (const auto &port : ports) {
jiabin19cdba52020-11-24 11:28:58 -08001742 for (size_t i = 0; i < port.num_audio_profiles; ++i) {
1743 formats.insert(port.audio_profiles[i].format);
1744 }
Kriti Dangef6be8f2020-11-05 11:58:19 +01001745 }
1746 return formats;
1747}
1748
Mikhail Naganov18885d32021-10-01 13:03:09 -07001749TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsReturnsSupportedFormats) {
Kriti Dangef6be8f2020-11-05 11:58:19 +01001750 mManager->setForceUse(
1751 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001752 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001753 ASSERT_EQ(1, surroundFormats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001754}
1755
Mikhail Naganov18885d32021-10-01 13:03:09 -07001756TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001757 GetSurroundFormatsReturnsManipulatedFormats) {
1758 mManager->setForceUse(
1759 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1760
1761 status_t ret =
Mikhail Naganov18885d32021-10-01 13:03:09 -07001762 mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001763 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001764 auto surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001765 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1766 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001767
Mikhail Naganov18885d32021-10-01 13:03:09 -07001768 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001769 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001770 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001771 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1772 ASSERT_TRUE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001773
Mikhail Naganov18885d32021-10-01 13:03:09 -07001774 ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001775 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001776 surroundFormats = getSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001777 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1778 ASSERT_FALSE(surroundFormats[GetParam()]);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001779}
1780
Mikhail Naganov18885d32021-10-01 13:03:09 -07001781TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001782 ListAudioPortsReturnManipulatedHdmiFormats) {
1783 mManager->setForceUse(
1784 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1785
Mikhail Naganov18885d32021-10-01 13:03:09 -07001786 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/));
jiabin12537fc2023-10-12 17:56:08 +00001787 auto formats = getFormatsFromPorts();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001788 ASSERT_EQ(1, formats.count(GetParam()));
jiabin12537fc2023-10-12 17:56:08 +00001789
1790 ASSERT_EQ(NO_ERROR, mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/));
1791 formats = getFormatsFromPorts();
1792 ASSERT_EQ(0, formats.count(GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001793}
1794
Mikhail Naganov18885d32021-10-01 13:03:09 -07001795TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001796 GetReportedSurroundFormatsReturnsHdmiReportedFormats) {
1797 mManager->setForceUse(
1798 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Kriti Dang6537def2021-03-02 13:46:59 +01001799 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001800 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001801}
1802
Mikhail Naganov18885d32021-10-01 13:03:09 -07001803TEST_P(AudioPolicyManagerTestForHdmi,
Kriti Dangef6be8f2020-11-05 11:58:19 +01001804 GetReportedSurroundFormatsReturnsNonManipulatedHdmiReportedFormats) {
1805 mManager->setForceUse(
1806 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL);
1807
Mikhail Naganov18885d32021-10-01 13:03:09 -07001808 status_t ret = mManager->setSurroundFormatEnabled(GetParam(), false /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001809 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001810 auto surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001811 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001812
Mikhail Naganov18885d32021-10-01 13:03:09 -07001813 ret = mManager->setSurroundFormatEnabled(GetParam(), true /*enabled*/);
Kriti Dangef6be8f2020-11-05 11:58:19 +01001814 ASSERT_EQ(NO_ERROR, ret);
Kriti Dang6537def2021-03-02 13:46:59 +01001815 surroundFormats = getReportedSurroundFormatsHelper();
Mikhail Naganov18885d32021-10-01 13:03:09 -07001816 ASSERT_EQ(1, std::count(surroundFormats.begin(), surroundFormats.end(), GetParam()));
Kriti Dangef6be8f2020-11-05 11:58:19 +01001817}
1818
Mikhail Naganov18885d32021-10-01 13:03:09 -07001819TEST_P(AudioPolicyManagerTestForHdmi, GetSurroundFormatsIgnoresSupportedFormats) {
1820 mManager->setForceUse(
1821 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER);
1822 auto surroundFormats = getSurroundFormatsHelper();
1823 ASSERT_EQ(1, surroundFormats.count(GetParam()));
1824 ASSERT_FALSE(surroundFormats[GetParam()]);
1825}
1826
1827INSTANTIATE_TEST_SUITE_P(SurroundFormatSupport, AudioPolicyManagerTestForHdmi,
1828 testing::Values(AUDIO_FORMAT_AC3, AUDIO_FORMAT_E_AC3),
1829 [](const ::testing::TestParamInfo<AudioPolicyManagerTestForHdmi::ParamType>& info) {
1830 return audio_format_to_string(info.param);
1831 });
1832
jiabin7c0205e2019-09-05 10:26:04 -07001833class AudioPolicyManagerTestDPNoRemoteSubmixModule : public AudioPolicyManagerTestDynamicPolicy {
1834protected:
1835 std::string getConfigFile() override { return sPrimaryOnlyConfig; }
1836
1837 static const std::string sPrimaryOnlyConfig;
1838};
1839
1840const std::string AudioPolicyManagerTestDPNoRemoteSubmixModule::sPrimaryOnlyConfig =
1841 sExecutableDir + "test_audio_policy_primary_only_configuration.xml";
1842
1843TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, InitSuccess) {
1844 // SetUp must finish with no assertions.
1845}
1846
1847TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, Dump) {
1848 dumpToLog();
1849}
1850
1851TEST_F(AudioPolicyManagerTestDPNoRemoteSubmixModule, RegistrationFailure) {
1852 // Registration/Unregistration should fail due to module for remote submix not found.
1853 status_t ret;
1854 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1855 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1856 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001857 audioConfig.sample_rate = k48000SamplingRate;
jiabin7c0205e2019-09-05 10:26:04 -07001858 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky0e7b2f12022-08-18 14:40:37 +02001859 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
jiabin7c0205e2019-09-05 10:26:04 -07001860 ASSERT_EQ(INVALID_OPERATION, ret);
1861
jiabinf4eb15a2019-08-28 15:31:47 -07001862 ret = mManager->unregisterPolicyMixes(mAudioMixes);
1863 ASSERT_EQ(INVALID_OPERATION, ret);
1864}
1865
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001866struct DPTestParam {
1867 DPTestParam(const std::vector<AudioMixMatchCriterion>& mixCriteria,
1868 bool expected_match = false)
1869 : mixCriteria(mixCriteria), attributes(defaultAttr), session(AUDIO_SESSION_NONE),
1870 expected_match(expected_match) {}
1871
1872 DPTestParam& withUsage(audio_usage_t usage) {
1873 attributes.usage = usage;
1874 return *this;
1875 }
1876
1877 DPTestParam& withTags(const char *tags) {
1878 std::strncpy(attributes.tags, tags, sizeof(attributes.tags));
1879 return *this;
1880 }
1881
1882 DPTestParam& withSource(audio_source_t source) {
1883 attributes.source = source;
1884 return *this;
1885 }
1886
1887 DPTestParam& withSessionId(audio_session_t sessionId) {
1888 session = sessionId;
1889 return *this;
1890 }
1891
1892 std::vector<AudioMixMatchCriterion> mixCriteria;
1893 audio_attributes_t attributes;
1894 audio_session_t session;
1895 bool expected_match;
1896};
1897
jiabinf4eb15a2019-08-28 15:31:47 -07001898class AudioPolicyManagerTestDPPlaybackReRouting : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001899 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07001900protected:
1901 void SetUp() override;
jiabinf4eb15a2019-08-28 15:31:47 -07001902};
1903
1904void AudioPolicyManagerTestDPPlaybackReRouting::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07001905 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07001906
1907 mTracker.reset(new RecordingActivityTracker());
1908
1909 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
1910 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1911 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11001912 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001913
1914 DPTestParam param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00001915 ASSERT_NO_FATAL_FAILURE(
1916 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
1917 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria,
1918 param.session));
jiabinf4eb15a2019-08-28 15:31:47 -07001919}
1920
jiabinf4eb15a2019-08-28 15:31:47 -07001921TEST_P(AudioPolicyManagerTestDPPlaybackReRouting, PlaybackReRouting) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001922 const DPTestParam param = GetParam();
1923 const audio_attributes_t& attr = param.attributes;
jiabinf4eb15a2019-08-28 15:31:47 -07001924
jiabin7c0205e2019-09-05 10:26:04 -07001925 audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07001926 getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11001927 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001928 attr, param.session);
1929 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07001930 EXPECT_EQ(mInjectionPort.id, playbackRoutedPortId);
1931 } else {
1932 EXPECT_NE(mInjectionPort.id, playbackRoutedPortId);
1933 }
1934}
1935
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001936const std::vector<AudioMixMatchCriterion> USAGE_MEDIA_ALARM_CRITERIA = {
1937 createUsageCriterion(AUDIO_USAGE_MEDIA),
1938 createUsageCriterion(AUDIO_USAGE_ALARM)
1939};
jiabinf4eb15a2019-08-28 15:31:47 -07001940
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001941INSTANTIATE_TEST_SUITE_P(
1942 PlaybackReroutingUsageMatch,
1943 AudioPolicyManagerTestDPPlaybackReRouting,
1944 testing::Values(
1945 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1946 .withUsage(AUDIO_USAGE_MEDIA),
1947 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1948 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=other"),
1949 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1950 .withUsage(AUDIO_USAGE_ALARM),
1951 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1952 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION),
1953 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1954 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING),
1955 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1956 .withUsage(AUDIO_USAGE_NOTIFICATION),
1957 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1958 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE),
1959 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1960 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST),
1961 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1962 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT),
1963 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1964 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED),
1965 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1966 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT),
1967 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1968 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY),
1969 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1970 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE),
1971 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1972 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION),
1973 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1974 .withUsage(AUDIO_USAGE_GAME),
1975 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ false)
1976 .withUsage(AUDIO_USAGE_ASSISTANT)));
jiabinf4eb15a2019-08-28 15:31:47 -07001977
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02001978INSTANTIATE_TEST_SUITE_P(
1979 PlaybackReroutingAddressPriorityMatch,
1980 AudioPolicyManagerTestDPPlaybackReRouting,
1981 testing::Values(
1982 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1983 .withUsage(AUDIO_USAGE_MEDIA).withTags("addr=remote_submix_media"),
1984 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1985 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION).withTags("addr=remote_submix_media"),
1986 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1987 .withUsage(AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING)
1988 .withTags("addr=remote_submix_media"),
1989 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1990 .withUsage(AUDIO_USAGE_ALARM)
1991 .withTags("addr=remote_submix_media"),
1992 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1993 .withUsage(AUDIO_USAGE_NOTIFICATION)
1994 .withTags("addr=remote_submix_media"),
1995 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1996 .withUsage(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE)
1997 .withTags("addr=remote_submix_media"),
1998 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
1999 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST)
2000 .withTags("addr=remote_submix_media"),
2001 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2002 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
2003 .withTags("addr=remote_submix_media"),
2004 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2005 .withUsage(AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED)
2006 .withTags("addr=remote_submix_media"),
2007 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2008 .withUsage(AUDIO_USAGE_NOTIFICATION_EVENT)
2009 .withTags("addr=remote_submix_media"),
2010 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2011 .withUsage(AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY)
2012 .withTags("addr=remote_submix_media"),
2013 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2014 .withUsage(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
2015 .withTags("addr=remote_submix_media"),
2016 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2017 .withUsage(AUDIO_USAGE_ASSISTANCE_SONIFICATION)
2018 .withTags("addr=remote_submix_media"),
2019 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2020 .withUsage(AUDIO_USAGE_GAME)
2021 .withTags("addr=remote_submix_media"),
2022 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2023 .withUsage(AUDIO_USAGE_VIRTUAL_SOURCE)
2024 .withTags("addr=remote_submix_media"),
2025 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2026 .withUsage(AUDIO_USAGE_ASSISTANT)
Jan Sebechlebskybc56bcd2022-09-26 13:15:19 +02002027 .withTags("addr=remote_submix_media"),
2028 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2029 .withUsage(AUDIO_USAGE_ASSISTANT)
2030 .withTags("sometag;addr=remote_submix_media;othertag=somevalue"),
2031 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2032 .withUsage(AUDIO_USAGE_ASSISTANT)
2033 .withTags("addr=remote_submix_media;othertag"),
2034 DPTestParam(USAGE_MEDIA_ALARM_CRITERIA, /*expected_match=*/ true)
2035 .withUsage(AUDIO_USAGE_ASSISTANT)
2036 .withTags("sometag;othertag;addr=remote_submix_media")));
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002037
2038static constexpr audio_session_t TEST_SESSION_ID = static_cast<audio_session_t>(42);
2039static constexpr audio_session_t OTHER_SESSION_ID = static_cast<audio_session_t>(77);
2040
2041INSTANTIATE_TEST_SUITE_P(
2042 PlaybackReRoutingWithSessionId,
2043 AudioPolicyManagerTestDPPlaybackReRouting,
2044 testing::Values(
2045 // Mix is matched because the session id matches the one specified by the mix rule.
2046 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2047 /*expected_match=*/ true)
2048 .withSessionId(TEST_SESSION_ID),
2049 // Mix is not matched because the session id doesn't match the one specified
2050 // by the mix rule.
2051 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2052 /*expected_match=*/ false)
2053 .withSessionId(OTHER_SESSION_ID),
2054 // Mix is matched, the session id doesn't match the one specified by rule,
2055 // but there's address specified in the tags which takes precedence.
2056 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2057 /*expected_match=*/ true)
2058 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2059 // Mix is matched, both the session id and the usage match ones specified by mix rule.
2060 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2061 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2062 /*expected_match=*/ true)
2063 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA),
2064 // Mix is not matched, the session id matches the one specified by mix rule,
2065 // but usage does not.
2066 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2067 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2068 /*expected_match=*/ false)
2069 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_GAME),
2070 // Mix is not matched, the usage matches the one specified by mix rule,
2071 // but the session id is excluded.
2072 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID, /*exclude=*/ true),
2073 createUsageCriterion(AUDIO_USAGE_MEDIA)},
2074 /*expected_match=*/ false)
2075 .withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA)));
jiabinf4eb15a2019-08-28 15:31:47 -07002076
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002077struct DPMmapTestParam {
2078 DPMmapTestParam(int mixRouteFlags, audio_devices_t deviceType, const std::string& deviceAddress)
2079 : mixRouteFlags(mixRouteFlags), deviceType(deviceType), deviceAddress(deviceAddress) {}
2080
2081 int mixRouteFlags;
2082 audio_devices_t deviceType;
2083 std::string deviceAddress;
2084};
2085
2086class AudioPolicyManagerTestMMapPlaybackRerouting
2087 : public AudioPolicyManagerTestDynamicPolicy,
2088 public ::testing::WithParamInterface<DPMmapTestParam> {
2089 protected:
2090 void SetUp() override {
2091 AudioPolicyManagerTestDynamicPolicy::SetUp();
2092 audioConfig = AUDIO_CONFIG_INITIALIZER;
2093 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2094 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2095 audioConfig.sample_rate = k48000SamplingRate;
2096 }
2097
2098 audio_config_t audioConfig;
2099 audio_io_handle_t mOutput;
2100 audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
2101 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebskyb3d3f622023-07-13 11:09:15 +02002102 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002103 AudioPolicyInterface::output_type_t mOutputType;
2104 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
2105 bool mIsSpatialized;
2106 bool mIsBitPerfect;
2107};
2108
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002109TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting, MmapPlaybackStreamMatchingLoopbackDapMixFails) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002110 // Add mix matching the test uid.
2111 const int testUid = 12345;
2112 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002113 ASSERT_NO_FATAL_FAILURE(
2114 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2115 param.deviceType, param.deviceAddress, audioConfig,
2116 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002117
jiabin24ff57a2023-11-27 21:06:51 +00002118 // Getting output for matching uid and mmap-ed stream should fail.
2119 audio_output_flags_t outputFlags =
2120 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002121 ASSERT_EQ(INVALID_OPERATION,
2122 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2123 createAttributionSourceState(testUid), &audioConfig,
2124 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2125 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2126}
2127
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002128TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting,
2129 NonMmapPlaybackStreamMatchingLoopbackDapMixSucceeds) {
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002130 // Add mix matching the test uid.
2131 const int testUid = 12345;
2132 const auto param = GetParam();
jiabin24ff57a2023-11-27 21:06:51 +00002133 ASSERT_NO_FATAL_FAILURE(
2134 addPolicyMixAndStartInputForLoopback(MIX_TYPE_PLAYERS, param.mixRouteFlags,
2135 param.deviceType,param.deviceAddress, audioConfig,
2136 {createUidCriterion(testUid)}));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002137
jiabin24ff57a2023-11-27 21:06:51 +00002138 // Getting output for matching uid should succeed for non-mmaped stream.
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002139 audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2140 ASSERT_EQ(NO_ERROR,
2141 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2142 createAttributionSourceState(testUid), &audioConfig,
2143 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2144 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2145}
2146
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002147TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002148 MmapPlaybackStreamMatchingRenderDapMixSupportingMmapSucceeds) {
jiabin24ff57a2023-11-27 21:06:51 +00002149 const std::string usbAddress = "card=1;device=0";
2150 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2151 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2152 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
2153 audio_port_v7 usbDevicePort;
2154 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_USB_DEVICE,
2155 usbAddress, &usbDevicePort));
2156
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002157 // Add render-only mix matching the test uid.
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002158 const int testUid = 12345;
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002159 // test_audio_policy_configuration.xml declares mmap-capable mix port
2160 // for AUDIO_DEVICE_OUT_USB_DEVICE.
jiabin24ff57a2023-11-27 21:06:51 +00002161 ASSERT_EQ(NO_ERROR,
2162 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2163 AUDIO_DEVICE_OUT_USB_DEVICE, /*mixAddress=*/"",
2164 audioConfig, {createUidCriterion(testUid)}));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002165
jiabin24ff57a2023-11-27 21:06:51 +00002166 static const audio_output_flags_t mmapDirectFlags =
2167 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
2168 // Getting output for matching uid should succeed for mmaped stream, because matched mix
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002169 // redirects to mmap capable device.
jiabin24ff57a2023-11-27 21:06:51 +00002170 audio_output_flags_t outputFlags = mmapDirectFlags;
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002171 ASSERT_EQ(NO_ERROR,
2172 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2173 createAttributionSourceState(testUid), &audioConfig,
2174 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2175 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
jiabin24ff57a2023-11-27 21:06:51 +00002176 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2177 auto outputDesc = mManager->getOutputs().valueFor(mOutput);
2178 ASSERT_NE(nullptr, outputDesc);
2179 ASSERT_EQ(mmapDirectFlags, outputDesc->getFlags().output);
2180
2181 // After releasing the client, the output is closed. APM should reselect output for the policy
2182 // mix.
2183 mManager->releaseOutput(mPortId);
2184 ASSERT_EQ(nullptr, mManager->getOutputs().valueFor(mOutput));
2185 outputFlags = AUDIO_OUTPUT_FLAG_NONE;
2186 mPortId = AUDIO_PORT_HANDLE_NONE;
2187 ASSERT_EQ(NO_ERROR,
2188 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2189 createAttributionSourceState(testUid), &audioConfig,
2190 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2191 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2192 ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
2193 outputDesc = mManager->getOutputs().valueFor(mOutput);
2194 ASSERT_NE(nullptr, outputDesc);
2195 ASSERT_NE(mmapDirectFlags, outputDesc->getFlags().output);
2196
2197 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2198 AUDIO_DEVICE_OUT_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2199 usbAddress.c_str(), "", AUDIO_FORMAT_DEFAULT));
Jan Sebechlebsky370abec2023-06-15 10:18:30 +02002200}
2201
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002202TEST_F(AudioPolicyManagerTestMMapPlaybackRerouting,
2203 MmapPlaybackStreamMatchingRenderDapMixNotSupportingMmapFails) {
2204 // Add render-only mix matching the test uid.
2205 const int testUid = 12345;
2206 // Per test_audio_policy_configuration.xml AUDIO_DEVICE_OUT_SPEAKER doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002207 ASSERT_EQ(NO_ERROR,
2208 addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2209 AUDIO_DEVICE_OUT_SPEAKER, /*mixAddress=*/"", audioConfig,
2210 {createUidCriterion(testUid)}));
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002211
jiabin24ff57a2023-11-27 21:06:51 +00002212 // Getting output for matching uid should fail for mmaped stream, because
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002213 // matched mix redirects to device which doesn't support mmap.
jiabin24ff57a2023-11-27 21:06:51 +00002214 audio_output_flags_t outputFlags =
2215 (audio_output_flags_t) (AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
Jan Sebechlebsky697f5d92023-08-04 11:15:00 +02002216 ASSERT_EQ(INVALID_OPERATION,
2217 mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
2218 createAttributionSourceState(testUid), &audioConfig,
2219 &outputFlags, &mSelectedDeviceId, &mPortId, {},
2220 &mOutputType, &mIsSpatialized, &mIsBitPerfect));
2221}
2222
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002223INSTANTIATE_TEST_SUITE_P(
2224 MmapPlaybackRerouting, AudioPolicyManagerTestMMapPlaybackRerouting,
2225 testing::Values(DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2226 /*deviceAddress=*/"remote_submix_media"),
2227 DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
2228 AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
jiabin1ca6c6f2023-09-22 17:25:59 +00002229 /*deviceAddress=*/"remote_submix_media"),
2230 DPMmapTestParam(MIX_ROUTE_FLAG_RENDER, AUDIO_DEVICE_OUT_SPEAKER,
2231 /*deviceAddress=*/"")));
Jan Sebechlebsky8e10cea2023-03-29 11:43:31 +02002232
jiabinf4eb15a2019-08-28 15:31:47 -07002233class AudioPolicyManagerTestDPMixRecordInjection : public AudioPolicyManagerTestDynamicPolicy,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002234 public testing::WithParamInterface<DPTestParam> {
jiabinf4eb15a2019-08-28 15:31:47 -07002235protected:
2236 void SetUp() override;
2237 void TearDown() override;
2238
2239 std::unique_ptr<RecordingActivityTracker> mTracker;
jiabin19cdba52020-11-24 11:28:58 -08002240 struct audio_port_v7 mExtractionPort;
jiabinf4eb15a2019-08-28 15:31:47 -07002241 audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
2242};
2243
2244void AudioPolicyManagerTestDPMixRecordInjection::SetUp() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07002245 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestDynamicPolicy::SetUp());
jiabinf4eb15a2019-08-28 15:31:47 -07002246
2247 mTracker.reset(new RecordingActivityTracker());
2248
2249 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2250 audioConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
2251 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002252 audioConfig.sample_rate = k48000SamplingRate;
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002253
2254 DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002255 status_t ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK,
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002256 AUDIO_DEVICE_IN_REMOTE_SUBMIX, mMixAddress, audioConfig, param.mixCriteria);
jiabinf4eb15a2019-08-28 15:31:47 -07002257 ASSERT_EQ(NO_ERROR, ret);
2258
jiabin19cdba52020-11-24 11:28:58 -08002259 struct audio_port_v7 injectionPort;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002260 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2261 mMixAddress, &injectionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002262
2263 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2264 audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
Mikhail Naganov55773032020-10-01 15:08:13 -07002265 audio_attributes_t attr =
2266 {AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
jiabinf4eb15a2019-08-28 15:31:47 -07002267 std::string tags = std::string("addr=") + mMixAddress;
2268 strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
2269 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002270 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, &mPortId, attr);
jiabinf4eb15a2019-08-28 15:31:47 -07002271 ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
2272 ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
2273
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002274 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
2275 mMixAddress, &mExtractionPort));
jiabinf4eb15a2019-08-28 15:31:47 -07002276}
2277
2278void AudioPolicyManagerTestDPMixRecordInjection::TearDown() {
2279 mManager->stopOutput(mPortId);
2280 AudioPolicyManagerTestDynamicPolicy::TearDown();
2281}
2282
jiabinf4eb15a2019-08-28 15:31:47 -07002283TEST_P(AudioPolicyManagerTestDPMixRecordInjection, RecordingInjection) {
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002284 const DPTestParam param = GetParam();
jiabinf4eb15a2019-08-28 15:31:47 -07002285
jiabin7c0205e2019-09-05 10:26:04 -07002286 audio_port_handle_t captureRoutedPortId = AUDIO_PORT_HANDLE_NONE;
jiabinf4eb15a2019-08-28 15:31:47 -07002287 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02002288 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2289 getInputForAttr(param.attributes, &input, param.session, mTracker->getRiid(),
2290 &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
2291 k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002292 if (param.expected_match) {
jiabinf4eb15a2019-08-28 15:31:47 -07002293 EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
2294 } else {
2295 EXPECT_NE(mExtractionPort.id, captureRoutedPortId);
2296 }
2297}
2298
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002299const std::vector<AudioMixMatchCriterion> SOURCE_CAM_MIC_VOICE_CRITERIA = {
2300 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
2301 createCapturePresetCriterion(AUDIO_SOURCE_MIC),
2302 createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
2303};
2304
jiabinf4eb15a2019-08-28 15:31:47 -07002305// No address priority rule for remote recording, address is a "don't care"
2306INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002307 RecordInjectionSource,
jiabinf4eb15a2019-08-28 15:31:47 -07002308 AudioPolicyManagerTestDPMixRecordInjection,
2309 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002310 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2311 .withSource(AUDIO_SOURCE_CAMCORDER),
2312 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2313 .withSource(AUDIO_SOURCE_CAMCORDER)
2314 .withTags("addr=remote_submix_media"),
2315 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2316 .withSource(AUDIO_SOURCE_MIC),
2317 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2318 .withSource(AUDIO_SOURCE_MIC)
2319 .withTags("addr=remote_submix_media"),
2320 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2321 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION),
2322 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ true)
2323 .withSource(AUDIO_SOURCE_VOICE_COMMUNICATION)
2324 .withTags("addr=remote_submix_media"),
2325 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2326 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION),
2327 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2328 .withSource(AUDIO_SOURCE_VOICE_RECOGNITION)
2329 .withTags("addr=remote_submix_media"),
2330 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2331 .withSource(AUDIO_SOURCE_HOTWORD),
2332 DPTestParam(SOURCE_CAM_MIC_VOICE_CRITERIA, /*expected_match=*/ false)
2333 .withSource(AUDIO_SOURCE_HOTWORD)
2334 .withTags("addr=remote_submix_media")));
jiabinf4eb15a2019-08-28 15:31:47 -07002335
jiabinf4eb15a2019-08-28 15:31:47 -07002336INSTANTIATE_TEST_CASE_P(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002337 RecordInjectionWithSessionId,
jiabinf4eb15a2019-08-28 15:31:47 -07002338 AudioPolicyManagerTestDPMixRecordInjection,
2339 testing::Values(
Jan Sebechlebsky1a80c062022-08-09 15:21:18 +02002340 // Mix is matched because the session id matches the one specified by the mix rule.
2341 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2342 /*expected_match=*/ true)
2343 .withSessionId(TEST_SESSION_ID),
2344 // Mix is not matched because the session id doesn't match the one specified
2345 // by the mix rule.
2346 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2347 /*expected_match=*/ false)
2348 .withSessionId(OTHER_SESSION_ID),
2349 // Mix is not matched, the session id doesn't match the one specified by rule,
2350 // but tand address specified in the tags is ignored for recorder mix.
2351 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID)},
2352 /*expected_match=*/ false)
2353 .withSessionId(OTHER_SESSION_ID).withTags("addr=remote_submix_media"),
2354 // Mix is matched, both the session id and the source match ones specified by mix rule
2355 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2356 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2357 /*expected_match=*/ true)
2358 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_CAMCORDER),
2359 // Mix is not matched, the session id matches the one specified by mix rule,
2360 // but source does not.
2361 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID),
2362 createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER)},
2363 /*expected_match=*/ false)
2364 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC),
2365 // Mix is not matched, the source matches the one specified by mix rule,
2366 // but the session id is excluded.
2367 DPTestParam(/*mixCriteria=*/ {createSessionIdCriterion(TEST_SESSION_ID,
2368 /*exclude=*/ true),
2369 createCapturePresetCriterion(AUDIO_SOURCE_MIC)},
2370 /*expected_match=*/ false)
2371 .withSessionId(TEST_SESSION_ID).withSource(AUDIO_SOURCE_MIC)));
jiabin43848a52019-09-05 14:07:25 -07002372
2373using DeviceConnectionTestParams =
2374 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/>;
2375
2376class AudioPolicyManagerTestDeviceConnection : public AudioPolicyManagerTestWithConfigurationFile,
2377 public testing::WithParamInterface<DeviceConnectionTestParams> {
2378};
2379
2380TEST_F(AudioPolicyManagerTestDeviceConnection, InitSuccess) {
2381 // SetUp must finish with no assertions.
2382}
2383
2384TEST_F(AudioPolicyManagerTestDeviceConnection, Dump) {
2385 dumpToLog();
2386}
2387
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002388TEST_F(AudioPolicyManagerTestDeviceConnection, RoutingUpdate) {
2389 mClient->resetRoutingUpdatedCounter();
2390 // Connecting a valid output device with valid parameters should trigger a routing update
2391 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2392 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002393 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002394 ASSERT_EQ(1, mClient->getRoutingUpdatedCounter());
2395
2396 // Disconnecting a connected device should succeed and trigger a routing update
2397 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2398 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002399 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002400 ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
2401
2402 // Disconnecting a disconnected device should fail and not trigger a routing update
2403 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2404 AUDIO_DEVICE_OUT_BLUETOOTH_SCO, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002405 "00:11:22:33:44:55", "b", AUDIO_FORMAT_DEFAULT));
Jean-Michel Trivi9a6b9ad2020-10-22 16:46:43 -07002406 ASSERT_EQ(2, mClient->getRoutingUpdatedCounter());
2407
2408 // Changing force use should trigger an update
2409 auto config = mManager->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA);
2410 auto newConfig = config == AUDIO_POLICY_FORCE_BT_A2DP ?
2411 AUDIO_POLICY_FORCE_NONE : AUDIO_POLICY_FORCE_BT_A2DP;
2412 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, newConfig);
2413 ASSERT_EQ(3, mClient->getRoutingUpdatedCounter());
2414}
2415
jiabin43848a52019-09-05 14:07:25 -07002416TEST_P(AudioPolicyManagerTestDeviceConnection, SetDeviceConnectionState) {
2417 const audio_devices_t type = std::get<0>(GetParam());
2418 const std::string name = std::get<1>(GetParam());
2419 const std::string address = std::get<2>(GetParam());
2420
2421 if (type == AUDIO_DEVICE_OUT_HDMI) {
2422 // Set device connection state failed due to no device descriptor found
2423 // For HDMI case, it is easier to simulate device descriptor not found error
Mikhail Naganov83caee02021-10-05 15:52:01 -07002424 // by using an encoded format which isn't listed in the 'encodedFormats'
2425 // attribute for this devicePort.
jiabin43848a52019-09-05 14:07:25 -07002426 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2427 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2428 address.c_str(), name.c_str(), AUDIO_FORMAT_MAT_2_1));
2429 }
2430 // Connect with valid parameters should succeed
2431 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2432 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2433 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2434 // Try to connect with the same device again should fail
2435 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2436 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2437 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2438 // Disconnect the connected device should succeed
2439 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2440 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2441 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2442 // Disconnect device that is not connected should fail
2443 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2444 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2445 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2446 // Try to set device connection state with a invalid connection state should fail
2447 ASSERT_EQ(BAD_VALUE, mManager->setDeviceConnectionState(
2448 type, AUDIO_POLICY_DEVICE_STATE_CNT,
2449 "", "", AUDIO_FORMAT_DEFAULT));
2450}
2451
2452TEST_P(AudioPolicyManagerTestDeviceConnection, ExplicitlyRoutingAfterConnection) {
2453 const audio_devices_t type = std::get<0>(GetParam());
2454 const std::string name = std::get<1>(GetParam());
2455 const std::string address = std::get<2>(GetParam());
2456
2457 // Connect device to do explicitly routing test
2458 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2459 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2460 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2461
jiabin19cdba52020-11-24 11:28:58 -08002462 audio_port_v7 devicePort;
jiabin43848a52019-09-05 14:07:25 -07002463 const audio_port_role_t role = audio_is_output_device(type)
2464 ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07002465 ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
jiabin43848a52019-09-05 14:07:25 -07002466
2467 audio_port_handle_t routedPortId = devicePort.id;
jiabin43848a52019-09-05 14:07:25 -07002468 // Try start input or output according to the device type
2469 if (audio_is_output_devices(type)) {
2470 getOutputForAttr(&routedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
Dean Wheatleyd082f472022-02-04 11:10:48 +11002471 k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002472 } else if (audio_is_input_device(type)) {
2473 RecordingActivityTracker tracker;
François Gaffie6ebbce02023-07-19 13:27:53 +02002474 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
2475 getInputForAttr({}, &input, AUDIO_SESSION_NONE, tracker.getRiid(), &routedPortId,
2476 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate,
2477 AUDIO_INPUT_FLAG_NONE);
jiabin43848a52019-09-05 14:07:25 -07002478 }
2479 ASSERT_EQ(devicePort.id, routedPortId);
2480
2481 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2482 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2483 address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
2484}
2485
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002486android::media::audio::common::ExtraAudioDescriptor make_ExtraAudioDescriptor(
2487 android::media::audio::common::AudioStandard audioStandard,
2488 android::media::audio::common::AudioEncapsulationType audioEncapsulationType) {
2489 android::media::audio::common::ExtraAudioDescriptor result;
2490 result.standard = audioStandard;
2491 result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
2492 result.encapsulationType = audioEncapsulationType;
2493 return result;
2494}
2495
2496TEST_P(AudioPolicyManagerTestDeviceConnection, PassingExtraAudioDescriptors) {
2497 const audio_devices_t type = std::get<0>(GetParam());
2498 if (!audio_device_is_digital(type)) {
2499 // EADs are used only for HDMI devices.
2500 GTEST_SKIP() << "Not a digital device type: " << audio_device_to_string(type);
2501 }
2502 const std::string name = std::get<1>(GetParam());
2503 const std::string address = std::get<2>(GetParam());
Atneya Nair638a6e42022-12-18 16:45:15 -08002504 android::media::AudioPortFw audioPort;
Mikhail Naganovddc5f312022-06-11 00:47:52 +00002505 ASSERT_EQ(NO_ERROR,
2506 mManager->deviceToAudioPort(type, address.c_str(), name.c_str(), &audioPort));
2507 android::media::audio::common::AudioPort& port = audioPort.hal;
2508 port.extraAudioDescriptors.push_back(make_ExtraAudioDescriptor(
2509 android::media::audio::common::AudioStandard::EDID,
2510 android::media::audio::common::AudioEncapsulationType::IEC61937));
2511 const size_t lastConnectedDevicePortCount = mClient->getConnectedDevicePortCount();
2512 const size_t lastDisconnectedDevicePortCount = mClient->getDisconnectedDevicePortCount();
2513 EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
2514 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, port, AUDIO_FORMAT_DEFAULT));
2515 EXPECT_EQ(lastConnectedDevicePortCount + 1, mClient->getConnectedDevicePortCount());
2516 EXPECT_EQ(lastDisconnectedDevicePortCount, mClient->getDisconnectedDevicePortCount());
2517 const audio_port_v7* devicePort = mClient->getLastConnectedDevicePort();
2518 EXPECT_EQ(port.extraAudioDescriptors.size(), devicePort->num_extra_audio_descriptors);
2519 EXPECT_EQ(AUDIO_STANDARD_EDID, devicePort->extra_audio_descriptors[0].standard);
2520 EXPECT_EQ(AUDIO_ENCAPSULATION_TYPE_IEC61937,
2521 devicePort->extra_audio_descriptors[0].encapsulation_type);
2522 EXPECT_NE(0, devicePort->extra_audio_descriptors[0].descriptor[0]);
2523}
2524
jiabin43848a52019-09-05 14:07:25 -07002525INSTANTIATE_TEST_CASE_P(
2526 DeviceConnectionState,
2527 AudioPolicyManagerTestDeviceConnection,
2528 testing::Values(
2529 DeviceConnectionTestParams({AUDIO_DEVICE_IN_HDMI, "test_in_hdmi",
2530 "audio_policy_test_in_hdmi"}),
2531 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_HDMI, "test_out_hdmi",
2532 "audio_policy_test_out_hdmi"}),
2533 DeviceConnectionTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "bt_hfp_in",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002534 "00:11:22:33:44:55"}),
jiabin43848a52019-09-05 14:07:25 -07002535 DeviceConnectionTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "bt_hfp_out",
Mikhail Naganovb1ddbb02023-03-15 17:06:59 -07002536 "00:11:22:33:44:55"})
jiabin43848a52019-09-05 14:07:25 -07002537 )
2538 );
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07002539
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002540namespace {
2541
2542class AudioPolicyManagerTestClientOpenFails : public AudioPolicyManagerTestClient {
2543 public:
2544 status_t openOutput(audio_module_handle_t module,
2545 audio_io_handle_t *output,
2546 audio_config_t * halConfig,
2547 audio_config_base_t * mixerConfig,
2548 const sp<DeviceDescriptorBase>& device,
2549 uint32_t * latencyMs,
Dean Wheatleydfb67b82024-01-23 09:36:29 +11002550 audio_output_flags_t *flags,
Haofan Wangb75aa6a2024-07-09 23:06:58 -07002551 audio_attributes_t attributes) override {
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002552 return mSimulateFailure ? BAD_VALUE :
2553 AudioPolicyManagerTestClient::openOutput(
Haofan Wangb75aa6a2024-07-09 23:06:58 -07002554 module, output, halConfig, mixerConfig, device, latencyMs, flags,
2555 attributes);
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002556 }
2557
2558 status_t openInput(audio_module_handle_t module,
2559 audio_io_handle_t *input,
2560 audio_config_t * config,
2561 audio_devices_t * device,
2562 const String8 & address,
2563 audio_source_t source,
2564 audio_input_flags_t flags) override {
2565 return mSimulateFailure ? BAD_VALUE :
2566 AudioPolicyManagerTestClient::openInput(
2567 module, input, config, device, address, source, flags);
2568 }
2569
2570 void setSimulateFailure(bool simulateFailure) { mSimulateFailure = simulateFailure; }
2571
Ping Tsai2a5a5242024-08-16 13:39:10 +08002572 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2573 if (status != NO_ERROR) {
2574 // simulate device connect status
2575 mSimulateBroadcastDeviceStatus[device] = status;
2576 } else {
2577 // remove device connection fixed status
2578 mSimulateBroadcastDeviceStatus.erase(device);
2579 }
2580 }
2581
2582 status_t setDeviceConnectedState(const struct audio_port_v7* port,
2583 media::DeviceConnectedState state) override {
2584 if (mSimulateBroadcastDeviceStatus.find(port->ext.device.type) !=
2585 mSimulateBroadcastDeviceStatus.end()) {
2586 // If a simulated status exists, return a status value
2587 return mSimulateBroadcastDeviceStatus[port->ext.device.type];
2588 }
2589 return AudioPolicyManagerTestClient::setDeviceConnectedState(port, state);
2590 }
2591
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002592 private:
2593 bool mSimulateFailure = false;
Ping Tsai2a5a5242024-08-16 13:39:10 +08002594 std::map<audio_devices_t, status_t> mSimulateBroadcastDeviceStatus;
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002595};
2596
2597} // namespace
2598
2599using DeviceConnectionWithFormatTestParams =
2600 std::tuple<audio_devices_t /*type*/, std::string /*name*/, std::string /*address*/,
2601 audio_format_t /*format*/>;
2602
2603class AudioPolicyManagerTestDeviceConnectionFailed :
2604 public AudioPolicyManagerTestWithConfigurationFile,
2605 public testing::WithParamInterface<DeviceConnectionWithFormatTestParams> {
2606 protected:
2607 std::string getConfigFile() override { return sBluetoothConfig; }
2608 AudioPolicyManagerTestClient* getClient() override {
2609 mFullClient = new AudioPolicyManagerTestClientOpenFails;
2610 return mFullClient;
2611 }
2612 void setSimulateOpenFailure(bool simulateFailure) {
2613 mFullClient->setSimulateFailure(simulateFailure); }
2614
Ping Tsai2a5a5242024-08-16 13:39:10 +08002615 void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
2616 mFullClient->setSimulateBroadcastDeviceStatus(device, status); }
2617
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002618 static const std::string sBluetoothConfig;
2619
2620 private:
2621 AudioPolicyManagerTestClientOpenFails* mFullClient;
2622};
2623
2624const std::string AudioPolicyManagerTestDeviceConnectionFailed::sBluetoothConfig =
2625 AudioPolicyManagerTestDeviceConnectionFailed::sExecutableDir +
2626 "test_audio_policy_configuration_bluetooth.xml";
2627
2628TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, SetDeviceConnectedStateHasAddress) {
2629 const audio_devices_t type = std::get<0>(GetParam());
2630 const std::string name = std::get<1>(GetParam());
2631 const std::string address = std::get<2>(GetParam());
2632 const audio_format_t format = std::get<3>(GetParam());
2633
2634 EXPECT_EQ(0, mClient->getConnectedDevicePortCount());
2635 EXPECT_EQ(0, mClient->getDisconnectedDevicePortCount());
2636
2637 setSimulateOpenFailure(true);
2638 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2639 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2640 address.c_str(), name.c_str(), format));
2641
2642 // Since the failure happens when opening input/output, the device must be connected
2643 // first and then disconnected.
2644 EXPECT_EQ(1, mClient->getConnectedDevicePortCount());
2645 EXPECT_EQ(1, mClient->getDisconnectedDevicePortCount());
2646
2647 if (mClient->getConnectedDevicePortCount() > 0) {
2648 auto port = mClient->getLastConnectedDevicePort();
2649 EXPECT_EQ(type, port->ext.device.type);
2650 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2651 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2652 }
2653 if (mClient->getDisconnectedDevicePortCount() > 0) {
2654 auto port = mClient->getLastDisconnectedDevicePort();
2655 EXPECT_EQ(type, port->ext.device.type);
2656 EXPECT_EQ(0, strncmp(port->ext.device.address, address.c_str(),
2657 AUDIO_DEVICE_MAX_ADDRESS_LEN)) << "\"" << port->ext.device.address << "\"";
2658 }
2659}
2660
Ping Tsai2a5a5242024-08-16 13:39:10 +08002661TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, BroadcastDeviceFailure) {
2662 const audio_devices_t type = std::get<0>(GetParam());
2663 const std::string name = std::get<1>(GetParam());
2664 const std::string address = std::get<2>(GetParam());
2665 const audio_format_t format = std::get<3>(GetParam());
2666
2667 // simulate broadcastDeviceConnectionState return failure
2668 setSimulateBroadcastDeviceStatus(type, INVALID_OPERATION);
2669 ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
2670 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2671 address.c_str(), name.c_str(), format));
2672
2673 // if broadcast is fail, device should not be added to available devices list
2674 if (audio_is_output_device(type)) {
2675 auto availableDevices = mManager->getAvailableOutputDevices();
2676 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2677 } else if (audio_is_input_device(type)) {
2678 auto availableDevices = mManager->getAvailableInputDevices();
2679 EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
2680 }
2681
2682 setSimulateBroadcastDeviceStatus(type, NO_ERROR);
2683}
2684
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07002685INSTANTIATE_TEST_CASE_P(
2686 DeviceConnectionFailure,
2687 AudioPolicyManagerTestDeviceConnectionFailed,
2688 testing::Values(
2689 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
2690 "bt_hfp_in", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2691 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_SCO,
2692 "bt_hfp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2693 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2694 "bt_a2dp_out", "00:11:22:33:44:55", AUDIO_FORMAT_DEFAULT}),
2695 DeviceConnectionWithFormatTestParams({AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
2696 "bt_a2dp_out", "00:11:22:33:44:66", AUDIO_FORMAT_LDAC})
2697 )
2698 );
2699
Dean Wheatleyd082f472022-02-04 11:10:48 +11002700class AudioPolicyManagerCarTest : public AudioPolicyManagerTestDynamicPolicy {
2701protected:
2702 std::string getConfigFile() override { return sCarConfig; }
2703
2704 static const std::string sCarConfig;
Oscar Azucena873d10f2023-01-12 18:34:42 -08002705 static const std::string sCarBusMediaOutput;
2706 static const std::string sCarBusNavigationOutput;
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002707 static const std::string sCarRearZoneOneOutput;
2708 static const std::string sCarRearZoneTwoOutput;
jiabin24ff57a2023-11-27 21:06:51 +00002709 static const std::string sCarBusMmapOutput;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002710};
2711
2712const std::string AudioPolicyManagerCarTest::sCarConfig =
2713 AudioPolicyManagerCarTest::sExecutableDir + "test_car_ap_atmos_offload_configuration.xml";
2714
Oscar Azucena873d10f2023-01-12 18:34:42 -08002715const std::string AudioPolicyManagerCarTest::sCarBusMediaOutput = "bus0_media_out";
2716
2717const std::string AudioPolicyManagerCarTest::sCarBusNavigationOutput = "bus1_navigation_out";
2718
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002719const std::string AudioPolicyManagerCarTest::sCarRearZoneOneOutput = "bus100_audio_zone_1";
2720
2721const std::string AudioPolicyManagerCarTest::sCarRearZoneTwoOutput = "bus200_audio_zone_2";
2722
jiabin24ff57a2023-11-27 21:06:51 +00002723const std::string AudioPolicyManagerCarTest::sCarBusMmapOutput = "bus8_mmap_out";
2724
Dean Wheatleyd082f472022-02-04 11:10:48 +11002725TEST_F(AudioPolicyManagerCarTest, InitSuccess) {
2726 // SetUp must finish with no assertions.
2727}
2728
2729TEST_F(AudioPolicyManagerCarTest, Dump) {
2730 dumpToLog();
2731}
2732
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002733TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAtmosOutputAfterRegisteringPolicyMix) {
Dean Wheatleyd082f472022-02-04 11:10:48 +11002734 status_t ret;
2735 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
Dean Wheatleyd082f472022-02-04 11:10:48 +11002736 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
Oscar Azucena873d10f2023-01-12 18:34:42 -08002737 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig);
Dean Wheatleyd082f472022-02-04 11:10:48 +11002738 ASSERT_EQ(NO_ERROR, ret);
2739
2740 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2741 audio_io_handle_t output;
2742 audio_port_handle_t portId;
2743 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_E_AC3_JOC, AUDIO_CHANNEL_OUT_5POINT1,
2744 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2745 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2746 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
2747 ASSERT_NE(nullptr, outDesc.get());
2748 ASSERT_EQ(AUDIO_FORMAT_E_AC3_JOC, outDesc->getFormat());
2749 ASSERT_EQ(AUDIO_CHANNEL_OUT_5POINT1, outDesc->getChannelMask());
2750 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyecbf2ee2022-03-04 10:51:36 +11002751
2752 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2753 output = AUDIO_IO_HANDLE_NONE;
2754 portId = AUDIO_PORT_HANDLE_NONE;
2755 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
2756 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
2757 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
2758 outDesc = mManager->getOutputs().valueFor(output);
2759 ASSERT_NE(nullptr, outDesc.get());
2760 ASSERT_EQ(AUDIO_FORMAT_PCM_16_BIT, outDesc->getFormat());
2761 ASSERT_EQ(AUDIO_CHANNEL_OUT_7POINT1POINT4, outDesc->getChannelMask());
2762 ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
Dean Wheatleyd082f472022-02-04 11:10:48 +11002763}
2764
Oscar Azucena873d10f2023-01-12 18:34:42 -08002765TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAfterRegisteringPolicyMix) {
2766 status_t ret;
2767 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2768 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2769 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2770 audioConfig.sample_rate = k48000SamplingRate;
2771 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2772 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2773 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2774 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2775 ASSERT_EQ(NO_ERROR, ret);
2776 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2777 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2778 /*exclude=*/ false)};
2779 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2780 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2781 ASSERT_EQ(NO_ERROR, ret);
2782 audio_port_v7 mediaDevicePort;
2783 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2784 sCarBusMediaOutput, &mediaDevicePort));
2785 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2786 audio_io_handle_t output;
2787 audio_port_handle_t portId;
2788 const audio_attributes_t mediaAttribute = {
2789 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2790 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2791
2792 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2793 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2794
2795 ASSERT_EQ(mediaDevicePort.id, selectedDeviceId);
2796}
2797
2798TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterRegisteringPolicyMix) {
2799 status_t ret;
2800 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2801 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2802 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2803 audioConfig.sample_rate = k48000SamplingRate;
2804 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2805 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2806 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2807 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2808 ASSERT_EQ(NO_ERROR, ret);
2809 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2810 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2811 /*exclude=*/ false)};
2812 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2813 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2814 ASSERT_EQ(NO_ERROR, ret);
2815 audio_port_v7 navDevicePort;
2816 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2817 sCarBusNavigationOutput, &navDevicePort));
2818 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2819 audio_io_handle_t output;
2820 audio_port_handle_t portId;
2821 const audio_attributes_t mediaAttribute = {
2822 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2823 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2824
2825 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2826 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2827
2828 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2829}
2830
2831TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterUserAffinities) {
2832 status_t ret;
2833 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2834 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2835 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2836 audioConfig.sample_rate = k48000SamplingRate;
2837 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2838 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2839 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2840 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2841 ASSERT_EQ(NO_ERROR, ret);
2842 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2843 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2844 /*exclude=*/ false)};
2845 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2846 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2847 ASSERT_EQ(NO_ERROR, ret);
2848 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2849 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002850 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002851 audio_port_v7 navDevicePort;
2852 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2853 sCarBusNavigationOutput, &navDevicePort));
2854 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2855 audio_io_handle_t output;
2856 audio_port_handle_t portId;
2857 const audio_attributes_t mediaAttribute = {
2858 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2859 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2860
2861 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2862 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2863
2864 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2865}
2866
2867TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithExcludeUserIdCriteria) {
2868 status_t ret;
2869 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2870 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2871 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2872 audioConfig.sample_rate = k48000SamplingRate;
2873 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2874 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2875 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2876 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2877 ASSERT_EQ(NO_ERROR, ret);
2878 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2879 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2880 /*exclude=*/ false),
2881 createUserIdCriterion(/* userId */ 0, /* exclude */ true)};
2882 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2883 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2884 ASSERT_EQ(NO_ERROR, ret);
2885 audio_port_v7 navDevicePort;
2886 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2887 sCarBusNavigationOutput, &navDevicePort));
2888 audio_io_handle_t output;
2889 audio_port_handle_t portId;
2890 const audio_attributes_t navigationAttribute = {
2891 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2892 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2893 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
2894
2895 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2896 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, navigationAttribute);
2897
2898 ASSERT_NE(navDevicePort.id, selectedDeviceId);
2899}
2900
2901TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputExcludeUserIdCriteria) {
2902 status_t ret;
2903 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2904 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2905 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2906 audioConfig.sample_rate = k48000SamplingRate;
2907 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2908 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2909 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2910 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2911 ASSERT_EQ(NO_ERROR, ret);
2912 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2913 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2914 /*exclude=*/ false),
2915 createUserIdCriterion(0 /* userId */, /* exclude */ true)};
2916 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2917 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2918 ASSERT_EQ(NO_ERROR, ret);
2919 audio_port_v7 navDevicePort;
2920 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2921 sCarBusNavigationOutput, &navDevicePort));
2922 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2923 audio_io_handle_t output;
2924 audio_port_handle_t portId;
2925 const audio_attributes_t mediaAttribute = {
2926 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2927 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2928
2929 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2930 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2931
2932 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2933}
2934
2935TEST_F(AudioPolicyManagerCarTest,
2936 GetOutputForAttrWithMatchingMixAndSelectedOutputAfterUserAffinities) {
2937 status_t ret;
2938 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2939 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2940 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2941 audioConfig.sample_rate = k48000SamplingRate;
2942 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2943 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2944 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2945 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2946 ASSERT_EQ(NO_ERROR, ret);
2947 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2948 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2949 /*exclude=*/ false)};
2950 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2951 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2952 ASSERT_EQ(NO_ERROR, ret);
2953 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2954 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
2955 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002956 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002957 audio_port_v7 navDevicePort;
2958 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2959 sCarBusNavigationOutput, &navDevicePort));
2960 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2961 audio_io_handle_t output;
2962 audio_port_handle_t portId;
2963 const audio_attributes_t mediaAttribute = {
2964 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
2965 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
2966
2967 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
2968 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
2969
2970 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
2971}
2972
2973TEST_F(AudioPolicyManagerCarTest,
2974 GetOutputForAttrWithNoMatchingMaxAndSelectedOutputAfterUserAffinities) {
2975 status_t ret;
2976 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
2977 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2978 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
2979 audioConfig.sample_rate = k48000SamplingRate;
2980 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
2981 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
2982 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2983 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
2984 ASSERT_EQ(NO_ERROR, ret);
2985 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
2986 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
2987 /*exclude=*/ false)};
2988 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
2989 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
2990 ASSERT_EQ(NO_ERROR, ret);
2991 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
2992 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
2993 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08002994 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08002995 audio_port_v7 navDevicePort;
2996 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
2997 sCarBusNavigationOutput, &navDevicePort));
2998 audio_port_handle_t selectedDeviceId = navDevicePort.id;
2999 audio_io_handle_t output;
3000 audio_port_handle_t portId;
3001 const audio_attributes_t alarmAttribute = {
3002 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3003 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3004
3005 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3006 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3007
3008 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3009}
3010
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003011TEST_F(AudioPolicyManagerCarTest,
3012 GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
3013 status_t ret;
3014 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3015 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3016 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3017 audioConfig.sample_rate = k48000SamplingRate;
3018 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3019 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3020 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3021 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3022 ASSERT_EQ(NO_ERROR, ret);
3023 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3024 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3025 ASSERT_EQ(NO_ERROR, ret);
3026 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3027 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3028 ASSERT_EQ(NO_ERROR, ret);
3029 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3030 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3031 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3032 audio_port_v7 primaryZoneDevicePort;
3033 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3034 sCarBusMediaOutput, &primaryZoneDevicePort));
3035 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3036 audio_io_handle_t output;
3037 audio_port_handle_t portId;
3038 const audio_attributes_t mediaAttribute = {
3039 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3040 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3041 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3042
3043 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3044 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3045 AUDIO_SESSION_NONE, user11AppUid);
3046
3047 ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceId);
3048}
3049
3050TEST_F(AudioPolicyManagerCarTest,
3051 GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
3052 status_t ret;
3053 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3054 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3055 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3056 audioConfig.sample_rate = k48000SamplingRate;
3057 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3058 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3059 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3060 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3061 ASSERT_EQ(NO_ERROR, ret);
3062 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3063 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3064 ASSERT_EQ(NO_ERROR, ret);
3065 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3066 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3067 ASSERT_EQ(NO_ERROR, ret);
3068 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3069 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3070 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3071 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3072 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3073 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3074 audio_port_v7 secondaryZoneDevicePort;
3075 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3076 sCarRearZoneOneOutput, &secondaryZoneDevicePort));
3077 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3078 audio_io_handle_t output;
3079 audio_port_handle_t portId;
3080 const audio_attributes_t mediaAttribute = {
3081 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3082 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3083 uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
3084
3085 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3086 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3087 AUDIO_SESSION_NONE, user11AppUid);
3088
3089 ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceId);
3090}
3091
3092TEST_F(AudioPolicyManagerCarTest,
3093 GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
3094 status_t ret;
3095 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3096 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3097 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3098 audioConfig.sample_rate = k48000SamplingRate;
3099 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3100 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3101 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3102 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3103 ASSERT_EQ(NO_ERROR, ret);
3104 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3105 AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
3106 ASSERT_EQ(NO_ERROR, ret);
3107 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3108 AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
3109 ASSERT_EQ(NO_ERROR, ret);
3110 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3111 const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
3112 mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
3113 const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
3114 const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
3115 mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
3116 const AudioDeviceTypeAddr tertiaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput);
3117 const AudioDeviceTypeAddrVector tertiaryZoneDevices = {tertiaryOutputDevice};
3118 mManager->setUserIdDeviceAffinities(/* userId */ 15, tertiaryZoneDevices);
3119 audio_port_v7 tertiaryZoneDevicePort;
3120 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3121 sCarRearZoneTwoOutput, &tertiaryZoneDevicePort));
3122 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3123 audio_io_handle_t output;
3124 audio_port_handle_t portId;
3125 const audio_attributes_t mediaAttribute = {
3126 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3127 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3128 uid_t user15AppUid = multiuser_get_uid(/* user_id */ 15, /* app_id */ 12345);
3129
3130 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3131 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
3132 AUDIO_SESSION_NONE, user15AppUid);
3133
3134 ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceId);
3135}
3136
Oscar Azucena873d10f2023-01-12 18:34:42 -08003137TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithNoMatchingMix) {
3138 status_t ret;
3139 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3140 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3141 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3142 audioConfig.sample_rate = k48000SamplingRate;
3143 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3144 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3145 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3146 AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
3147 ASSERT_EQ(NO_ERROR, ret);
3148 std::vector<AudioMixMatchCriterion> navMatchCriteria = {
3149 createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
3150 /*exclude=*/ false)};
3151 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3152 AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
3153 ASSERT_EQ(NO_ERROR, ret);
3154 const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
3155 const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
3156 const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
Oscar Azucena4f49ef62023-01-25 23:32:13 -08003157 mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
Oscar Azucena873d10f2023-01-12 18:34:42 -08003158 audio_port_v7 navDevicePort;
3159 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3160 sCarBusNavigationOutput, &navDevicePort));
3161 audio_port_handle_t selectedDeviceId = navDevicePort.id;
3162 audio_io_handle_t output;
3163 audio_port_handle_t portId;
3164 const audio_attributes_t alarmAttribute = {
3165 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
3166 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3167
3168 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3169 k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
3170
3171 ASSERT_EQ(navDevicePort.id, selectedDeviceId);
3172}
3173
jiabin24ff57a2023-11-27 21:06:51 +00003174TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrForMMapWithPolicyMatched) {
3175 status_t ret;
3176 audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
3177 audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3178 audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
3179 audioConfig.sample_rate = k48000SamplingRate;
3180 std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
3181 createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
3182 ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
3183 AUDIO_DEVICE_OUT_BUS, sCarBusMmapOutput, audioConfig, mediaMatchCriteria);
3184 ASSERT_EQ(NO_ERROR, ret);
3185 ASSERT_EQ(NO_ERROR, ret);
3186 audio_port_v7 mmapDevicePort;
3187 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
3188 sCarBusMmapOutput, &mmapDevicePort));
3189 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3190 audio_io_handle_t output;
3191 audio_port_handle_t portId;
3192 const audio_attributes_t mediaAttribute = {
3193 AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
3194 AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
3195
3196 getOutputForAttr(
3197 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3198 k48000SamplingRate,
3199 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT),
3200 &output, &portId, mediaAttribute);
3201
3202 ASSERT_EQ(mmapDevicePort.id, selectedDeviceId);
3203}
3204
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003205class AudioPolicyManagerTVTest : public AudioPolicyManagerTestWithConfigurationFile {
3206protected:
3207 std::string getConfigFile() override { return sTvConfig; }
3208 void testHDMIPortSelection(audio_output_flags_t flags, const char* expectedMixPortName);
3209
3210 static const std::string sTvConfig;
3211};
3212
3213const std::string AudioPolicyManagerTVTest::sTvConfig =
3214 AudioPolicyManagerTVTest::sExecutableDir + "test_tv_apm_configuration.xml";
3215
3216// SwAudioOutputDescriptor doesn't populate flags so check against the port name.
3217void AudioPolicyManagerTVTest::testHDMIPortSelection(
3218 audio_output_flags_t flags, const char* expectedMixPortName) {
3219 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3220 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3221 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3222 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3223 audio_io_handle_t output;
3224 audio_port_handle_t portId;
Dean Wheatleyd082f472022-02-04 11:10:48 +11003225 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
3226 k48000SamplingRate, flags, &output, &portId);
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003227 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3228 ASSERT_NE(nullptr, outDesc.get());
jiabin19cdba52020-11-24 11:28:58 -08003229 audio_port_v7 port = {};
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003230 outDesc->toAudioPort(&port);
3231 mManager->releaseOutput(portId);
3232 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3233 AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3234 "" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
3235 ASSERT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3236 ASSERT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3237 ASSERT_STREQ(expectedMixPortName, port.name);
3238}
3239
3240TEST_F(AudioPolicyManagerTVTest, InitSuccess) {
3241 // SetUp must finish with no assertions.
3242}
3243
3244TEST_F(AudioPolicyManagerTVTest, Dump) {
3245 dumpToLog();
3246}
3247
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003248TEST_F(AudioPolicyManagerTVTest, MatchNoFlags) {
3249 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_NONE, "primary output");
3250}
3251
3252TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectNoHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003253 // b/140447125: The selected port must not have HW AV Sync flag (see the config file).
3254 testHDMIPortSelection(AUDIO_OUTPUT_FLAG_DIRECT, "direct");
3255}
3256
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003257TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectHwAvSync) {
Mikhail Naganov0756bbf2019-09-06 13:53:26 -07003258 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3259 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
3260 "tunnel");
3261}
Mikhail Naganov57ac2ce2019-09-11 09:29:41 -07003262
3263TEST_F(AudioPolicyManagerTVTest, MatchOutputDirectMMapNoIrq) {
3264 testHDMIPortSelection(static_cast<audio_output_flags_t>(
3265 AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3266 "low latency");
3267}
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003268
Mikhail Naganov285c1732024-09-05 17:26:50 -07003269class AudioPolicyManagerPhoneTest : public AudioPolicyManagerTestWithConfigurationFile {
3270protected:
3271 std::string getConfigFile() override { return sPhoneConfig; }
3272 void testOutputMixPortSelectionForAttr(audio_output_flags_t flags, audio_format_t format,
3273 int samplingRate, bool isMusic, const char* expectedMixPortName);
3274 void testOutputMixPortSelectionForStream(
3275 audio_stream_type_t stream, const char* expectedMixPortName);
3276 void verifyMixPortNameAndFlags(audio_io_handle_t output, const char* expectedMixPortName);
3277
3278 static const std::string sPhoneConfig;
3279 static const std::map<std::string, audio_output_flags_t> sMixPortFlags;
3280};
3281
3282const std::string AudioPolicyManagerPhoneTest::sPhoneConfig =
3283 AudioPolicyManagerPhoneTest::sExecutableDir + "test_phone_apm_configuration.xml";
3284
3285// Must be in sync with the contents of the sPhoneConfig file.
3286const std::map<std::string, audio_output_flags_t> AudioPolicyManagerPhoneTest::sMixPortFlags = {
3287 {"primary output",
3288 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_FAST)},
3289 {"direct", AUDIO_OUTPUT_FLAG_DIRECT},
3290 {"deep buffer", AUDIO_OUTPUT_FLAG_DEEP_BUFFER},
3291 {"compressed_offload",
3292 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3293 AUDIO_OUTPUT_FLAG_NON_BLOCKING |
3294 AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD)},
3295 {"raw", (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_FAST)},
3296 {"mmap_no_irq_out",
3297 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)},
3298 {"voip_rx", AUDIO_OUTPUT_FLAG_VOIP_RX},
3299};
3300
3301void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForAttr(
3302 audio_output_flags_t flags, audio_format_t format, int samplingRate, bool isMusic,
3303 const char* expectedMixPortName) {
3304 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3305 audio_io_handle_t output;
3306 audio_port_handle_t portId;
3307 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3308 if (isMusic) {
3309 attr.content_type = AUDIO_CONTENT_TYPE_MUSIC;
3310 attr.usage = AUDIO_USAGE_MEDIA;
3311 }
3312 getOutputForAttr(&selectedDeviceId, format, AUDIO_CHANNEL_OUT_STEREO, samplingRate, flags,
3313 &output, &portId, attr);
3314 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3315 mManager->releaseOutput(portId);
3316}
3317
3318void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForStream(
3319 audio_stream_type_t stream, const char* expectedMixPortName) {
3320 audio_io_handle_t output = mManager->getOutput(stream);
3321 EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
3322}
3323
3324void AudioPolicyManagerPhoneTest::verifyMixPortNameAndFlags(audio_io_handle_t output,
3325 const char* expectedMixPortName) {
3326 ALOGI("%s: checking output %d", __func__, output);
3327 sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
3328 ASSERT_NE(nullptr, outDesc.get());
3329 audio_port_v7 port = {};
3330 outDesc->toAudioPort(&port);
3331 EXPECT_EQ(AUDIO_PORT_TYPE_MIX, port.type);
3332 EXPECT_EQ(AUDIO_PORT_ROLE_SOURCE, port.role);
3333 ASSERT_STREQ(expectedMixPortName, port.name);
3334
3335 auto iter = sMixPortFlags.find(port.name);
3336 ASSERT_NE(iter, sMixPortFlags.end()) << "\"" << port.name << "\" is not in sMixPortFlags";
3337 auto actualFlags = mClient->getOpenOutputFlags(output);
3338 ASSERT_TRUE(actualFlags.has_value()) << "\"" << port.name << "\" was not opened via client";
3339 EXPECT_EQ(*actualFlags, iter->second);
3340}
3341
3342TEST_F(AudioPolicyManagerPhoneTest, InitSuccess) {
3343 // SetUp must finish with no assertions.
3344}
3345
Mikhail Naganov2788e012024-12-03 16:46:40 -08003346TEST_F(AudioPolicyManagerPhoneTest, Dump) {
3347 dumpToLog();
3348}
3349
3350TEST_F(AudioPolicyManagerPhoneTest, NoPatchChangesDuringAlarmPlayback) {
3351 audio_port_handle_t alarmPortId = AUDIO_PORT_HANDLE_NONE;
3352 audio_io_handle_t alarmOutput = AUDIO_IO_HANDLE_NONE;
3353 {
3354 // Uses STRATEGY_SONIFICATION, routed to AUDIO_DEVICE_OUT_SPEAKER_SAFE.
3355 audio_attributes_t attr = {
3356 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
3357 .usage = AUDIO_USAGE_ALARM,
3358 };
3359 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3360 ASSERT_NO_FATAL_FAILURE(getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
3361 AUDIO_CHANNEL_OUT_STEREO, 48000,
3362 AUDIO_OUTPUT_FLAG_NONE,
3363 &alarmOutput, &alarmPortId, attr));
3364 EXPECT_EQ(NO_ERROR, mManager->startOutput(alarmPortId));
3365 }
3366 const audio_patch lastPatchBefore = *(mClient->getLastAddedPatch());
3367
3368 {
3369 // Uses STRATEGY_MEDIA, routed to AUDIO_DEVICE_OUT_SPEAKER.
3370 audio_attributes_t attr = {
3371 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
3372 .usage = AUDIO_USAGE_MEDIA,
3373 };
3374 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3375 audio_port_handle_t notifPortId = AUDIO_PORT_HANDLE_NONE;
3376 audio_io_handle_t notifOutput = AUDIO_IO_HANDLE_NONE;
3377 ASSERT_NO_FATAL_FAILURE(getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
3378 AUDIO_CHANNEL_OUT_STEREO, 48000,
3379 AUDIO_OUTPUT_FLAG_NONE,
3380 &notifOutput, &notifPortId, attr));
3381 EXPECT_EQ(NO_ERROR, mManager->startOutput(notifPortId));
3382 }
3383 dumpToLog();
3384 const audio_patch lastPatchAfter = *(mClient->getLastAddedPatch());
3385 EXPECT_TRUE(audio_patches_are_equal(&lastPatchBefore, &lastPatchAfter)) <<
3386 "Unexpected change in patches detected";
3387}
3388
Mikhail Naganov285c1732024-09-05 17:26:50 -07003389enum {
3390 MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER,
3391 MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3392 MIX_PORT_ATTR_FLAGS_PARAMETER,
3393 MIX_PORT_ATTR_FORMAT_PARAMETER,
3394 MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER,
3395};
3396using MixPortSelectionForAttr =
3397 std::tuple<const char*, const char*, audio_output_flags_t, audio_format_t, int>;
3398
3399class AudioPolicyManagerOutputMixPortForAttrSelectionTest
3400 : public AudioPolicyManagerPhoneTest,
3401 public testing::WithParamInterface<MixPortSelectionForAttr> {
3402};
3403
3404// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3405// Instead, just run the same selection twice while altering the deep buffer for media setting.
3406TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags) {
3407 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3408 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3409 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3410 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3411 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3412 false /*isMusic*/,
3413 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3414}
3415TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_Music) {
3416 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3417 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForAttr(
3418 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3419 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3420 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3421 true /*isMusic*/,
3422 std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam())));
3423}
3424TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia) {
3425 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3426 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3427 ASSERT_NO_FATAL_FAILURE(
3428 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3429 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3430 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3431 false /*isMusic*/,
3432 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3433 GetParam()) ?: fallbackName));
3434}
3435TEST_P(AudioPolicyManagerOutputMixPortForAttrSelectionTest, SelectPortByFlags_DeepMedia_Music) {
3436 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3437 const char* fallbackName = std::get<MIX_PORT_ATTR_EXPECTED_NAME_PARAMETER>(GetParam());
3438 ASSERT_NO_FATAL_FAILURE(
3439 testOutputMixPortSelectionForAttr(std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(GetParam()),
3440 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(GetParam()),
3441 std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(GetParam()),
3442 true /*isMusic*/,
3443 std::get<MIX_PORT_ATTR_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3444 GetParam()) ?: fallbackName));
3445}
3446
3447INSTANTIATE_TEST_CASE_P(AudioPolicyManagerOutputMixPortForAttrSelection,
3448 AudioPolicyManagerOutputMixPortForAttrSelectionTest,
3449 ::testing::Values(
3450 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3451 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3452 std::make_tuple("primary output", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3453 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3454 // Note: this goes to "direct" because 384000 > SAMPLE_RATE_HZ_MAX (192000)
3455 std::make_tuple("direct", "deep buffer", AUDIO_OUTPUT_FLAG_NONE,
3456 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3457 std::make_tuple("primary output", nullptr, AUDIO_OUTPUT_FLAG_FAST,
3458 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3459 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3460 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k96000SamplingRate),
3461 std::make_tuple("direct", nullptr, AUDIO_OUTPUT_FLAG_DIRECT,
3462 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3463 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3464 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate),
3465 std::make_tuple("deep buffer", nullptr, AUDIO_OUTPUT_FLAG_DEEP_BUFFER,
3466 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3467 std::make_tuple("compressed_offload", nullptr,
3468 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
3469 AUDIO_OUTPUT_FLAG_NON_BLOCKING),
3470 AUDIO_FORMAT_MP3, AudioPolicyManagerTest::k48000SamplingRate),
3471 std::make_tuple("raw", nullptr,
3472 AUDIO_OUTPUT_FLAG_RAW, AUDIO_FORMAT_PCM_32_BIT,
3473 AudioPolicyManagerTest::k48000SamplingRate),
3474 std::make_tuple("mmap_no_irq_out", nullptr,
3475 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3476 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3477 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k48000SamplingRate),
3478 std::make_tuple("mmap_no_irq_out", nullptr,
3479 (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT |
3480 AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
3481 AUDIO_FORMAT_PCM_FLOAT, AudioPolicyManagerTest::k384000SamplingRate),
3482 std::make_tuple("voip_rx", nullptr, AUDIO_OUTPUT_FLAG_VOIP_RX,
3483 AUDIO_FORMAT_PCM_16_BIT, AudioPolicyManagerTest::k48000SamplingRate)),
3484 [](const ::testing::TestParamInfo<MixPortSelectionForAttr>& info) {
3485 static const std::string flagPrefix = "AUDIO_OUTPUT_FLAG_";
3486 static const std::string formatPrefix = "AUDIO_FORMAT_";
3487 std::string flags;
3488 TypeConverter<OutputFlagTraits>::maskToString(
3489 std::get<MIX_PORT_ATTR_FLAGS_PARAMETER>(info.param), flags, "__");
3490 size_t index = 0;
3491 while (true) {
3492 index = flags.rfind(flagPrefix);
3493 if (index == std::string::npos) break;
3494 flags.erase(index, flagPrefix.length());
3495 }
3496 std::string format;
3497 TypeConverter<FormatTraits>::toString(
3498 std::get<MIX_PORT_ATTR_FORMAT_PARAMETER>(info.param), format);
3499 if (size_t index = format.find(formatPrefix); index != std::string::npos) {
3500 format.erase(index, formatPrefix.length());
3501 }
3502 return flags + "__" + format + "__" +
3503 std::to_string(std::get<MIX_PORT_ATTR_SAMPLING_RATE_PARAMETER>(info.param));
3504 }
3505);
3506
3507
3508enum {
3509 MIX_PORT_STRM_EXPECTED_NAME_PARAMETER,
3510 MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER,
3511 MIX_PORT_STRM_STREAM_PARAMETER,
3512};
3513using MixPortSelectionForStream =
3514 std::tuple<const char*, const char*, audio_stream_type_t>;
3515
3516class AudioPolicyManagerOutputMixPortForStreamSelectionTest
3517 : public AudioPolicyManagerPhoneTest,
3518 public testing::WithParamInterface<MixPortSelectionForStream> {
3519};
3520
3521// There is no easy way to create a flat tuple from tuples via ::testing::Combine.
3522// Instead, just run the same selection twice while altering the deep buffer for media setting.
3523TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_NoDBFM) {
3524 mConfig->setUseDeepBufferForMediaOverrideForTests(false);
3525 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3526 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3527 std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam())));
3528}
3529TEST_P(AudioPolicyManagerOutputMixPortForStreamSelectionTest, SelectPort_WithDBFM) {
3530 mConfig->setUseDeepBufferForMediaOverrideForTests(true);
3531 const char* fallbackName = std::get<MIX_PORT_STRM_EXPECTED_NAME_PARAMETER>(GetParam());
3532 ASSERT_NO_FATAL_FAILURE(testOutputMixPortSelectionForStream(
3533 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(GetParam()),
3534 std::get<MIX_PORT_STRM_EXPECTED_NAME_WITH_DBFM_PARAMETER>(
3535 GetParam()) ?: fallbackName));
3536}
3537
3538INSTANTIATE_TEST_CASE_P(
3539 AudioPolicyManagerOutputMixPortForStreamSelection,
3540 AudioPolicyManagerOutputMixPortForStreamSelectionTest,
3541 ::testing::Values(std::make_tuple("primary output", nullptr, AUDIO_STREAM_DEFAULT),
3542 std::make_tuple("primary output", nullptr, AUDIO_STREAM_SYSTEM),
3543 std::make_tuple("primary output", nullptr, AUDIO_STREAM_RING),
3544 std::make_tuple("primary output", "deep buffer", AUDIO_STREAM_MUSIC),
3545 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ALARM),
3546 std::make_tuple("primary output", nullptr, AUDIO_STREAM_NOTIFICATION),
3547 std::make_tuple("primary output", nullptr, AUDIO_STREAM_BLUETOOTH_SCO),
3548 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ENFORCED_AUDIBLE),
3549 std::make_tuple("primary output", nullptr, AUDIO_STREAM_DTMF),
3550 std::make_tuple("primary output", nullptr, AUDIO_STREAM_TTS),
3551 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ACCESSIBILITY),
3552 std::make_tuple("primary output", nullptr, AUDIO_STREAM_ASSISTANT)),
3553 [](const ::testing::TestParamInfo<MixPortSelectionForStream>& info) {
3554 static const std::string streamPrefix = "AUDIO_STREAM_";
3555 std::string stream;
3556 TypeConverter<StreamTraits>::toString(
3557 std::get<MIX_PORT_STRM_STREAM_PARAMETER>(info.param), stream);
3558 if (size_t index = stream.find(streamPrefix); index != std::string::npos) {
3559 stream.erase(index, streamPrefix.length());
3560 }
3561 return stream;
3562 }
3563);
3564
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003565class AudioPolicyManagerDynamicHwModulesTest : public AudioPolicyManagerTestWithConfigurationFile {
3566protected:
3567 void SetUpManagerConfig() override;
3568};
3569
3570void AudioPolicyManagerDynamicHwModulesTest::SetUpManagerConfig() {
Mikhail Naganovd4c21aa2021-10-05 15:10:16 -07003571 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUpManagerConfig());
Mikhail Naganovc0d04982020-03-02 21:02:28 +00003572 // Only allow successful opening of "primary" hw module during APM initialization.
3573 mClient->swapAllowedModuleNames({"primary"});
3574}
3575
3576TEST_F(AudioPolicyManagerDynamicHwModulesTest, InitSuccess) {
3577 // SetUp must finish with no assertions.
3578}
3579
3580TEST_F(AudioPolicyManagerDynamicHwModulesTest, DynamicAddition) {
3581 const auto handleBefore = mClient->peekNextModuleHandle();
3582 mManager->onNewAudioModulesAvailable();
3583 ASSERT_EQ(handleBefore, mClient->peekNextModuleHandle());
3584 // Reset module loading restrictions.
3585 mClient->swapAllowedModuleNames();
3586 mManager->onNewAudioModulesAvailable();
3587 const auto handleAfter = mClient->peekNextModuleHandle();
3588 ASSERT_GT(handleAfter, handleBefore);
3589 mManager->onNewAudioModulesAvailable();
3590 ASSERT_EQ(handleAfter, mClient->peekNextModuleHandle());
3591}
3592
3593TEST_F(AudioPolicyManagerDynamicHwModulesTest, AddedDeviceAvailable) {
3594 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, mManager->getDeviceConnectionState(
3595 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3596 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3597 mManager->onNewAudioModulesAvailable();
3598 ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE, mManager->getDeviceConnectionState(
3599 AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
3600}
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003601
3602TEST_F(AudioPolicyManagerDynamicHwModulesTest, ListAddedAudioPorts) {
3603 ASSERT_FALSE(
3604 findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
3605 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3606 mManager->onNewAudioModulesAvailable();
jiabin19cdba52020-11-24 11:28:58 -08003607 struct audio_port_v7 port;
Mikhail Naganovd0e2c742020-03-25 15:59:59 -07003608 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
3609}
3610
3611TEST_F(AudioPolicyManagerDynamicHwModulesTest, ClientIsUpdated) {
3612 const size_t prevAudioPortListUpdateCount = mClient->getAudioPortListUpdateCount();
3613 const uint32_t prevAudioPortGeneration = mManager->getAudioPortGeneration();
3614 mClient->swapAllowedModuleNames({"primary", "r_submix"});
3615 mManager->onNewAudioModulesAvailable();
3616 EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
3617 EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
3618}
Jiabin Huang3b98d322020-09-03 17:54:16 +00003619
3620using DevicesRoleForCapturePresetParam = std::tuple<audio_source_t, device_role_t>;
3621
3622class AudioPolicyManagerDevicesRoleForCapturePresetTest
3623 : public AudioPolicyManagerTestWithConfigurationFile,
3624 public testing::WithParamInterface<DevicesRoleForCapturePresetParam> {
3625protected:
3626 // The `inputDevice` and `inputDevice2` indicate the audio devices type to be used for setting
3627 // device role. They must be declared in the test_audio_policy_configuration.xml
3628 AudioDeviceTypeAddr inputDevice = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
3629 AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_HDMI, "");
3630};
3631
3632TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCapturePreset) {
3633 const audio_source_t audioSource = std::get<0>(GetParam());
3634 const device_role_t role = std::get<1>(GetParam());
3635
3636 // Test invalid device when setting
3637 const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
3638 const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
3639 ASSERT_EQ(BAD_VALUE,
3640 mManager->setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3641 ASSERT_EQ(BAD_VALUE,
3642 mManager->addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3643 AudioDeviceTypeAddrVector devices;
3644 ASSERT_EQ(NAME_NOT_FOUND,
3645 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3646 ASSERT_TRUE(devices.empty());
3647 ASSERT_EQ(BAD_VALUE,
3648 mManager->removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
3649
3650 // Without setting, call get/remove/clear must fail
3651 ASSERT_EQ(NAME_NOT_FOUND,
3652 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3653 ASSERT_EQ(NAME_NOT_FOUND,
3654 mManager->removeDevicesRoleForCapturePreset(audioSource, role, devices));
3655 ASSERT_EQ(NAME_NOT_FOUND,
3656 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3657
3658 // Test set/get devices role
3659 const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
3660 ASSERT_EQ(NO_ERROR,
3661 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3662 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3663 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice));
3664
3665 // Test setting will change the previously set devices
3666 const AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
3667 ASSERT_EQ(NO_ERROR,
3668 mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
3669 devices.clear();
3670 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3671 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3672
3673 // Test add devices
3674 ASSERT_EQ(NO_ERROR,
3675 mManager->addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3676 devices.clear();
3677 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3678 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice, inputDevice2));
3679
3680 // Test remove devices
3681 ASSERT_EQ(NO_ERROR,
3682 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3683 devices.clear();
3684 ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3685 EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
3686
3687 // Test remove devices that are not set as the device role
3688 ASSERT_EQ(BAD_VALUE,
3689 mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
3690
3691 // Test clear devices
3692 ASSERT_EQ(NO_ERROR,
3693 mManager->clearDevicesRoleForCapturePreset(audioSource, role));
3694 devices.clear();
3695 ASSERT_EQ(NAME_NOT_FOUND,
3696 mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
3697}
3698
jiabin14662b52023-03-06 21:35:29 +00003699TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) {
3700 const audio_source_t source = AUDIO_SOURCE_MIC;
3701 const device_role_t role = DEVICE_ROLE_PREFERRED;
3702 const std::string address = "card=1;device=0";
3703 const std::string deviceName = "randomName";
3704
3705 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3706 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3707 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3708 auto availableDevices = mManager->getAvailableInputDevices();
3709 ASSERT_GT(availableDevices.size(), 1);
3710
3711 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3712 attr.source = source;
3713 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003714 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3715 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003716 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003717 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003718 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3719 ASSERT_NE(nullptr, selectedDevice);
3720
3721 sp<DeviceDescriptor> preferredDevice = nullptr;
3722 for (const auto& device : availableDevices) {
3723 if (device != selectedDevice) {
3724 preferredDevice = device;
3725 break;
3726 }
3727 }
3728 ASSERT_NE(nullptr, preferredDevice);
3729 // After setting preferred device for capture preset, the selected device for input should be
3730 // the preferred device.
3731 ASSERT_EQ(NO_ERROR,
3732 mManager->setDevicesRoleForCapturePreset(source, role,
3733 {preferredDevice->getDeviceTypeAddr()}));
3734 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003735 input = AUDIO_PORT_HANDLE_NONE;
3736 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003737 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003738 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003739 ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3740
3741 // After clearing preferred device for capture preset, the selected device for input should be
3742 // the same as original one.
3743 ASSERT_EQ(NO_ERROR,
3744 mManager->clearDevicesRoleForCapturePreset(source, role));
3745 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003746 input = AUDIO_PORT_HANDLE_NONE;
3747 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003748 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003749 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003750 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3751
3752 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3753 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3754 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3755}
3756
3757TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) {
3758 const audio_source_t source = AUDIO_SOURCE_MIC;
3759 const device_role_t role = DEVICE_ROLE_DISABLED;
3760 const std::string address = "card=1;device=0";
3761 const std::string deviceName = "randomName";
3762
3763 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3764 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3765 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3766 auto availableDevices = mManager->getAvailableInputDevices();
3767 ASSERT_GT(availableDevices.size(), 1);
3768
3769 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3770 attr.source = source;
3771 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003772 audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
3773 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003774 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003775 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003776 auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
3777 ASSERT_NE(nullptr, selectedDevice);
3778
3779 // After setting disabled device for capture preset, the disabled device must not be
3780 // selected for input.
3781 ASSERT_EQ(NO_ERROR,
3782 mManager->setDevicesRoleForCapturePreset(source, role,
3783 {selectedDevice->getDeviceTypeAddr()}));
3784 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003785 input = AUDIO_PORT_HANDLE_NONE;
3786 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1,
3787 &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003788 AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003789 ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3790
3791 // After clearing disabled device for capture preset, the selected device for input should be
3792 // the original one.
3793 ASSERT_EQ(NO_ERROR,
3794 mManager->clearDevicesRoleForCapturePreset(source, role));
3795 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
François Gaffie6ebbce02023-07-19 13:27:53 +02003796 input = AUDIO_PORT_HANDLE_NONE;
3797 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
jiabin14662b52023-03-06 21:35:29 +00003798 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003799 k48000SamplingRate));
jiabin14662b52023-03-06 21:35:29 +00003800 ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
3801
3802 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3803 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3804 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3805}
3806
Jiabin Huang3b98d322020-09-03 17:54:16 +00003807INSTANTIATE_TEST_CASE_P(
3808 DevicesRoleForCapturePresetOperation,
3809 AudioPolicyManagerDevicesRoleForCapturePresetTest,
3810 testing::Values(
3811 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_MIC, DEVICE_ROLE_PREFERRED}),
3812 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_UPLINK,
3813 DEVICE_ROLE_PREFERRED}),
3814 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_DOWNLINK,
3815 DEVICE_ROLE_PREFERRED}),
3816 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_CALL, DEVICE_ROLE_PREFERRED}),
3817 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_CAMCORDER, DEVICE_ROLE_PREFERRED}),
3818 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_RECOGNITION,
3819 DEVICE_ROLE_PREFERRED}),
3820 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_COMMUNICATION,
3821 DEVICE_ROLE_PREFERRED}),
3822 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_REMOTE_SUBMIX,
3823 DEVICE_ROLE_PREFERRED}),
3824 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_UNPROCESSED, DEVICE_ROLE_PREFERRED}),
3825 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_PERFORMANCE,
3826 DEVICE_ROLE_PREFERRED}),
3827 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_ECHO_REFERENCE,
3828 DEVICE_ROLE_PREFERRED}),
3829 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_FM_TUNER, DEVICE_ROLE_PREFERRED}),
3830 DevicesRoleForCapturePresetParam({AUDIO_SOURCE_HOTWORD, DEVICE_ROLE_PREFERRED})
3831 )
3832 );
François Gaffie6ebbce02023-07-19 13:27:53 +02003833
3834
3835const effect_descriptor_t TEST_EFFECT_DESC = {
3836 {0xf2a4bb20, 0x0c3c, 0x11e3, 0x8b07, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
3837 {0xff93e360, 0x0c3c, 0x11e3, 0x8a97, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
3838 EFFECT_CONTROL_API_VERSION,
3839 EFFECT_FLAG_TYPE_PRE_PROC,
3840 0,
3841 1,
3842 "APM test Effect",
3843 "The Android Open Source Project",
3844};
3845
3846class AudioPolicyManagerPreProcEffectTest : public AudioPolicyManagerTestWithConfigurationFile {
3847};
3848
3849TEST_F(AudioPolicyManagerPreProcEffectTest, DeviceDisconnectWhileClientActive) {
3850 const audio_source_t source = AUDIO_SOURCE_MIC;
3851 const std::string address = "BUS00_MIC";
3852 const std::string deviceName = "randomName";
3853 audio_port_handle_t portId;
3854 audio_devices_t type = AUDIO_DEVICE_IN_BUS;
3855
3856 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(type,
3857 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), deviceName.c_str(),
3858 AUDIO_FORMAT_DEFAULT));
3859 auto availableDevices = mManager->getAvailableInputDevices();
3860 ASSERT_GT(availableDevices.size(), 1);
3861
3862 audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
3863 attr.source = source;
3864 audio_session_t session = TEST_SESSION_ID;
3865 audio_io_handle_t inputClientHandle = 777;
3866 int effectId = 666;
3867 audio_port_v7 devicePort;
3868 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3869
3870 audio_port_handle_t routedPortId = devicePort.id;
3871 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3872 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003873 k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId));
François Gaffie6ebbce02023-07-19 13:27:53 +02003874 ASSERT_EQ(devicePort.id, routedPortId);
3875 auto selectedDevice = availableDevices.getDeviceFromId(routedPortId);
3876 ASSERT_NE(nullptr, selectedDevice);
3877
3878 // Add a pre processing effect on the input client session
3879 ASSERT_EQ(NO_ERROR, mManager->registerEffect(&TEST_EFFECT_DESC, inputClientHandle,
3880 PRODUCT_STRATEGY_NONE, session, effectId));
3881
3882 ASSERT_EQ(NO_ERROR, mManager->startInput(portId));
3883
3884 // Force a device disconnection to close the input, no crash expected of APM
3885 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3886 type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3887 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3888
3889 // Reconnect the device
3890 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
3891 type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3892 address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
3893
3894 inputClientHandle += 1;
3895 ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, type, address, &devicePort));
3896 routedPortId = devicePort.id;
3897
3898 // Reconnect the client changing voluntarily the io, but keeping the session to get the
3899 // effect attached again
3900 ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &inputClientHandle, session, 1, &routedPortId,
3901 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
Mikhail Naganov285c1732024-09-05 17:26:50 -07003902 k48000SamplingRate));
François Gaffie6ebbce02023-07-19 13:27:53 +02003903
3904 // unregister effect should succeed since effect shall have been restore on the client session
3905 ASSERT_EQ(NO_ERROR, mManager->unregisterEffect(effectId));
Mikhail Naganovf88c2f32024-04-16 15:01:13 -07003906}
jiabin220eea12024-05-17 17:55:20 +00003907
3908class AudioPolicyManagerTestBitPerfectBase : public AudioPolicyManagerTestWithConfigurationFile {
3909protected:
3910 void SetUp() override;
3911 void TearDown() override;
3912
3913 void startBitPerfectOutput();
3914 void reset();
3915 void getBitPerfectOutput(status_t expected);
3916
3917 const audio_format_t mBitPerfectFormat = AUDIO_FORMAT_PCM_16_BIT;
3918 const audio_channel_mask_t mBitPerfectChannelMask = AUDIO_CHANNEL_OUT_STEREO;
3919 const uint32_t mBitPerfectSampleRate = 48000;
3920 const uid_t mUid = 1234;
3921 audio_port_handle_t mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3922
3923 audio_io_handle_t mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
3924 audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
3925 audio_port_handle_t mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
3926
3927 static constexpr audio_attributes_t sMediaAttr = {
3928 .content_type = AUDIO_CONTENT_TYPE_MUSIC,
3929 .usage = AUDIO_USAGE_MEDIA,
3930 };
3931};
3932
3933void AudioPolicyManagerTestBitPerfectBase::SetUp() {
3934 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::SetUp());
3935
3936 mClient->addSupportedFormat(mBitPerfectFormat);
3937 mClient->addSupportedChannelMask(mBitPerfectChannelMask);
3938 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3939 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
3940 "", "", AUDIO_FORMAT_DEFAULT));
3941 auto devices = mManager->getAvailableOutputDevices();
3942 mUsbPortId = AUDIO_PORT_HANDLE_NONE;
3943 for (auto device : devices) {
3944 if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
3945 mUsbPortId = device->getId();
3946 break;
3947 }
3948 }
3949 EXPECT_NE(AUDIO_PORT_HANDLE_NONE, mUsbPortId);
3950
3951 std::vector<audio_mixer_attributes_t> mixerAttributes;
3952 EXPECT_EQ(NO_ERROR, mManager->getSupportedMixerAttributes(mUsbPortId, mixerAttributes));
3953 EXPECT_GT(mixerAttributes.size(), 0);
3954 size_t bitPerfectIndex = 0;
3955 for (; bitPerfectIndex < mixerAttributes.size(); ++bitPerfectIndex) {
3956 if (mixerAttributes[bitPerfectIndex].mixer_behavior == AUDIO_MIXER_BEHAVIOR_BIT_PERFECT) {
3957 break;
3958 }
3959 }
3960 EXPECT_LT(bitPerfectIndex, mixerAttributes.size());
3961 EXPECT_EQ(mBitPerfectFormat, mixerAttributes[bitPerfectIndex].config.format);
3962 EXPECT_EQ(mBitPerfectChannelMask, mixerAttributes[bitPerfectIndex].config.channel_mask);
3963 EXPECT_EQ(mBitPerfectSampleRate, mixerAttributes[bitPerfectIndex].config.sample_rate);
3964 EXPECT_EQ(NO_ERROR,
3965 mManager->setPreferredMixerAttributes(
3966 &sMediaAttr, mUsbPortId, mUid, &mixerAttributes[bitPerfectIndex]));
3967}
3968
3969void AudioPolicyManagerTestBitPerfectBase::TearDown() {
3970 EXPECT_EQ(NO_ERROR,
3971 mManager->clearPreferredMixerAttributes(&sMediaAttr, mUsbPortId, mUid));
3972 ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
3973 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
3974 "", "", AUDIO_FORMAT_LDAC));
3975
3976 ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTestWithConfigurationFile::TearDown());
3977}
3978
3979void AudioPolicyManagerTestBitPerfectBase::startBitPerfectOutput() {
3980 reset();
3981 bool isBitPerfect;
3982
3983 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3984 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3985 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3986 status_t status = mManager->startOutput(mBitPerfectPortId);
3987 if (status == DEAD_OBJECT) {
3988 getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
3989 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
3990 &mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
3991 status = mManager->startOutput(mBitPerfectPortId);
3992 }
3993 EXPECT_EQ(NO_ERROR, status);
3994 EXPECT_TRUE(isBitPerfect);
3995 EXPECT_NE(AUDIO_IO_HANDLE_NONE, mBitPerfectOutput);
3996 const auto bitPerfectOutputDesc = mManager->getOutputs().valueFor(mBitPerfectOutput);
3997 EXPECT_NE(nullptr, bitPerfectOutputDesc);
3998 EXPECT_EQ(AUDIO_OUTPUT_FLAG_BIT_PERFECT,
3999 bitPerfectOutputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
4000};
4001
4002void AudioPolicyManagerTestBitPerfectBase::reset() {
4003 mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
4004 mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4005 mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
4006}
4007
4008void AudioPolicyManagerTestBitPerfectBase::getBitPerfectOutput(status_t expected) {
4009 reset();
4010 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
4011 AttributionSourceState attributionSource = createAttributionSourceState(mUid);
4012 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4013 config.sample_rate = mBitPerfectSampleRate;
4014 config.channel_mask = mBitPerfectChannelMask;
4015 config.format = mBitPerfectFormat;
4016 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_BIT_PERFECT;
4017 AudioPolicyInterface::output_type_t outputType;
4018 bool isSpatialized;
4019 bool isBitPerfect;
4020 EXPECT_EQ(expected,
4021 mManager->getOutputForAttr(&sMediaAttr, &mBitPerfectOutput, AUDIO_SESSION_NONE,
4022 &stream, attributionSource, &config, &flags,
4023 &mSelectedDeviceId, &mBitPerfectPortId, {}, &outputType,
4024 &isSpatialized, &isBitPerfect));
4025}
4026
4027class AudioPolicyManagerTestBitPerfect : public AudioPolicyManagerTestBitPerfectBase {
4028};
4029
4030TEST_F(AudioPolicyManagerTestBitPerfect, UseBitPerfectOutput) {
4031 const uid_t anotherUid = 5678;
4032 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4033 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4034 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
4035 bool isBitPerfect;
4036
4037 // When there is no active bit-perfect playback, the output selection will follow default
4038 // routing strategy.
4039 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
4040 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4041 AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4042 EXPECT_FALSE(isBitPerfect);
4043 EXPECT_NE(AUDIO_IO_HANDLE_NONE, output);
4044 const auto outputDesc = mManager->getOutputs().valueFor(output);
4045 EXPECT_NE(nullptr, outputDesc);
4046 EXPECT_NE(AUDIO_OUTPUT_FLAG_BIT_PERFECT, outputDesc->mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT);
4047
4048 // Start bit-perfect playback
4049 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4050
4051 // If the playback is from preferred mixer attributes owner but the request doesn't match
4052 // preferred mixer attributes, it will not be bit-perfect.
4053 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
4054 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4055 AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4056 EXPECT_FALSE(isBitPerfect);
4057 EXPECT_EQ(mBitPerfectOutput, output);
4058
4059 // When bit-perfect playback is active, all other playback will be routed to bit-perfect output.
4060 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4061 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4062 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4063 EXPECT_FALSE(isBitPerfect);
4064 EXPECT_EQ(mBitPerfectOutput, output);
4065
4066 // When bit-pefect playback is active, dtmf will also be routed to bit-perfect output.
4067 const audio_attributes_t dtmfAttr = {
4068 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
4069 .usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
4070 };
4071 audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
4072 selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4073 portId = AUDIO_PORT_HANDLE_NONE;
4074 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4075 48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
4076 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4077 EXPECT_FALSE(isBitPerfect);
4078 EXPECT_EQ(mBitPerfectOutput, dtmfOutput);
4079
4080 // When configuration matches preferred mixer attributes, which is bit-perfect, but the client
4081 // is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
4082 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4083 mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
4084 AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
4085 EXPECT_FALSE(isBitPerfect);
4086 EXPECT_EQ(mBitPerfectOutput, output);
4087}
4088
4089TEST_F_WITH_FLAGS(
4090 AudioPolicyManagerTestBitPerfect,
4091 InternalMuteWhenBitPerfectCLientIsActive,
4092 REQUIRES_FLAGS_ENABLED(
4093 ACONFIG_FLAG(com::android::media::audioserver,
4094 fix_concurrent_playback_behavior_with_bit_perfect_client))
4095) {
4096 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4097
4098 // When bit-perfect playback is active, the system sound will be routed to bit-perfect output.
4099 // The system sound will be muted internally in this case. The bit-perfect client will be
4100 // played normally.
4101 const uint32_t anotherSampleRate = 44100;
4102 audio_port_handle_t systemSoundPortId = AUDIO_PORT_HANDLE_NONE;
4103 audio_io_handle_t systemSoundOutput = AUDIO_IO_HANDLE_NONE;
4104 const audio_attributes_t systemSoundAttr = {
4105 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4106 .usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION,
4107 };
4108 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4109 bool isBitPerfect;
4110 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4111 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &systemSoundOutput,
4112 &systemSoundPortId, systemSoundAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
4113 EXPECT_FALSE(isBitPerfect);
4114 EXPECT_EQ(mBitPerfectOutput, systemSoundOutput);
4115 EXPECT_EQ(NO_ERROR, mManager->startOutput(systemSoundPortId));
4116 EXPECT_TRUE(mClient->getTrackInternalMute(systemSoundPortId));
4117 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4118 EXPECT_EQ(NO_ERROR, mManager->stopOutput(systemSoundPortId));
4119 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4120
4121 // When bit-perfect playback is active, the notification will be routed to bit-perfect output.
4122 // The notification sound will be played normally while the bit-perfect client will be muted
4123 // internally.
4124 audio_port_handle_t notificationPortId = AUDIO_PORT_HANDLE_NONE;
4125 audio_io_handle_t notificationOutput = AUDIO_IO_HANDLE_NONE;
4126 const audio_attributes_t notificationAttr = {
4127 .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
4128 .usage = AUDIO_USAGE_NOTIFICATION,
4129 };
4130 getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
4131 anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &notificationOutput,
4132 &notificationPortId, notificationAttr, AUDIO_SESSION_NONE, mUid,
4133 &isBitPerfect);
4134 EXPECT_FALSE(isBitPerfect);
4135 EXPECT_EQ(mBitPerfectOutput, notificationOutput);
4136 EXPECT_EQ(NO_ERROR, mManager->startOutput(notificationPortId));
4137 EXPECT_FALSE(mClient->getTrackInternalMute(notificationPortId));
4138 EXPECT_TRUE(mClient->getTrackInternalMute(mBitPerfectPortId));
4139 EXPECT_EQ(NO_ERROR, mManager->stopOutput(notificationPortId));
4140 EXPECT_FALSE(mClient->getTrackInternalMute(mBitPerfectPortId));
4141
4142 EXPECT_EQ(NO_ERROR, mManager->stopOutput(mBitPerfectPortId));
4143}
4144
4145class AudioPolicyManagerTestBitPerfectPhoneMode : public AudioPolicyManagerTestBitPerfectBase,
4146 public testing::WithParamInterface<audio_mode_t> {
4147};
4148
4149TEST_P(AudioPolicyManagerTestBitPerfectPhoneMode, RejectBitPerfectWhenPhoneModeIsNotNormal) {
4150 if (!com::android::media::audioserver::
4151 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4152 GTEST_SKIP()
4153 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4154 }
4155
4156 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4157
4158 audio_mode_t mode = GetParam();
4159 mManager->setPhoneState(mode);
4160 // When the phone mode is not normal, the bit-perfect output will be reopned
4161 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4162
4163 // When the phone mode is not normal, the bit-perfect output will be closed.
4164 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4165
4166 mManager->setPhoneState(AUDIO_MODE_NORMAL);
4167}
4168
4169INSTANTIATE_TEST_CASE_P(
4170 PhoneMode,
4171 AudioPolicyManagerTestBitPerfectPhoneMode,
4172 testing::Values(AUDIO_MODE_IN_CALL,
4173 AUDIO_MODE_RINGTONE,
4174 AUDIO_MODE_IN_COMMUNICATION,
4175 AUDIO_MODE_CALL_SCREEN)
4176);
4177
4178class AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive :
4179 public AudioPolicyManagerTestBitPerfectBase,
4180 public testing::WithParamInterface<audio_usage_t> {
4181};
4182
4183TEST_P(AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4184 RejectBitPerfectWhenHigherPriorityUseCaseIsActive) {
4185 if (!com::android::media::audioserver::
4186 fix_concurrent_playback_behavior_with_bit_perfect_client()) {
4187 GTEST_SKIP()
4188 << "Flag fix_concurrent_playback_behavior_with_bit_perfect_client is not enabled";
4189 }
4190
4191 ASSERT_NO_FATAL_FAILURE(startBitPerfectOutput());
4192
4193 audio_attributes_t attr = {
4194 .usage = GetParam(),
4195 .content_type = AUDIO_CONTENT_TYPE_UNKNOWN
4196 };
4197 audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
4198 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
4199 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4200 ASSERT_NO_FATAL_FAILURE(
4201 getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
4202 48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, attr));
4203 EXPECT_NE(mBitPerfectOutput, output);
4204 EXPECT_EQ(NO_ERROR, mManager->startOutput(portId));
4205 // When a high priority use case is active, the bit-perfect output will be closed.
4206 EXPECT_EQ(nullptr, mManager->getOutputs().valueFor(mBitPerfectOutput));
4207
4208 // When any higher priority use case is active, the bit-perfect request will be rejected.
4209 ASSERT_NO_FATAL_FAILURE(getBitPerfectOutput(INVALID_OPERATION));
4210}
4211
4212INSTANTIATE_TEST_CASE_P(
4213 HigherPriorityUseCases,
4214 AudioPolicyManagerTestBitPerfectHigherPriorityUseCaseActive,
4215 testing::Values(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4216 AUDIO_USAGE_ALARM)
4217);
Mikhail Naganov7f7344a2024-09-06 10:23:24 -07004218
4219int main(int argc, char** argv) {
4220 ::testing::InitGoogleTest(&argc, argv);
4221 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
4222 return RUN_ALL_TESTS();
4223}