1 /*
2 * Copyright (C) 2023 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 #define LOG_TAG "VtsHalSpatializerTest"
18 #include <android-base/logging.h>
19
20 #include "EffectHelper.h"
21
22 using namespace android;
23
24 using aidl::android::hardware::audio::effect::Descriptor;
25 using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
26 using aidl::android::hardware::audio::effect::IEffect;
27 using aidl::android::hardware::audio::effect::IFactory;
28 using aidl::android::hardware::audio::effect::Parameter;
29 using aidl::android::hardware::audio::effect::Range;
30 using aidl::android::hardware::audio::effect::Spatializer;
31 using aidl::android::media::audio::common::HeadTracking;
32 using aidl::android::media::audio::common::Spatialization;
33 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
34 using ::android::internal::ToString;
35
36 enum ParamName {
37 PARAM_INSTANCE_NAME,
38 PARAM_SPATIALIZATION_LEVEL,
39 PARAM_SPATIALIZATION_MODE,
40 PARAM_HEADTRACK_SENSORID,
41 PARAM_HEADTRACK_MODE,
42 PARAM_HEADTRACK_CONNECTION_MODE
43 };
44
45 using SpatializerParamTestParam =
46 std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Spatialization::Level,
47 Spatialization::Mode, int /* sensor ID */, HeadTracking::Mode,
48 HeadTracking::ConnectionMode>;
49
50 class SpatializerParamTest : public ::testing::TestWithParam<SpatializerParamTestParam>,
51 public EffectHelper {
52 public:
SpatializerParamTest()53 SpatializerParamTest()
54 : mSpatializerParams([&]() {
55 Spatialization::Level level = std::get<PARAM_SPATIALIZATION_LEVEL>(GetParam());
56 Spatialization::Mode mode = std::get<PARAM_SPATIALIZATION_MODE>(GetParam());
57 int sensorId = std::get<PARAM_HEADTRACK_SENSORID>(GetParam());
58 HeadTracking::Mode htMode = std::get<PARAM_HEADTRACK_MODE>(GetParam());
59 HeadTracking::ConnectionMode htConnectMode =
60 std::get<PARAM_HEADTRACK_CONNECTION_MODE>(GetParam());
61 std::map<Spatializer::Tag, Spatializer> params;
62 params[Spatializer::spatializationLevel] =
63 Spatializer::make<Spatializer::spatializationLevel>(level);
64 params[Spatializer::spatializationMode] =
65 Spatializer::make<Spatializer::spatializationMode>(mode);
66 params[Spatializer::headTrackingSensorId] =
67 Spatializer::make<Spatializer::headTrackingSensorId>(sensorId);
68 params[Spatializer::headTrackingMode] =
69 Spatializer::make<Spatializer::headTrackingMode>(htMode);
70 params[Spatializer::headTrackingConnectionMode] =
71 Spatializer::make<Spatializer::headTrackingConnectionMode>(htConnectMode);
72 return params;
73 }()) {
74 std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
75 }
76
SetUp()77 void SetUp() override {
78 ASSERT_NE(nullptr, mFactory);
79 ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
80
81 Parameter::Specific specific = getDefaultParamSpecific();
82 Parameter::Common common = createParamCommon(
83 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
84 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
85 IEffect::OpenEffectReturn ret;
86 ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
87 ASSERT_NE(nullptr, mEffect);
88 }
89
TearDown()90 void TearDown() override {
91 ASSERT_NO_FATAL_FAILURE(close(mEffect));
92 ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
93 }
94
getDefaultParamSpecific()95 Parameter::Specific getDefaultParamSpecific() {
96 Spatializer spatializer = Spatializer::make<Spatializer::headTrackingSensorId>(0);
97 Parameter::Specific specific =
98 Parameter::Specific::make<Parameter::Specific::spatializer>(spatializer);
99 return specific;
100 }
101
102 static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
103 std::shared_ptr<IFactory> mFactory;
104 std::shared_ptr<IEffect> mEffect;
105 Descriptor mDescriptor;
106 const std::map<Spatializer::Tag, Spatializer> mSpatializerParams;
107 };
108
TEST_P(SpatializerParamTest,SetAndGetParam)109 TEST_P(SpatializerParamTest, SetAndGetParam) {
110 for (const auto& it : mSpatializerParams) {
111 auto& tag = it.first;
112 auto& spatializer = it.second;
113
114 // validate parameter
115 Descriptor desc;
116 ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
117 const bool valid = isParameterValid<Spatializer, Range::spatializer>(it.second, desc);
118 const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
119
120 // set parameter
121 Parameter expectParam;
122 Parameter::Specific specific;
123 specific.set<Parameter::Specific::spatializer>(spatializer);
124 expectParam.set<Parameter::specific>(specific);
125 EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
126
127 // only get if parameter in range and set success
128 if (expected == EX_NONE) {
129 Parameter getParam;
130 Parameter::Id id;
131 Spatializer::Id spatializerId;
132 spatializerId.set<Spatializer::Id::commonTag>(tag);
133 id.set<Parameter::Id::spatializerTag>(spatializerId);
134 // if set success, then get should match
135 EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
136 EXPECT_EQ(expectParam, getParam);
137 }
138 }
139 }
140
141 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
142 INSTANTIATE_TEST_SUITE_P(
143 SpatializerTest, SpatializerParamTest,
144 ::testing::Combine(
145 testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
146 IFactory::descriptor, getEffectTypeUuidSpatializer())),
147 testing::ValuesIn(EffectHelper::getTestValueSet<
148 Spatializer, Spatialization::Level, Range::spatializer,
149 Spatializer::spatializationLevel>(kDescPair)),
150 testing::ValuesIn(EffectHelper::getTestValueSet<
151 Spatializer, Spatialization::Mode, Range::spatializer,
152 Spatializer::spatializationMode>(kDescPair)),
153 testing::ValuesIn(
154 EffectHelper::getTestValueSet<Spatializer, int, Range::spatializer,
155 Spatializer::headTrackingSensorId>(
156 kDescPair, EffectHelper::expandTestValueBasic<int>)),
157 testing::ValuesIn(EffectHelper::getTestValueSet<
158 Spatializer, HeadTracking::Mode, Range::spatializer,
159 Spatializer::headTrackingMode>(kDescPair)),
160 testing::ValuesIn(EffectHelper::getTestValueSet<
161 Spatializer, HeadTracking::ConnectionMode, Range::spatializer,
162 Spatializer::headTrackingConnectionMode>(kDescPair))),
__anonf77b5c970202(const testing::TestParamInfo<SpatializerParamTest::ParamType>& info) 163 [](const testing::TestParamInfo<SpatializerParamTest::ParamType>& info) {
164 auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
165 std::string level = ToString(std::get<PARAM_SPATIALIZATION_LEVEL>(info.param));
166 std::string mode = ToString(std::get<PARAM_SPATIALIZATION_MODE>(info.param));
167 std::string sensorId = ToString(std::get<PARAM_HEADTRACK_SENSORID>(info.param));
168 std::string htMode = ToString(std::get<PARAM_HEADTRACK_MODE>(info.param));
169 std::string htConnectMode =
170 ToString(std::get<PARAM_HEADTRACK_CONNECTION_MODE>(info.param));
171 std::string name = getPrefix(descriptor) + "_sensorID_" + level + "_mode_" + mode +
172 "_sensorID_" + sensorId + "_HTMode_" + htMode +
173 "_HTConnectionMode_" + htConnectMode;
174 std::replace_if(
175 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
176 return name;
177 });
178
179 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SpatializerParamTest);
180
main(int argc,char ** argv)181 int main(int argc, char** argv) {
182 ::testing::InitGoogleTest(&argc, argv);
183 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
184 ABinderProcess_setThreadPoolMaxThreadCount(1);
185 ABinderProcess_startThreadPool();
186 return RUN_ALL_TESTS();
187 }
188