blob: 975ce8fd0861612793fad1e963aad82d2df65e7a [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
Mikhail Naganov04a86632017-12-15 18:01:42 -080017#include <memory>
18#include <set>
Mikhail Naganov21b43362018-06-04 10:37:09 -070019#include <sys/wait.h>
20#include <unistd.h>
Mikhail Naganov04a86632017-12-15 18:01:42 -080021
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080022#include <gtest/gtest.h>
23
Mikhail Naganov21b43362018-06-04 10:37:09 -070024#define LOG_TAG "APM_Test"
25#include <log/log.h>
Mikhail Naganovdc769682018-05-04 15:34:08 -070026#include <media/PatchBuilder.h>
27
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080028#include "AudioPolicyTestClient.h"
29#include "AudioPolicyTestManager.h"
30
31using namespace android;
32
Mikhail Naganove13c6792019-05-14 10:32:51 -070033TEST(AudioPolicyManagerTestInit, EngineFailure) {
34 AudioPolicyTestClient client;
35 AudioPolicyTestManager manager(&client);
36 manager.getConfig().setDefault();
37 manager.getConfig().setEngineLibraryNameSuffix("non-existent");
38 ASSERT_EQ(NO_INIT, manager.initialize());
39 ASSERT_EQ(NO_INIT, manager.initCheck());
40}
41
42TEST(AudioPolicyManagerTestInit, ClientFailure) {
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080043 AudioPolicyTestClient client;
44 AudioPolicyTestManager manager(&client);
45 manager.getConfig().setDefault();
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080046 // Since the default client fails to open anything,
47 // APM should indicate that the initialization didn't succeed.
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080048 ASSERT_EQ(NO_INIT, manager.initialize());
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080049 ASSERT_EQ(NO_INIT, manager.initCheck());
50}
51
52
Mikhail Naganov04a86632017-12-15 18:01:42 -080053class AudioPolicyManagerTestClient : public AudioPolicyTestClient {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080054 public:
Mikhail Naganov04a86632017-12-15 18:01:42 -080055 // AudioPolicyClientInterface implementation
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080056 audio_module_handle_t loadHwModule(const char* /*name*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080057 return mNextModuleHandle++;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080058 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080059
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080060 status_t openOutput(audio_module_handle_t module,
61 audio_io_handle_t* output,
62 audio_config_t* /*config*/,
63 audio_devices_t* /*devices*/,
64 const String8& /*address*/,
65 uint32_t* /*latencyMs*/,
66 audio_output_flags_t /*flags*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080067 if (module >= mNextModuleHandle) {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080068 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
Mikhail Naganov04a86632017-12-15 18:01:42 -080069 __func__, module, mNextModuleHandle);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080070 return BAD_VALUE;
71 }
72 *output = mNextIoHandle++;
73 return NO_ERROR;
74 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080075
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080076 status_t openInput(audio_module_handle_t module,
77 audio_io_handle_t* input,
78 audio_config_t* /*config*/,
79 audio_devices_t* /*device*/,
80 const String8& /*address*/,
81 audio_source_t /*source*/,
82 audio_input_flags_t /*flags*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080083 if (module >= mNextModuleHandle) {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080084 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
Mikhail Naganov04a86632017-12-15 18:01:42 -080085 __func__, module, mNextModuleHandle);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080086 return BAD_VALUE;
87 }
88 *input = mNextIoHandle++;
89 return NO_ERROR;
90 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080091
92 status_t createAudioPatch(const struct audio_patch* /*patch*/,
93 audio_patch_handle_t* handle,
94 int /*delayMs*/) override {
95 *handle = mNextPatchHandle++;
96 mActivePatches.insert(*handle);
97 return NO_ERROR;
98 }
99
100 status_t releaseAudioPatch(audio_patch_handle_t handle,
101 int /*delayMs*/) override {
102 if (mActivePatches.erase(handle) != 1) {
103 if (handle >= mNextPatchHandle) {
104 ALOGE("%s: Patch handle %d has not been allocated yet (next is %d)",
105 __func__, handle, mNextPatchHandle);
106 } else {
107 ALOGE("%s: Attempt to release patch %d twice", __func__, handle);
108 }
109 return BAD_VALUE;
110 }
111 return NO_ERROR;
112 }
113
114 // Helper methods for tests
115 size_t getActivePatchesCount() const { return mActivePatches.size(); }
116
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800117 private:
Mikhail Naganov04a86632017-12-15 18:01:42 -0800118 audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800119 audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800120 audio_patch_handle_t mNextPatchHandle = AUDIO_PATCH_HANDLE_NONE + 1;
121 std::set<audio_patch_handle_t> mActivePatches;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800122};
123
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800124class PatchCountCheck {
125 public:
126 explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
127 : mClient{client},
128 mInitialCount{mClient->getActivePatchesCount()} {}
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800129 int deltaFromSnapshot() const {
130 size_t currentCount = mClient->getActivePatchesCount();
131 if (mInitialCount <= currentCount) {
132 return currentCount - mInitialCount;
133 } else {
134 return -(static_cast<int>(mInitialCount - currentCount));
135 }
136 }
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800137 private:
138 const AudioPolicyManagerTestClient *mClient;
139 const size_t mInitialCount;
140};
141
Mikhail Naganov04a86632017-12-15 18:01:42 -0800142class AudioPolicyManagerTest : public testing::Test {
143 protected:
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800144 void SetUp() override;
145 void TearDown() override;
146 virtual void SetUpConfig(AudioPolicyConfig *config) { (void)config; }
147
148 void dumpToLog();
149 void getOutputForAttr(
150 audio_port_handle_t *selectedDeviceId,
151 audio_format_t format,
152 int channelMask,
153 int sampleRate,
154 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
155 audio_port_handle_t *portId = nullptr);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800156 PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
Mikhail Naganov04a86632017-12-15 18:01:42 -0800157
158 std::unique_ptr<AudioPolicyManagerTestClient> mClient;
159 std::unique_ptr<AudioPolicyTestManager> mManager;
160};
161
162void AudioPolicyManagerTest::SetUp() {
163 mClient.reset(new AudioPolicyManagerTestClient);
164 mManager.reset(new AudioPolicyTestManager(mClient.get()));
165 mManager->getConfig().setDefault();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800166 SetUpConfig(&mManager->getConfig()); // Subclasses may want to customize the config.
Mikhail Naganov04a86632017-12-15 18:01:42 -0800167 ASSERT_EQ(NO_ERROR, mManager->initialize());
168 ASSERT_EQ(NO_ERROR, mManager->initCheck());
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800169}
Mikhail Naganov04a86632017-12-15 18:01:42 -0800170
171void AudioPolicyManagerTest::TearDown() {
172 mManager.reset();
173 mClient.reset();
174}
175
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800176void AudioPolicyManagerTest::dumpToLog() {
Mikhail Naganov21b43362018-06-04 10:37:09 -0700177 int pipefd[2];
178 ASSERT_NE(-1, pipe(pipefd));
179 pid_t cpid = fork();
180 ASSERT_NE(-1, cpid);
181 if (cpid == 0) {
182 // Child process reads from the pipe and logs.
183 close(pipefd[1]);
184 std::string line;
185 char buf;
186 while (read(pipefd[0], &buf, sizeof(buf)) > 0) {
187 if (buf != '\n') {
188 line += buf;
189 } else {
190 ALOGI("%s", line.c_str());
191 line = "";
192 }
193 }
194 if (!line.empty()) ALOGI("%s", line.c_str());
195 close(pipefd[0]);
196 _exit(EXIT_SUCCESS);
197 } else {
198 // Parent does the dump and checks the status code.
199 close(pipefd[0]);
200 ASSERT_EQ(NO_ERROR, mManager->dump(pipefd[1]));
201 close(pipefd[1]);
202 wait(NULL); // Wait for the child to exit.
203 }
204}
205
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800206void AudioPolicyManagerTest::getOutputForAttr(
207 audio_port_handle_t *selectedDeviceId,
208 audio_format_t format,
209 int channelMask,
210 int sampleRate,
211 audio_output_flags_t flags,
212 audio_port_handle_t *portId) {
213 audio_attributes_t attr = {};
214 audio_io_handle_t output = AUDIO_PORT_HANDLE_NONE;
215 audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
216 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
217 config.sample_rate = sampleRate;
218 config.channel_mask = channelMask;
219 config.format = format;
220 *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
221 audio_port_handle_t localPortId;
222 if (!portId) portId = &localPortId;
223 *portId = AUDIO_PORT_HANDLE_NONE;
224 ASSERT_EQ(OK, mManager->getOutputForAttr(
225 &attr, &output, AUDIO_SESSION_NONE, &stream, 0 /*uid*/, &config, &flags,
Kevin Rocard153f92d2018-12-18 18:33:28 -0800226 selectedDeviceId, portId, {}));
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800227 ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
228}
229
230
231TEST_F(AudioPolicyManagerTest, InitSuccess) {
232 // SetUp must finish with no assertions.
233}
234
235TEST_F(AudioPolicyManagerTest, Dump) {
236 dumpToLog();
237}
238
Mikhail Naganov04a86632017-12-15 18:01:42 -0800239TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
240 audio_patch patch{};
241 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800242 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganov04a86632017-12-15 18:01:42 -0800243 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
244 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
245 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
246 patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
247 patch.num_sinks = 1;
248 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
249 patch.num_sources = 1;
250 patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
251 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
252 patch.num_sources = 2;
253 patch.num_sinks = 1;
254 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
255 patch = {};
256 patch.num_sources = 1;
257 patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
258 patch.num_sinks = 1;
259 patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
260 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
261 patch = {};
262 patch.num_sources = 1;
263 patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
264 patch.num_sinks = 1;
265 patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
266 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
267 // Verify that the handle is left unchanged.
268 ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800269 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800270}
271
272TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
Mikhail Naganov04a86632017-12-15 18:01:42 -0800273 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
274 uid_t uid = 42;
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800275 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdc769682018-05-04 15:34:08 -0700276 ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
277 PatchBuilder patchBuilder;
278 patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
279 addSink(mManager->getConfig().getDefaultOutputDevice());
280 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800281 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800282 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganov04a86632017-12-15 18:01:42 -0800283}
284
285// TODO: Add patch creation tests that involve already existing patch
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800286
287class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest {
288 protected:
289 void SetUpConfig(AudioPolicyConfig *config) override;
290 void TearDown() override;
291
292 sp<DeviceDescriptor> mMsdOutputDevice;
293 sp<DeviceDescriptor> mMsdInputDevice;
294};
295
296void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) {
297 // TODO: Consider using Serializer to load part of the config from a string.
298 mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
299 sp<AudioProfile> pcmOutputProfile = new AudioProfile(
300 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
301 sp<AudioProfile> ac3OutputProfile = new AudioProfile(
302 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000);
303 mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
304 mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
305 mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
306 // Match output profile from AudioPolicyConfig::setDefault.
307 sp<AudioProfile> pcmInputProfile = new AudioProfile(
308 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
309 mMsdInputDevice->addAudioProfile(pcmInputProfile);
310 config->addAvailableDevice(mMsdOutputDevice);
311 config->addAvailableDevice(mMsdInputDevice);
312
313 sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
314 HwModuleCollection modules = config->getHwModules();
315 modules.add(msdModule);
316 config->setHwModules(modules);
317 mMsdOutputDevice->attach(msdModule);
318 mMsdInputDevice->attach(msdModule);
319
jiabineaf09f02019-08-19 15:08:30 -0700320 sp<OutputProfile> msdOutputProfile = new OutputProfile("msd input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800321 msdOutputProfile->addAudioProfile(pcmOutputProfile);
322 msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
323 msdModule->addOutputProfile(msdOutputProfile);
jiabineaf09f02019-08-19 15:08:30 -0700324 sp<OutputProfile> msdCompressedOutputProfile = new OutputProfile("msd compressed input");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800325 msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
326 msdCompressedOutputProfile->setFlags(
327 AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
328 AUDIO_OUTPUT_FLAG_NON_BLOCKING);
329 msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
330 msdModule->addOutputProfile(msdCompressedOutputProfile);
331
jiabineaf09f02019-08-19 15:08:30 -0700332 sp<InputProfile> msdInputProfile = new InputProfile("msd output");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800333 msdInputProfile->addAudioProfile(pcmInputProfile);
334 msdInputProfile->addSupportedDevice(mMsdInputDevice);
335 msdModule->addInputProfile(msdInputProfile);
336
337 // Add a profile with another encoding to the default device to test routing
338 // of streams that are not supported by MSD.
339 sp<AudioProfile> dtsOutputProfile = new AudioProfile(
340 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000);
341 config->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
jiabineaf09f02019-08-19 15:08:30 -0700342 sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile("encoded");
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800343 primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
344 primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
345 primaryEncodedOutputProfile->addSupportedDevice(config->getDefaultOutputDevice());
346 config->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
347 addOutputProfile(primaryEncodedOutputProfile);
348}
349
350void AudioPolicyManagerTestMsd::TearDown() {
351 mMsdOutputDevice.clear();
352 mMsdInputDevice.clear();
353 AudioPolicyManagerTest::TearDown();
354}
355
356TEST_F(AudioPolicyManagerTestMsd, InitSuccess) {
357 ASSERT_TRUE(mMsdOutputDevice);
358 ASSERT_TRUE(mMsdInputDevice);
359}
360
361TEST_F(AudioPolicyManagerTestMsd, Dump) {
362 dumpToLog();
363}
364
365TEST_F(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800366 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800367 mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
368 AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800369 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800370}
371
372TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800373 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800374 audio_port_handle_t selectedDeviceId;
375 getOutputForAttr(&selectedDeviceId,
376 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
377 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800378 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800379}
380
381TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800382 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800383 audio_port_handle_t selectedDeviceId;
384 getOutputForAttr(&selectedDeviceId,
385 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
386 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800387 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800388}
389
390TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800391 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800392 audio_port_handle_t selectedDeviceId;
393 getOutputForAttr(&selectedDeviceId,
394 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
395 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800396 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800397 getOutputForAttr(&selectedDeviceId,
398 AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
399 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800400 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800401}
402
403TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800404 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800405 audio_port_handle_t selectedDeviceId;
406 getOutputForAttr(&selectedDeviceId,
407 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
408 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800409 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800410}
411
412TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
413 // Switch between formats that are supported and not supported by MSD.
414 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800415 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800416 audio_port_handle_t selectedDeviceId, portId;
417 getOutputForAttr(&selectedDeviceId,
418 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
419 &portId);
420 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800421 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800422 mManager->releaseOutput(portId);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800423 ASSERT_EQ(1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800424 }
425 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800426 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800427 audio_port_handle_t selectedDeviceId, portId;
428 getOutputForAttr(&selectedDeviceId,
429 AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
430 &portId);
431 ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800432 ASSERT_EQ(-1, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800433 mManager->releaseOutput(portId);
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800434 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800435 }
436 {
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800437 const PatchCountCheck patchCount = snapshotPatchCount();
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800438 audio_port_handle_t selectedDeviceId;
439 getOutputForAttr(&selectedDeviceId,
440 AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
441 ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
Mikhail Naganovd53525f2019-01-24 13:15:46 -0800442 ASSERT_EQ(0, patchCount.deltaFromSnapshot());
Mikhail Naganovdf2e3592018-12-19 14:27:42 -0800443 }
444}