blob: 242be3ff392597ce08dd999318cb2354a8f6cbb0 [file] [log] [blame]
Sham Rathod94aae5e2022-11-23 12:22:32 +05301/*
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
17#include <aidl/Vintf.h>
18
19#define LOG_TAG "VtsHalVisualizerTest"
20
21#include <Utils.h>
Shunkai Yaoe39cd362022-12-22 00:23:34 +000022#include <android/binder_enums.h>
23#include <unordered_set>
24
Sham Rathod94aae5e2022-11-23 12:22:32 +053025#include "EffectHelper.h"
26
27using namespace android;
28
29using aidl::android::hardware::audio::effect::Capability;
30using aidl::android::hardware::audio::effect::Descriptor;
31using aidl::android::hardware::audio::effect::IEffect;
32using aidl::android::hardware::audio::effect::IFactory;
33using aidl::android::hardware::audio::effect::kVisualizerTypeUUID;
34using aidl::android::hardware::audio::effect::Parameter;
35using aidl::android::hardware::audio::effect::Visualizer;
36
37/**
38 * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
39 * VtsAudioEffectTargetTest.
40 */
41enum ParamName {
42 PARAM_INSTANCE_NAME,
43 PARAM_CAPTURE_SIZE,
44 PARAM_SCALING_MODE,
45 PARAM_MEASUREMENT_MODE,
46 PARAM_LATENCY,
47};
48using VisualizerParamTestParam =
49 std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, Visualizer::ScalingMode,
50 Visualizer::MeasurementMode, int>;
51
Sham Rathod94aae5e2022-11-23 12:22:32 +053052class VisualizerParamTest : public ::testing::TestWithParam<VisualizerParamTestParam>,
53 public EffectHelper {
54 public:
55 VisualizerParamTest()
56 : mCaptureSize(std::get<PARAM_CAPTURE_SIZE>(GetParam())),
57 mScalingMode(std::get<PARAM_SCALING_MODE>(GetParam())),
58 mMeasurementMode(std::get<PARAM_MEASUREMENT_MODE>(GetParam())),
59 mLatency(std::get<PARAM_LATENCY>(GetParam())) {
60 std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
61 }
62
63 void SetUp() override {
64 ASSERT_NE(nullptr, mFactory);
65 ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
66
67 Parameter::Specific specific = getDefaultParamSpecific();
68 Parameter::Common common = EffectHelper::createParamCommon(
69 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
70 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
71 IEffect::OpenEffectReturn ret;
72 ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
73 ASSERT_NE(nullptr, mEffect);
74 }
75
76 void TearDown() override {
77 ASSERT_NO_FATAL_FAILURE(close(mEffect));
78 ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
79 }
Sham Rathod94aae5e2022-11-23 12:22:32 +053080 Parameter::Specific getDefaultParamSpecific() {
Shunkai Yaoe39cd362022-12-22 00:23:34 +000081 Visualizer vs = Visualizer::make<Visualizer::captureSamples>(
82 mDescriptor.capability.get<Capability::visualizer>().captureSampleRange.max);
Sham Rathod94aae5e2022-11-23 12:22:32 +053083 Parameter::Specific specific =
84 Parameter::Specific::make<Parameter::Specific::visualizer>(vs);
85 return specific;
86 }
87
88 static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
89 std::shared_ptr<IFactory> mFactory;
90 std::shared_ptr<IEffect> mEffect;
91 Descriptor mDescriptor;
Shunkai Yaoe39cd362022-12-22 00:23:34 +000092 int mCaptureSize;
Sham Rathod94aae5e2022-11-23 12:22:32 +053093 Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
94 Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
95 int mLatency = 0;
96
97 void SetAndGetCommonParameters() {
98 for (auto& it : mCommonTags) {
99 auto& tag = it.first;
100 auto& vs = it.second;
101
102 // validate parameter
103 Descriptor desc;
104 ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
105 const bool valid = isTagInRange(tag, vs, desc);
106 const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
107
108 // set parameter
109 Parameter expectParam;
110 Parameter::Specific specific;
111 specific.set<Parameter::Specific::visualizer>(vs);
112 expectParam.set<Parameter::specific>(specific);
113 EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
114
115 // only get if parameter in range and set success
116 if (expected == EX_NONE) {
117 Parameter getParam;
118 Parameter::Id id;
119 Visualizer::Id vsId;
120 vsId.set<Visualizer::Id::commonTag>(tag);
121 id.set<Parameter::Id::visualizerTag>(vsId);
122 EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
123
124 EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
125 << "\ngetParam:" << getParam.toString();
126 }
127 }
128 }
129
130 void SetAndGetSetOnlyParameters() {
131 for (auto& it : mSetOnlyParamTags) {
132 auto& tag = it.first;
133 auto& vs = it.second;
134
135 // validate parameter
136 Descriptor desc;
137 ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
Shunkai Yao883d75b2022-12-24 05:15:15 +0000138 const bool valid = isSetOnlyParamTagInRange(vs, desc);
Sham Rathod94aae5e2022-11-23 12:22:32 +0530139 const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
140
141 // set parameter
142 Parameter expectParam;
143 Parameter::Specific specific;
144 specific.set<Parameter::Specific::visualizer>(vs);
145 expectParam.set<Parameter::specific>(specific);
146 ASSERT_STATUS(expected, mEffect->setParameter(expectParam));
147
148 // parameter defined in this setOnlyParameter union must be settable via
149 // setParameter(), but must not be gettable
150 Parameter getParam;
151 Parameter::Id id;
152 Visualizer::Id vsId;
153 vsId.set<Visualizer::Id::setOnlyParamTag>(tag);
154 id.set<Parameter::Id::visualizerTag>(vsId);
155 EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->getParameter(id, &getParam));
156 }
157 }
158
159 void GetandSetGetOnlyParameters() {
160 for (auto& tag : mGetOnlyParamTags) {
161 // get parameter
162 Parameter getParam;
163 Parameter::Id id;
164 Visualizer::Id vsId;
165 vsId.set<Visualizer::Id::getOnlyParamTag>(tag);
166 id.set<Parameter::Id::visualizerTag>(vsId);
167 ASSERT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
168
169 // parameter defined in this getOnlyParameter union must be gettable via
170 // getParameter(), but must not be settable
171 // set parameter
172 ASSERT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->setParameter(getParam));
173 }
174 }
175
176 void addCaptureSizeParam(int captureSize) {
177 Visualizer vs;
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000178 vs.set<Visualizer::captureSamples>(captureSize);
179 mCommonTags.push_back({Visualizer::captureSamples, vs});
Sham Rathod94aae5e2022-11-23 12:22:32 +0530180 }
181
182 void addScalingModeParam(Visualizer::ScalingMode scalingMode) {
183 Visualizer vs;
184 vs.set<Visualizer::scalingMode>(scalingMode);
185 mCommonTags.push_back({Visualizer::scalingMode, vs});
186 }
187
188 void addMeasurementModeParam(Visualizer::MeasurementMode measurementMode) {
189 Visualizer vs;
190 vs.set<Visualizer::measurementMode>(measurementMode);
191 mCommonTags.push_back({Visualizer::measurementMode, vs});
192 }
193
194 void addLatencyParam(int latency) {
195 Visualizer vs;
196 Visualizer::SetOnlyParameters setOnlyParam;
197 setOnlyParam.set<Visualizer::SetOnlyParameters::latencyMs>(latency);
198 vs.set<Visualizer::setOnlyParameters>(setOnlyParam);
199 mSetOnlyParamTags.push_back({Visualizer::SetOnlyParameters::latencyMs, vs});
200 }
201
202 void addMeasurementTag() {
203 mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::measurement);
204 }
205
206 void addCaptureBytesTag() {
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000207 mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::captureSampleBuffer);
Sham Rathod94aae5e2022-11-23 12:22:32 +0530208 }
209
210 bool isTagInRange(const Visualizer::Tag& tag, const Visualizer& vs,
211 const Descriptor& desc) const {
212 const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
213 switch (tag) {
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000214 case Visualizer::captureSamples: {
215 int captureSize = vs.get<Visualizer::captureSamples>();
Shunkai Yao883d75b2022-12-24 05:15:15 +0000216 return captureSize >= vsCap.captureSampleRange.min &&
217 captureSize <= vsCap.captureSampleRange.max;
Sham Rathod94aae5e2022-11-23 12:22:32 +0530218 }
219 case Visualizer::scalingMode:
220 case Visualizer::measurementMode:
221 return true;
Shunkai Yao883d75b2022-12-24 05:15:15 +0000222 case Visualizer::setOnlyParameters: {
223 auto setOnly = vs.get<Visualizer::setOnlyParameters>();
224 if (setOnly.getTag() != Visualizer::SetOnlyParameters::latencyMs) {
225 return false;
226 }
227 auto latencyMs = setOnly.get<Visualizer::SetOnlyParameters::latencyMs>();
228 return latencyMs >= 0 && latencyMs <= vsCap.maxLatencyMs;
229 }
Sham Rathod94aae5e2022-11-23 12:22:32 +0530230 default:
231 return false;
232 }
233 }
234
Shunkai Yao883d75b2022-12-24 05:15:15 +0000235 bool isSetOnlyParamTagInRange(const Visualizer& vs, const Descriptor& desc) const {
Sham Rathod94aae5e2022-11-23 12:22:32 +0530236 const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
237 if (vs.getTag() != Visualizer::setOnlyParameters) return false;
238 Visualizer::SetOnlyParameters setOnlyParam = vs.get<Visualizer::setOnlyParameters>();
239 if (setOnlyParam.getTag() != Visualizer::SetOnlyParameters::latencyMs) return false;
240 int latency = setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>();
241 return isLatencyInRange(vsCap, latency);
242 }
243
Sham Rathod94aae5e2022-11-23 12:22:32 +0530244 bool isLatencyInRange(const Visualizer::Capability& cap, int latency) const {
245 return (latency >= 0 && latency <= cap.maxLatencyMs);
246 }
247
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000248 static std::unordered_set<int> getCaptureSizeValues() {
Shunkai Yao883d75b2022-12-24 05:15:15 +0000249 auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
250 kVisualizerTypeUUID);
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000251 int minCaptureSize = std::numeric_limits<int>::max();
252 int maxCaptureSize = std::numeric_limits<int>::min();
Shunkai Yao883d75b2022-12-24 05:15:15 +0000253 for (const auto& it : descList) {
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000254 maxCaptureSize = std::max(
255 it.second.capability.get<Capability::visualizer>().captureSampleRange.max,
256 maxCaptureSize);
257 minCaptureSize = std::min(
258 it.second.capability.get<Capability ::visualizer>().captureSampleRange.min,
259 minCaptureSize);
260 }
261 return {std::numeric_limits<int>::min(), minCaptureSize - 1, minCaptureSize,
262 (minCaptureSize + maxCaptureSize) >> 1, maxCaptureSize, maxCaptureSize + 1,
263 std::numeric_limits<int>::max()};
264 }
265
266 static std::unordered_set<int> getLatencyValues() {
Shunkai Yao883d75b2022-12-24 05:15:15 +0000267 auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
268 kVisualizerTypeUUID);
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000269 const auto max = std::max_element(
Shunkai Yao883d75b2022-12-24 05:15:15 +0000270 descList.begin(), descList.end(),
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000271 [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
272 const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
273 return a.second.capability.get<Capability::visualizer>().maxLatencyMs <
274 b.second.capability.get<Capability::visualizer>().maxLatencyMs;
275 });
Shunkai Yao883d75b2022-12-24 05:15:15 +0000276 if (max == descList.end()) {
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000277 return {0};
278 }
279 int maxDelay = max->second.capability.get<Capability::visualizer>().maxLatencyMs;
280 return {-1, 0, maxDelay >> 1, maxDelay - 1, maxDelay, maxDelay + 1};
281 }
Shunkai Yao883d75b2022-12-24 05:15:15 +0000282 static std::unordered_set<Visualizer::MeasurementMode> getMeasurementModeValues() {
283 return {ndk::enum_range<Visualizer::MeasurementMode>().begin(),
284 ndk::enum_range<Visualizer::MeasurementMode>().end()};
285 }
286 static std::unordered_set<Visualizer::ScalingMode> getScalingModeValues() {
287 return {ndk::enum_range<Visualizer::ScalingMode>().begin(),
288 ndk::enum_range<Visualizer::ScalingMode>().end()};
289 }
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000290
Sham Rathod94aae5e2022-11-23 12:22:32 +0530291 private:
292 std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
293 std::vector<std::pair<Visualizer::SetOnlyParameters::Tag, Visualizer>> mSetOnlyParamTags;
294 std::vector<Visualizer::GetOnlyParameters::Tag> mGetOnlyParamTags;
295 void CleanUp() {
296 mCommonTags.clear();
297 mSetOnlyParamTags.clear();
298 mGetOnlyParamTags.clear();
299 }
300};
301
302TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
303 EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
304 SetAndGetCommonParameters();
305}
306
307TEST_P(VisualizerParamTest, SetAndGetScalingMode) {
308 EXPECT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
309 SetAndGetCommonParameters();
310}
311
312TEST_P(VisualizerParamTest, SetAndGetMeasurementMode) {
313 EXPECT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
314 SetAndGetCommonParameters();
315}
316
317TEST_P(VisualizerParamTest, SetAndGetLatency) {
318 EXPECT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
319 SetAndGetSetOnlyParameters();
320}
321
322TEST_P(VisualizerParamTest, GetAndSetMeasurement) {
323 EXPECT_NO_FATAL_FAILURE(addMeasurementTag());
324 GetandSetGetOnlyParameters();
325}
326
327TEST_P(VisualizerParamTest, GetAndSetCaptureBytes) {
328 EXPECT_NO_FATAL_FAILURE(addCaptureBytesTag());
329 GetandSetGetOnlyParameters();
330}
331
332INSTANTIATE_TEST_SUITE_P(
Shunkai Yaoe39cd362022-12-22 00:23:34 +0000333 VisualizerParamTest, VisualizerParamTest,
Sham Rathod94aae5e2022-11-23 12:22:32 +0530334 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
335 IFactory::descriptor, kVisualizerTypeUUID)),
Shunkai Yao883d75b2022-12-24 05:15:15 +0000336 testing::ValuesIn(VisualizerParamTest::getCaptureSizeValues()),
337 testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
338 testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
339 testing::ValuesIn(VisualizerParamTest::getLatencyValues())),
Sham Rathod94aae5e2022-11-23 12:22:32 +0530340 [](const testing::TestParamInfo<VisualizerParamTest::ParamType>& info) {
341 auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
342 std::string captureSize = std::to_string(std::get<PARAM_CAPTURE_SIZE>(info.param));
Shunkai Yao883d75b2022-12-24 05:15:15 +0000343 std::string scalingMode = aidl::android::hardware::audio::effect::toString(
344 std::get<PARAM_SCALING_MODE>(info.param));
345 std::string measurementMode = aidl::android::hardware::audio::effect::toString(
346 std::get<PARAM_MEASUREMENT_MODE>(info.param));
Sham Rathod94aae5e2022-11-23 12:22:32 +0530347 std::string latency = std::to_string(std::get<PARAM_LATENCY>(info.param));
348
349 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
350 descriptor.common.name + "_UUID_" +
351 descriptor.common.id.uuid.toString() + "_captureSize" + captureSize +
352 "_scalingMode" + scalingMode + "_measurementMode" + measurementMode +
353 "_latency" + latency;
354 std::replace_if(
355 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
356 return name;
357 });
358
359GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VisualizerParamTest);
360
361int main(int argc, char** argv) {
362 ::testing::InitGoogleTest(&argc, argv);
363 ABinderProcess_setThreadPoolMaxThreadCount(1);
364 ABinderProcess_startThreadPool();
365 return RUN_ALL_TESTS();
366}