blob: 9b100b1959256d11f5ef993647909505eaf5ca79 [file] [log] [blame]
Shunkai Yao67b1be62022-07-13 05:01:42 +00001/*
2 * Copyright (C) 2022 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
Shunkai Yao45905172022-08-24 18:14:02 +000017#include <memory>
Shunkai Yao67b1be62022-07-13 05:01:42 +000018#include <string>
Shunkai Yao45905172022-08-24 18:14:02 +000019#include <unordered_map>
20#include <unordered_set>
21#include <vector>
Shunkai Yao67b1be62022-07-13 05:01:42 +000022
23#define LOG_TAG "VtsHalAudioEffect"
24
25#include <aidl/Gtest.h>
26#include <aidl/Vintf.h>
27#include <android-base/logging.h>
28#include <android-base/properties.h>
29#include <android/binder_interface_utils.h>
30#include <android/binder_manager.h>
31#include <android/binder_process.h>
32
33#include <aidl/android/hardware/audio/effect/IFactory.h>
34
35#include "AudioHalBinderServiceUtil.h"
36
37using namespace android;
38
39using ndk::ScopedAStatus;
40
41using aidl::android::hardware::audio::effect::Descriptor;
Shunkai Yao45905172022-08-24 18:14:02 +000042using aidl::android::hardware::audio::effect::IEffect;
Shunkai Yao67b1be62022-07-13 05:01:42 +000043using aidl::android::hardware::audio::effect::IFactory;
44using aidl::android::media::audio::common::AudioUuid;
45
Shunkai Yao45905172022-08-24 18:14:02 +000046class EffectFactoryHelper {
Shunkai Yao67b1be62022-07-13 05:01:42 +000047 public:
Shunkai Yao45905172022-08-24 18:14:02 +000048 EffectFactoryHelper(const std::string& name) : mServiceName(name) {}
Shunkai Yao67b1be62022-07-13 05:01:42 +000049
Shunkai Yao45905172022-08-24 18:14:02 +000050 void ConnectToFactoryService() {
51 mEffectFactory = IFactory::fromBinder(binderUtil.connectToService(mServiceName));
52 ASSERT_NE(mEffectFactory, nullptr);
Shunkai Yao67b1be62022-07-13 05:01:42 +000053 }
54
Shunkai Yao45905172022-08-24 18:14:02 +000055 void RestartFactoryService() {
56 ASSERT_NE(mEffectFactory, nullptr);
57 mEffectFactory = IFactory::fromBinder(binderUtil.restartService());
58 ASSERT_NE(mEffectFactory, nullptr);
Shunkai Yao67b1be62022-07-13 05:01:42 +000059 }
60
Shunkai Yao45905172022-08-24 18:14:02 +000061 void QueryAllEffects() {
62 EXPECT_NE(mEffectFactory, nullptr);
63 ScopedAStatus status =
64 mEffectFactory->queryEffects(std::nullopt, std::nullopt, &mCompleteIds);
65 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
66 }
67
68 void QueryEffects(const std::optional<AudioUuid>& in_type,
69 const std::optional<AudioUuid>& in_instance,
70 std::vector<Descriptor::Identity>* _aidl_return) {
71 EXPECT_NE(mEffectFactory, nullptr);
72 ScopedAStatus status = mEffectFactory->queryEffects(in_type, in_instance, _aidl_return);
73 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
74 mIds = *_aidl_return;
75 }
76
77 void CreateEffects() {
78 EXPECT_NE(mEffectFactory, nullptr);
79 ScopedAStatus status;
80 for (const auto& id : mIds) {
81 std::shared_ptr<IEffect> effect;
82 status = mEffectFactory->createEffect(id.uuid, &effect);
83 EXPECT_EQ(status.getExceptionCode(), EX_NONE) << id.toString();
84 EXPECT_NE(effect, nullptr) << id.toString();
85 mEffectIdMap[effect] = id;
86 }
87 }
88
89 void DestroyEffects() {
90 EXPECT_NE(mEffectFactory, nullptr);
91 ScopedAStatus status;
92 for (const auto& it : mEffectIdMap) {
93 status = mEffectFactory->destroyEffect(it.first);
94 EXPECT_EQ(status.getExceptionCode(), EX_NONE) << it.second.toString();
95 }
96 mEffectIdMap.clear();
97 }
98
99 std::shared_ptr<IFactory> GetFactory() { return mEffectFactory; }
100 const std::vector<Descriptor::Identity>& GetEffectIds() { return mIds; }
101 const std::vector<Descriptor::Identity>& GetCompleteEffectIdList() { return mCompleteIds; }
102 const std::unordered_map<std::shared_ptr<IEffect>, Descriptor::Identity>& GetEffectMap() {
103 return mEffectIdMap;
104 }
105
106 private:
107 std::shared_ptr<IFactory> mEffectFactory;
108 std::string mServiceName;
Shunkai Yao67b1be62022-07-13 05:01:42 +0000109 AudioHalBinderServiceUtil binderUtil;
Shunkai Yao45905172022-08-24 18:14:02 +0000110 std::vector<Descriptor::Identity> mIds;
111 std::vector<Descriptor::Identity> mCompleteIds;
112 std::unordered_map<std::shared_ptr<IEffect>, Descriptor::Identity> mEffectIdMap;
113};
114
115/// Effect factory testing.
116class EffectFactoryTest : public testing::TestWithParam<std::string> {
117 public:
118 void SetUp() override { ASSERT_NO_FATAL_FAILURE(mFactory.ConnectToFactoryService()); }
119
120 void TearDown() override { mFactory.DestroyEffects(); }
121
122 EffectFactoryHelper mFactory = EffectFactoryHelper(GetParam());
123
Shunkai Yao67b1be62022-07-13 05:01:42 +0000124 // TODO: these UUID can get from config file
125 // ec7178ec-e5e1-4432-a3f4-4657e6795210
126 const AudioUuid nullUuid = {static_cast<int32_t>(0xec7178ec),
127 0xe5e1,
128 0x4432,
129 0xa3f4,
130 {0x46, 0x57, 0xe6, 0x79, 0x52, 0x10}};
131 const AudioUuid zeroUuid = {
132 static_cast<int32_t>(0x0), 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
133};
134
Shunkai Yao45905172022-08-24 18:14:02 +0000135TEST_P(EffectFactoryTest, SetupAndTearDown) {
Shunkai Yao67b1be62022-07-13 05:01:42 +0000136 // Intentionally empty test body.
137}
138
Shunkai Yao45905172022-08-24 18:14:02 +0000139TEST_P(EffectFactoryTest, CanBeRestarted) {
140 ASSERT_NO_FATAL_FAILURE(mFactory.RestartFactoryService());
Shunkai Yao67b1be62022-07-13 05:01:42 +0000141}
142
Shunkai Yao45905172022-08-24 18:14:02 +0000143TEST_P(EffectFactoryTest, QueriedDescriptorList) {
Shunkai Yao67b1be62022-07-13 05:01:42 +0000144 std::vector<Descriptor::Identity> descriptors;
Shunkai Yao45905172022-08-24 18:14:02 +0000145 mFactory.QueryEffects(std::nullopt, std::nullopt, &descriptors);
Shunkai Yao67b1be62022-07-13 05:01:42 +0000146 EXPECT_NE(static_cast<int>(descriptors.size()), 0);
147}
148
Shunkai Yao45905172022-08-24 18:14:02 +0000149TEST_P(EffectFactoryTest, DescriptorUUIDNotNull) {
Shunkai Yao67b1be62022-07-13 05:01:42 +0000150 std::vector<Descriptor::Identity> descriptors;
Shunkai Yao45905172022-08-24 18:14:02 +0000151 mFactory.QueryEffects(std::nullopt, std::nullopt, &descriptors);
Shunkai Yao67b1be62022-07-13 05:01:42 +0000152 // TODO: Factory eventually need to return the full list of MUST supported AOSP effects.
153 for (auto& desc : descriptors) {
154 EXPECT_NE(desc.type, zeroUuid);
155 EXPECT_NE(desc.uuid, zeroUuid);
156 }
157}
158
Shunkai Yao45905172022-08-24 18:14:02 +0000159TEST_P(EffectFactoryTest, QueriedDescriptorNotExistType) {
Shunkai Yao67b1be62022-07-13 05:01:42 +0000160 std::vector<Descriptor::Identity> descriptors;
Shunkai Yao45905172022-08-24 18:14:02 +0000161 mFactory.QueryEffects(nullUuid, std::nullopt, &descriptors);
Shunkai Yao67b1be62022-07-13 05:01:42 +0000162 EXPECT_EQ(static_cast<int>(descriptors.size()), 0);
163}
164
Shunkai Yao45905172022-08-24 18:14:02 +0000165TEST_P(EffectFactoryTest, QueriedDescriptorNotExistInstance) {
Shunkai Yao67b1be62022-07-13 05:01:42 +0000166 std::vector<Descriptor::Identity> descriptors;
Shunkai Yao45905172022-08-24 18:14:02 +0000167 mFactory.QueryEffects(std::nullopt, nullUuid, &descriptors);
Shunkai Yao67b1be62022-07-13 05:01:42 +0000168 EXPECT_EQ(static_cast<int>(descriptors.size()), 0);
169}
170
Shunkai Yao45905172022-08-24 18:14:02 +0000171TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
172 std::vector<Descriptor::Identity> descriptors;
173 mFactory.QueryEffects(std::nullopt, std::nullopt, &descriptors);
174 int numIds = static_cast<int>(mFactory.GetEffectIds().size());
175 EXPECT_NE(numIds, 0);
176
177 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 0);
178 mFactory.CreateEffects();
179 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), numIds);
180 mFactory.DestroyEffects();
181 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 0);
182
183 // Create and destroy again
184 mFactory.CreateEffects();
185 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), numIds);
186 mFactory.DestroyEffects();
187 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 0);
188}
189
190TEST_P(EffectFactoryTest, CreateMultipleInstanceOfSameEffect) {
191 std::vector<Descriptor::Identity> descriptors;
192 mFactory.QueryEffects(std::nullopt, std::nullopt, &descriptors);
193 int numIds = static_cast<int>(mFactory.GetEffectIds().size());
194 EXPECT_NE(numIds, 0);
195
196 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 0);
197 mFactory.CreateEffects();
198 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), numIds);
199 // Create effect instances of same implementation
200 mFactory.CreateEffects();
201 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 2 * numIds);
202
203 mFactory.CreateEffects();
204 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 3 * numIds);
205
206 mFactory.DestroyEffects();
207 EXPECT_EQ(static_cast<int>(mFactory.GetEffectMap().size()), 0);
208}
209
210INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
Shunkai Yao67b1be62022-07-13 05:01:42 +0000211 testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
212 android::PrintInstanceNameToString);
Shunkai Yao45905172022-08-24 18:14:02 +0000213GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EffectFactoryTest);
214
215/// Effect testing.
216class AudioEffect : public testing::TestWithParam<std::string> {
217 public:
218 void SetUp() override {
219 ASSERT_NO_FATAL_FAILURE(mFactory.ConnectToFactoryService());
220 ASSERT_NO_FATAL_FAILURE(mFactory.CreateEffects());
221 }
222
223 void TearDown() override {
224 CloseEffects();
225 ASSERT_NO_FATAL_FAILURE(mFactory.DestroyEffects());
226 }
227
228 void OpenEffects() {
229 auto open = [](const std::shared_ptr<IEffect>& effect) {
230 ScopedAStatus status = effect->open();
231 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
232 };
233 EXPECT_NO_FATAL_FAILURE(ForEachEffect(open));
234 }
235
236 void CloseEffects() {
237 auto close = [](const std::shared_ptr<IEffect>& effect) {
238 ScopedAStatus status = effect->close();
239 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
240 };
241 EXPECT_NO_FATAL_FAILURE(ForEachEffect(close));
242 }
243
244 void GetEffectDescriptors() {
245 auto get = [](const std::shared_ptr<IEffect>& effect) {
246 Descriptor desc;
247 ScopedAStatus status = effect->getDescriptor(&desc);
248 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
249 };
250 EXPECT_NO_FATAL_FAILURE(ForEachEffect(get));
251 }
252
253 template <typename Functor>
254 void ForEachEffect(Functor functor) {
255 auto effectMap = mFactory.GetEffectMap();
256 ScopedAStatus status;
257 for (const auto& it : effectMap) {
258 SCOPED_TRACE(it.second.toString());
259 functor(it.first);
260 }
261 }
262
263 EffectFactoryHelper mFactory = EffectFactoryHelper(GetParam());
264};
265
266TEST_P(AudioEffect, OpenEffectTest) {
267 EXPECT_NO_FATAL_FAILURE(OpenEffects());
268}
269
270TEST_P(AudioEffect, OpenAndCloseEffect) {
271 EXPECT_NO_FATAL_FAILURE(OpenEffects());
272 EXPECT_NO_FATAL_FAILURE(CloseEffects());
273}
274
275TEST_P(AudioEffect, CloseUnopenedEffectTest) {
276 EXPECT_NO_FATAL_FAILURE(CloseEffects());
277}
278
279TEST_P(AudioEffect, DoubleOpenCloseEffects) {
280 EXPECT_NO_FATAL_FAILURE(OpenEffects());
281 EXPECT_NO_FATAL_FAILURE(CloseEffects());
282 EXPECT_NO_FATAL_FAILURE(OpenEffects());
283 EXPECT_NO_FATAL_FAILURE(CloseEffects());
284
285 EXPECT_NO_FATAL_FAILURE(OpenEffects());
286 EXPECT_NO_FATAL_FAILURE(OpenEffects());
287 EXPECT_NO_FATAL_FAILURE(CloseEffects());
288
289 EXPECT_NO_FATAL_FAILURE(OpenEffects());
290 EXPECT_NO_FATAL_FAILURE(CloseEffects());
291 EXPECT_NO_FATAL_FAILURE(CloseEffects());
292}
293
294TEST_P(AudioEffect, GetDescriptors) {
295 EXPECT_NO_FATAL_FAILURE(GetEffectDescriptors());
296}
297
298TEST_P(AudioEffect, DescriptorIdExistAndUnique) {
299 auto checker = [&](const std::shared_ptr<IEffect>& effect) {
300 Descriptor desc;
301 std::vector<Descriptor::Identity> idList;
302 ScopedAStatus status = effect->getDescriptor(&desc);
303 EXPECT_EQ(status.getExceptionCode(), EX_NONE);
304 mFactory.QueryEffects(desc.common.id.type, desc.common.id.uuid, &idList);
305 EXPECT_EQ(static_cast<int>(idList.size()), 1);
306 };
307 EXPECT_NO_FATAL_FAILURE(ForEachEffect(checker));
308
309 // Check unique with a set
310 auto stringHash = [](const Descriptor::Identity& id) {
311 return std::hash<std::string>()(id.toString());
312 };
313 auto vec = mFactory.GetCompleteEffectIdList();
314 std::unordered_set<Descriptor::Identity, decltype(stringHash)> idSet(0, stringHash);
315 for (auto it : vec) {
316 EXPECT_EQ(static_cast<int>(idSet.count(it)), 0);
317 idSet.insert(it);
318 }
319}
320
321INSTANTIATE_TEST_SUITE_P(AudioEffectTest, AudioEffect,
322 testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
323 android::PrintInstanceNameToString);
324GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioEffect);
Shunkai Yao67b1be62022-07-13 05:01:42 +0000325
326int main(int argc, char** argv) {
327 ::testing::InitGoogleTest(&argc, argv);
328 ABinderProcess_setThreadPoolMaxThreadCount(1);
329 ABinderProcess_startThreadPool();
330 return RUN_ALL_TESTS();
Shunkai Yao45905172022-08-24 18:14:02 +0000331}