blob: 2d9260edcdded1bfcdaa375a1d7b8b34ff6a6b37 [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>
19
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080020#include <gtest/gtest.h>
21
Mikhail Naganovdc769682018-05-04 15:34:08 -070022#include <media/PatchBuilder.h>
23
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080024#include "AudioPolicyTestClient.h"
25#include "AudioPolicyTestManager.h"
26
27using namespace android;
28
Mikhail Naganov04a86632017-12-15 18:01:42 -080029TEST(AudioPolicyManagerTestInit, Failure) {
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080030 AudioPolicyTestClient client;
31 AudioPolicyTestManager manager(&client);
32 manager.getConfig().setDefault();
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080033 // Since the default client fails to open anything,
34 // APM should indicate that the initialization didn't succeed.
Mikhail Naganovad3f8a12017-12-12 13:24:23 -080035 ASSERT_EQ(NO_INIT, manager.initialize());
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080036 ASSERT_EQ(NO_INIT, manager.initCheck());
37}
38
39
Mikhail Naganov04a86632017-12-15 18:01:42 -080040class AudioPolicyManagerTestClient : public AudioPolicyTestClient {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080041 public:
Mikhail Naganov04a86632017-12-15 18:01:42 -080042 // AudioPolicyClientInterface implementation
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080043 audio_module_handle_t loadHwModule(const char* /*name*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080044 return mNextModuleHandle++;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080045 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080046
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080047 status_t openOutput(audio_module_handle_t module,
48 audio_io_handle_t* output,
49 audio_config_t* /*config*/,
50 audio_devices_t* /*devices*/,
51 const String8& /*address*/,
52 uint32_t* /*latencyMs*/,
53 audio_output_flags_t /*flags*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080054 if (module >= mNextModuleHandle) {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080055 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
Mikhail Naganov04a86632017-12-15 18:01:42 -080056 __func__, module, mNextModuleHandle);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080057 return BAD_VALUE;
58 }
59 *output = mNextIoHandle++;
60 return NO_ERROR;
61 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080062
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080063 status_t openInput(audio_module_handle_t module,
64 audio_io_handle_t* input,
65 audio_config_t* /*config*/,
66 audio_devices_t* /*device*/,
67 const String8& /*address*/,
68 audio_source_t /*source*/,
69 audio_input_flags_t /*flags*/) override {
Mikhail Naganov04a86632017-12-15 18:01:42 -080070 if (module >= mNextModuleHandle) {
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080071 ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
Mikhail Naganov04a86632017-12-15 18:01:42 -080072 __func__, module, mNextModuleHandle);
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -080073 return BAD_VALUE;
74 }
75 *input = mNextIoHandle++;
76 return NO_ERROR;
77 }
Mikhail Naganov04a86632017-12-15 18:01:42 -080078
79 status_t createAudioPatch(const struct audio_patch* /*patch*/,
80 audio_patch_handle_t* handle,
81 int /*delayMs*/) override {
82 *handle = mNextPatchHandle++;
83 mActivePatches.insert(*handle);
84 return NO_ERROR;
85 }
86
87 status_t releaseAudioPatch(audio_patch_handle_t handle,
88 int /*delayMs*/) override {
89 if (mActivePatches.erase(handle) != 1) {
90 if (handle >= mNextPatchHandle) {
91 ALOGE("%s: Patch handle %d has not been allocated yet (next is %d)",
92 __func__, handle, mNextPatchHandle);
93 } else {
94 ALOGE("%s: Attempt to release patch %d twice", __func__, handle);
95 }
96 return BAD_VALUE;
97 }
98 return NO_ERROR;
99 }
100
101 // Helper methods for tests
102 size_t getActivePatchesCount() const { return mActivePatches.size(); }
103
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800104 private:
Mikhail Naganov04a86632017-12-15 18:01:42 -0800105 audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800106 audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
Mikhail Naganov04a86632017-12-15 18:01:42 -0800107 audio_patch_handle_t mNextPatchHandle = AUDIO_PATCH_HANDLE_NONE + 1;
108 std::set<audio_patch_handle_t> mActivePatches;
Mikhail Naganovbcbcb1b2017-12-13 13:03:35 -0800109};
110
Mikhail Naganov04a86632017-12-15 18:01:42 -0800111class AudioPolicyManagerTest : public testing::Test {
112 protected:
113 virtual void SetUp();
114 virtual void TearDown();
115
116 std::unique_ptr<AudioPolicyManagerTestClient> mClient;
117 std::unique_ptr<AudioPolicyTestManager> mManager;
118};
119
120void AudioPolicyManagerTest::SetUp() {
121 mClient.reset(new AudioPolicyManagerTestClient);
122 mManager.reset(new AudioPolicyTestManager(mClient.get()));
123 mManager->getConfig().setDefault();
124 ASSERT_EQ(NO_ERROR, mManager->initialize());
125 ASSERT_EQ(NO_ERROR, mManager->initCheck());
Mikhail Naganovad3f8a12017-12-12 13:24:23 -0800126}
Mikhail Naganov04a86632017-12-15 18:01:42 -0800127
128void AudioPolicyManagerTest::TearDown() {
129 mManager.reset();
130 mClient.reset();
131}
132
133TEST_F(AudioPolicyManagerTest, InitSuccess) {
134 // SetUp must finish with no assertions.
135}
136
137TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
138 audio_patch patch{};
139 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
140 const size_t patchCountBefore = mClient->getActivePatchesCount();
141 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
142 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
143 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
144 patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
145 patch.num_sinks = 1;
146 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
147 patch.num_sources = 1;
148 patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
149 ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
150 patch.num_sources = 2;
151 patch.num_sinks = 1;
152 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
153 patch = {};
154 patch.num_sources = 1;
155 patch.sources[0].role = AUDIO_PORT_ROLE_SINK;
156 patch.num_sinks = 1;
157 patch.sinks[0].role = AUDIO_PORT_ROLE_SINK;
158 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
159 patch = {};
160 patch.num_sources = 1;
161 patch.sources[0].role = AUDIO_PORT_ROLE_SOURCE;
162 patch.num_sinks = 1;
163 patch.sinks[0].role = AUDIO_PORT_ROLE_SOURCE;
164 ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
165 // Verify that the handle is left unchanged.
166 ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
167 ASSERT_EQ(patchCountBefore, mClient->getActivePatchesCount());
168}
169
170TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
Mikhail Naganov04a86632017-12-15 18:01:42 -0800171 audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
172 uid_t uid = 42;
173 const size_t patchCountBefore = mClient->getActivePatchesCount();
Mikhail Naganovdc769682018-05-04 15:34:08 -0700174 ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
175 PatchBuilder patchBuilder;
176 patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
177 addSink(mManager->getConfig().getDefaultOutputDevice());
178 ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
Mikhail Naganov04a86632017-12-15 18:01:42 -0800179 ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
180 ASSERT_EQ(patchCountBefore + 1, mClient->getActivePatchesCount());
181}
182
183// TODO: Add patch creation tests that involve already existing patch