1 /*
2  * Copyright 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 //#define LOG_NDEBUG 0
18 #include <algorithm>
19 #include <array>
20 #include <cstddef>
21 #include <cstdint>
22 #include <cstring>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #define LOG_TAG "EffectsFactoryHalInterfaceTest"
27 
28 #include <aidl/android/media/audio/common/AudioUuid.h>
29 #include <android/media/audio/common/HeadTracking.h>
30 #include <android/media/audio/common/Spatialization.h>
31 #include <gtest/gtest.h>
32 #include <media/AidlConversionCppNdk.h>
33 #include <media/audiohal/EffectsFactoryHalInterface.h>
34 #include <system/audio_aidl_utils.h>
35 #include <system/audio_effect.h>
36 #include <system/audio_effects/audio_effects_utils.h>
37 #include <system/audio_effects/effect_aec.h>
38 #include <system/audio_effects/effect_agc.h>
39 #include <system/audio_effects/effect_agc2.h>
40 #include <system/audio_effects/effect_bassboost.h>
41 #include <system/audio_effects/effect_downmix.h>
42 #include <system/audio_effects/effect_dynamicsprocessing.h>
43 #include <system/audio_effects/effect_hapticgenerator.h>
44 #include <system/audio_effects/effect_loudnessenhancer.h>
45 #include <system/audio_effects/effect_ns.h>
46 #include <system/audio_effects/effect_spatializer.h>
47 #include <utils/RefBase.h>
48 #include <vibrator/ExternalVibrationUtils.h>
49 
50 namespace android {
51 
52 using aidl::android::media::audio::common::AudioUuid;
53 using android::audio::utils::toString;
54 using effect::utils::EffectParamReader;
55 using effect::utils::EffectParamWriter;
56 using media::audio::common::HeadTracking;
57 using media::audio::common::Spatialization;
58 
59 // EffectsFactoryHalInterface
TEST(libAudioHalTest,createEffectsFactoryHalInterface)60 TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
61     ASSERT_NE(nullptr, EffectsFactoryHalInterface::create());
62 }
63 
TEST(libAudioHalTest,queryNumberEffects)64 TEST(libAudioHalTest, queryNumberEffects) {
65     auto factory = EffectsFactoryHalInterface::create();
66     ASSERT_NE(nullptr, factory);
67 
68     uint32_t numEffects = 0;
69     EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
70     EXPECT_NE(0ul, numEffects);
71 }
72 
TEST(libAudioHalTest,getDescriptorByNumber)73 TEST(libAudioHalTest, getDescriptorByNumber) {
74     auto factory = EffectsFactoryHalInterface::create();
75     ASSERT_NE(nullptr, factory);
76 
77     uint32_t numEffects = 0;
78     EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
79     EXPECT_NE(0ul, numEffects);
80 
81     effect_descriptor_t desc;
82     for (uint32_t i = 0; i < numEffects; i++) {
83         EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
84     }
85 }
86 
TEST(libAudioHalTest,createEffect)87 TEST(libAudioHalTest, createEffect) {
88     auto factory = EffectsFactoryHalInterface::create();
89     ASSERT_NE(nullptr, factory);
90 
91     uint32_t numEffects = 0;
92     EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
93     EXPECT_NE(0ul, numEffects);
94 
95     effect_descriptor_t desc;
96     for (uint32_t i = 0; i < numEffects; i++) {
97         sp<EffectHalInterface> interface;
98         EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
99         EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
100                                             1 /* deviceId */, &interface));
101     }
102 }
103 
TEST(libAudioHalTest,getProcessings)104 TEST(libAudioHalTest, getProcessings) {
105     auto factory = EffectsFactoryHalInterface::create();
106     ASSERT_NE(nullptr, factory);
107 
108     const auto &processings = factory->getProcessings();
109     if (processings) {
110         EXPECT_NE(0UL, processings->preprocess.size() + processings->postprocess.size() +
111                                processings->deviceprocess.size());
112 
113         auto processingChecker = [](const auto& processings) {
114             if (processings.size() != 0) {
115                 // any process need at least 1 effect inside
116                 std::for_each(processings.begin(), processings.end(), [](const auto& process) {
117                     EXPECT_NE(0ul, process.effects.size());
118                     // any effect should have a valid name string, and not proxy
119                     for (const auto& effect : process.effects) {
120                         SCOPED_TRACE("Effect: {" +
121                                      (effect == nullptr
122                                               ? "NULL}"
123                                               : ("{name: " + effect->name + ", isproxy: " +
124                                                  (effect->isProxy ? "true" : "false") + ", sw: " +
125                                                  (effect->libSw ? "non-null" : "null") + ", hw: " +
126                                                  (effect->libHw ? "non-null" : "null") + "}")));
127                         EXPECT_NE(nullptr, effect);
128                         EXPECT_NE("", effect->name);
129                         EXPECT_EQ(false, effect->isProxy);
130                         EXPECT_EQ(nullptr, effect->libSw);
131                         EXPECT_EQ(nullptr, effect->libHw);
132                     }
133                 });
134             }
135         };
136 
137         processingChecker(processings->preprocess);
138         processingChecker(processings->postprocess);
139         processingChecker(processings->deviceprocess);
140     } else {
141         GTEST_SKIP() << "no processing found, skipping the test";
142     }
143 }
144 
TEST(libAudioHalTest,getHalVersion)145 TEST(libAudioHalTest, getHalVersion) {
146     auto factory = EffectsFactoryHalInterface::create();
147     ASSERT_NE(nullptr, factory);
148 
149     auto version = factory->getHalVersion();
150     EXPECT_NE(0, version.getMajorVersion());
151 }
152 
153 enum ParamSetGetType { SET_N_GET, SET_ONLY, GET_ONLY };
154 class EffectParamCombination {
155   public:
156     template <typename P, typename V>
init(const P & p,const V & v,size_t len,ParamSetGetType type)157     void init(const P& p, const V& v, size_t len, ParamSetGetType type) {
158         if (type != GET_ONLY) {
159             mSetBuffer.resize(sizeof(effect_param_t) + sizeof(p) + sizeof(v) + 4);
160             mParameterSet =
161                     std::make_shared<EffectParamReader>(createEffectParam(mSetBuffer.data(), p, v));
162         }
163 
164         if (type != SET_ONLY) {
165             mGetBuffer.resize(sizeof(effect_param_t) + sizeof(p) + len + 4);
166             mExpectBuffer.resize(sizeof(effect_param_t) + sizeof(p) + len + 4);
167             mParameterGet =
168                     std::make_shared<EffectParamReader>(createEffectParam(mGetBuffer.data(), p, v));
169             mParameterExpect = std::make_shared<EffectParamReader>(
170                     createEffectParam(mExpectBuffer.data(), p, v));
171             mValueSize = len;
172         }
173         mType = type;
174     }
175 
176     std::shared_ptr<EffectParamReader> mParameterSet;    /* setParameter */
177     std::shared_ptr<EffectParamReader> mParameterGet;    /* getParameter */
178     std::shared_ptr<EffectParamReader> mParameterExpect; /* expected from getParameter */
179     size_t mValueSize = 0ul; /* ValueSize expect to write in reply data buffer */
180     ParamSetGetType mType = SET_N_GET;
181 
toString()182     std::string toString() {
183         uint32_t command = 0;
184         std::string str = "Command: ";
185         if (mType != GET_ONLY) {
186             str += (OK == mParameterSet->readFromParameter(&command) ? std::to_string(command)
187                                                                      : mParameterSet->toString());
188         } else {
189             str += (OK == mParameterGet->readFromParameter(&command) ? std::to_string(command)
190                                                                      : mParameterSet->toString());
191         }
192         str += "_";
193         str += toString(mType);
194         return str;
195     }
196 
toString(ParamSetGetType type)197     static std::string toString(ParamSetGetType type) {
198         switch (type) {
199             case SET_N_GET:
200                 return "Type:SetAndGet";
201             case SET_ONLY:
202                 return "Type:SetOnly";
203             case GET_ONLY:
204                 return "Type:GetOnly";
205         }
206     }
207 
208   private:
209     std::vector<uint8_t> mSetBuffer;
210     std::vector<uint8_t> mGetBuffer;
211     std::vector<uint8_t> mExpectBuffer;
212 
213     template <typename P, typename V>
createEffectParam(void * buf,const P & p,const V & v)214     static EffectParamReader createEffectParam(void* buf, const P& p, const V& v) {
215         effect_param_t* paramRet = (effect_param_t*)buf;
216         paramRet->psize = sizeof(P);
217         paramRet->vsize = sizeof(V);
218         EffectParamWriter writer(*paramRet);
219         EXPECT_EQ(OK, writer.writeToParameter(&p));
220         EXPECT_EQ(OK, writer.writeToValue(&v));
221         writer.finishValueWrite();
222         return writer;
223     }
224 };
225 
226 template <typename P, typename V>
createEffectParamCombination(const P & p,const V & v,size_t len,ParamSetGetType type=SET_N_GET)227 std::shared_ptr<EffectParamCombination> createEffectParamCombination(
228         const P& p, const V& v, size_t len, ParamSetGetType type = SET_N_GET) {
229     auto comb = std::make_shared<EffectParamCombination>();
230     comb->init(p, v, len, type);
231     return comb;
232 }
233 
234 enum ParamName { TUPLE_UUID, TUPLE_IS_INPUT, TUPLE_PARAM_COMBINATION };
235 using EffectParamTestTuple = std::tuple<const effect_uuid_t* /* type UUID */, bool /* isInput */,
236                                         std::vector<std::shared_ptr<EffectParamCombination>>>;
237 static const effect_uuid_t EXTEND_EFFECT_TYPE_UUID = {
238         0xfa81dbde, 0x588b, 0x11ed, 0x9b6a, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
239 constexpr std::array<uint8_t, 10> kVendorExtensionData({0xff, 0x5, 0x50, 0xab, 0xcd, 0x00, 0xbd,
240                                                         0xdb, 0xee, 0xff});
241 static std::vector<EffectParamTestTuple> testPairs = {
242         std::make_tuple(
243                 FX_IID_AEC, true /* isInput */,
244                 std::vector<std::shared_ptr<EffectParamCombination>>{
245                         createEffectParamCombination(AEC_PARAM_ECHO_DELAY, 0xff /* echoDelayMs */,
246                                                      sizeof(int32_t) /* returnValueSize */)}),
247         std::make_tuple(
248                 FX_IID_AGC, false /* isInput */,
249                 std::vector<std::shared_ptr<EffectParamCombination>>{
250                         createEffectParamCombination(AGC_PARAM_TARGET_LEVEL, 20 /* targetLevel */,
251                                                      sizeof(int16_t) /* returnValueSize */)}),
252         std::make_tuple(
253                 SL_IID_BASSBOOST, false /* isInput */,
254                 std::vector<std::shared_ptr<EffectParamCombination>>{
255                         createEffectParamCombination(BASSBOOST_PARAM_STRENGTH, 20 /* strength */,
256                                                      sizeof(int16_t) /* returnValueSize */)}),
257         std::make_tuple(
258                 EFFECT_UIID_DOWNMIX, false /* isInput */,
259                 std::vector<std::shared_ptr<EffectParamCombination>>{
260                         createEffectParamCombination(DOWNMIX_PARAM_TYPE, DOWNMIX_TYPE_FOLD,
261                                                      sizeof(int16_t) /* returnValueSize */)}),
262         std::make_tuple(
263                 SL_IID_DYNAMICSPROCESSING, false /* isInput */,
264                 std::vector<std::shared_ptr<EffectParamCombination>>{createEffectParamCombination(
265                         std::array<uint32_t, 2>({DP_PARAM_INPUT_GAIN, 0 /* channel */}),
266                         30 /* gainDb */, sizeof(int32_t) /* returnValueSize */)}),
267         std::make_tuple(
268                 FX_IID_LOUDNESS_ENHANCER, false /* isInput */,
269                 std::vector<std::shared_ptr<EffectParamCombination>>{createEffectParamCombination(
270                         LOUDNESS_ENHANCER_PARAM_TARGET_GAIN_MB, 5 /* gain */,
271                         sizeof(int32_t) /* returnValueSize */)}),
272         std::make_tuple(
273                 FX_IID_NS, true /* isInput */,
274                 std::vector<std::shared_ptr<EffectParamCombination>>{createEffectParamCombination(
275                         NS_PARAM_LEVEL, 1 /* level */, sizeof(int32_t) /* returnValueSize */)}),
276         std::make_tuple(
277                 FX_IID_SPATIALIZER, false /* isInput */,
278                 std::vector<std::shared_ptr<EffectParamCombination>>{
279                         createEffectParamCombination(SPATIALIZER_PARAM_LEVEL,
280                                                      SPATIALIZATION_LEVEL_MULTICHANNEL,
281                                                      sizeof(uint8_t), SET_N_GET),
282                         createEffectParamCombination(SPATIALIZER_PARAM_HEADTRACKING_MODE,
283                                                      HeadTracking::Mode::RELATIVE_WORLD,
284                                                      sizeof(uint8_t), SET_N_GET),
285                         createEffectParamCombination(
286                                 SPATIALIZER_PARAM_HEAD_TO_STAGE,
287                                 std::array<float, 6>{.55f, 0.2f, 1.f, .999f, .43f, 19.f},
288                                 sizeof(std::array<float, 6>), SET_ONLY),
289                         createEffectParamCombination(
290                                 SPATIALIZER_PARAM_HEADTRACKING_CONNECTION,
291                                 std::array<uint32_t, 2>{
292                                         static_cast<uint32_t>(HeadTracking::ConnectionMode::
293                                                                       DIRECT_TO_SENSOR_TUNNEL),
294                                         0x5e /* sensorId */},
295                                 sizeof(std::array<uint32_t, 2>), SET_N_GET),
296                         createEffectParamCombination(
297                                 SPATIALIZER_PARAM_SUPPORTED_LEVELS,
298                                 std::array<Spatialization::Level, 3>{
299                                         Spatialization::Level::NONE,
300                                         Spatialization::Level::MULTICHANNEL,
301                                         Spatialization::Level::BED_PLUS_OBJECTS},
302                                 sizeof(std::array<uint8_t, 3>), GET_ONLY),
303                         createEffectParamCombination(SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED, true,
304                                                      sizeof(bool), GET_ONLY),
305                         createEffectParamCombination(SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS,
306                                                      AUDIO_CHANNEL_OUT_5POINT1, sizeof(uint8_t),
307                                                      GET_ONLY),
308                         createEffectParamCombination(
309                                 SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES,
310                                 std::array<Spatialization::Mode, 2>{
311                                         Spatialization::Mode::BINAURAL,
312                                         Spatialization::Mode::TRANSAURAL},
313                                 sizeof(std::array<uint8_t, 2>), GET_ONLY),
314                         createEffectParamCombination(
315                                 SPATIALIZER_PARAM_SUPPORTED_HEADTRACKING_CONNECTION,
316                                 std::array<HeadTracking::ConnectionMode, 3>{
317                                         HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED,
318                                         HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_SW,
319                                         HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL},
320                                 sizeof(std::array<uint8_t, 3>), GET_ONLY),
321                 }),
322         std::make_tuple(
323                 &EXTEND_EFFECT_TYPE_UUID, false /* isInput */,
324                 std::vector<std::shared_ptr<EffectParamCombination>>{createEffectParamCombination(
325                         uint32_t{8}, kVendorExtensionData, sizeof(kVendorExtensionData))}),
326 };
327 
328 class libAudioHalEffectParamTest : public ::testing::TestWithParam<EffectParamTestTuple> {
329   public:
libAudioHalEffectParamTest()330     libAudioHalEffectParamTest()
331         : mParamTuple(GetParam()),
332           mFactory(EffectsFactoryHalInterface::create()),
333           mTypeUuid(std::get<TUPLE_UUID>(mParamTuple)),
334           mCombinations(std::get<TUPLE_PARAM_COMBINATION>(mParamTuple)),
335           mIsInput(std::get<TUPLE_IS_INPUT>(mParamTuple)),
336           mDescs([&]() {
337               std::vector<effect_descriptor_t> descs;
338               if (mFactory && mTypeUuid && OK == mFactory->getDescriptors(mTypeUuid, &descs)) {
339                   return descs;
340               }
341               return descs;
342           }()) {}
343 
SetUp()344     void SetUp() override {
345         if (0ul == mDescs.size()) {
346             GTEST_SKIP() << "Effect type not available on device, skipping";
347         }
348         for (const auto& desc : mDescs) {
349             sp<EffectHalInterface> interface = createEffectHal(desc);
350             ASSERT_NE(nullptr, interface);
351             mHalInterfaces.push_back(interface);
352         }
353     }
354 
initEffect(const sp<EffectHalInterface> & interface)355     void initEffect(const sp<EffectHalInterface>& interface) {
356         uint32_t reply = 0;
357         uint32_t replySize = sizeof(reply);
358         ASSERT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &replySize, &reply));
359 
360         ASSERT_EQ(OK, interface->command(EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
361                                          &mEffectConfig, &replySize, &reply));
362     }
363 
TearDown()364     void TearDown() override {
365         for (auto& interface : mHalInterfaces) {
366             interface->close();
367         }
368     }
369 
createEffectHal(const effect_descriptor_t & desc)370     sp<EffectHalInterface> createEffectHal(const effect_descriptor_t& desc) {
371         sp<EffectHalInterface> interface = nullptr;
372         if (0 == std::memcmp(&desc.type, mTypeUuid, sizeof(effect_uuid_t)) &&
373             OK == mFactory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
374                                          1 /* deviceId */, &interface)) {
375             return interface;
376         }
377         return nullptr;
378     }
379 
setAndGetParameter(const sp<EffectHalInterface> & interface)380     void setAndGetParameter(const sp<EffectHalInterface>& interface) {
381         for (const auto combination : mCombinations) {
382             uint32_t replySize = kSetParamReplySize;
383             uint8_t reply[replySize];
384             const auto type = combination->mType;
385             if (type != GET_ONLY) {
386                 const auto& set = combination->mParameterSet;
387                 ASSERT_EQ(OK,
388                           interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)set->getTotalSize(),
389                                              const_cast<effect_param_t*>(&set->getEffectParam()),
390                                              &replySize, &reply))
391                         << set->toString();
392                 ASSERT_EQ(replySize, kSetParamReplySize);
393             }
394 
395             if (type != SET_ONLY) {
396                 auto get = combination->mParameterGet;
397                 auto expect = combination->mParameterExpect;
398                 effect_param_t* getParam = const_cast<effect_param_t*>(&get->getEffectParam());
399                 size_t maxReplySize = combination->mValueSize + sizeof(effect_param_t) +
400                                       sizeof(expect->getPaddedParameterSize());
401                 replySize = maxReplySize;
402                 EXPECT_EQ(OK,
403                           interface->command(EFFECT_CMD_GET_PARAM, (uint32_t)expect->getTotalSize(),
404                                              const_cast<effect_param_t*>(&expect->getEffectParam()),
405                                              &replySize, getParam));
406 
407                 EffectParamReader getReader(*getParam);
408                 EXPECT_EQ(replySize, getReader.getTotalSize()) << getReader.toString();
409                 if (combination->mValueSize) {
410                     std::vector<uint8_t> expectedData(combination->mValueSize);
411                     EXPECT_EQ(OK, expect->readFromValue(expectedData.data(), expectedData.size()))
412                             << combination->toString();
413                     std::vector<uint8_t> response(combination->mValueSize);
414                     EXPECT_EQ(OK, getReader.readFromValue(response.data(), combination->mValueSize))
415                             << " try get valueSize " << combination->mValueSize << " from:\n"
416                             << getReader.toString() << "\nexpect:\n"
417                             << expect->toString();
418                     EXPECT_EQ(expectedData, response) << combination->toString();
419                 }
420             }
421         }
422     }
423 
424     static constexpr size_t kSetParamReplySize = sizeof(uint32_t);
425     const EffectParamTestTuple mParamTuple;
426     const sp<EffectsFactoryHalInterface> mFactory;
427     const effect_uuid_t* mTypeUuid;
428     std::vector<std::shared_ptr<EffectParamCombination>> mCombinations{};
429     const bool mIsInput;
430     const std::vector<effect_descriptor_t> mDescs;
431     std::vector<sp<EffectHalInterface>> mHalInterfaces{};
432     effect_config_t mEffectConfig = {
433             .inputCfg =
434                     {
435                             .buffer = {.frameCount = 0x100},
436                             .samplingRate = 48000,
437                             .channels = mIsInput ? AUDIO_CHANNEL_IN_VOICE_CALL_MONO
438                                                  : AUDIO_CHANNEL_IN_STEREO,
439                             .bufferProvider = {.getBuffer = nullptr,
440                                                .releaseBuffer = nullptr,
441                                                .cookie = nullptr},
442                             .format = AUDIO_FORMAT_PCM_FLOAT,
443                             .accessMode = EFFECT_BUFFER_ACCESS_READ,
444                             .mask = EFFECT_CONFIG_ALL,
445                     },
446             .outputCfg =
447                     {
448                             .buffer = {.frameCount = 0x100},
449                             .samplingRate = 48000,
450                             .channels = mIsInput ? AUDIO_CHANNEL_IN_VOICE_CALL_MONO
451                                                  : AUDIO_CHANNEL_OUT_STEREO,
452                             .bufferProvider = {.getBuffer = nullptr,
453                                                .releaseBuffer = nullptr,
454                                                .cookie = nullptr},
455                             .format = AUDIO_FORMAT_PCM_FLOAT,
456                             .accessMode = EFFECT_BUFFER_ACCESS_WRITE,
457                             .mask = EFFECT_CONFIG_ALL,
458                     },
459     };
460 };
461 
TEST_P(libAudioHalEffectParamTest,setAndGetParam)462 TEST_P(libAudioHalEffectParamTest, setAndGetParam) {
463     for (auto& interface : mHalInterfaces) {
464         EXPECT_NO_FATAL_FAILURE(initEffect(interface));
465         EXPECT_NO_FATAL_FAILURE(setAndGetParameter(interface));
466     }
467 }
468 
TEST_P(libAudioHalEffectParamTest,deviceIndicationUpdate)469 TEST_P(libAudioHalEffectParamTest, deviceIndicationUpdate) {
470     for (auto& interface : mHalInterfaces) {
471         EXPECT_NO_FATAL_FAILURE(initEffect(interface));
472 
473         // output device
474         uint32_t deviceTypes = AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_BLE_SPEAKER;
475         status_t cmdStatus;
476         uint32_t replySize = sizeof(cmdStatus);
477         EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_DEVICE, sizeof(uint32_t), &deviceTypes,
478                                          &replySize, &cmdStatus));
479         // input device
480         deviceTypes = AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_BLUETOOTH_BLE;
481         EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_DEVICE, sizeof(uint32_t), &deviceTypes,
482                                          &replySize, &cmdStatus));
483     }
484 }
485 
TEST_P(libAudioHalEffectParamTest,audioModeIndicationUpdate)486 TEST_P(libAudioHalEffectParamTest, audioModeIndicationUpdate) {
487     for (auto& interface : mHalInterfaces) {
488         EXPECT_NO_FATAL_FAILURE(initEffect(interface));
489         uint32_t mode = AUDIO_MODE_IN_CALL;
490         status_t cmdStatus;
491         uint32_t replySize = sizeof(cmdStatus);
492         EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_AUDIO_MODE, sizeof(uint32_t), &mode,
493                                          &replySize, &cmdStatus));
494     }
495 }
496 
TEST_P(libAudioHalEffectParamTest,audioSourceIndicationUpdate)497 TEST_P(libAudioHalEffectParamTest, audioSourceIndicationUpdate) {
498     for (auto& interface : mHalInterfaces) {
499         EXPECT_NO_FATAL_FAILURE(initEffect(interface));
500         uint32_t source = AUDIO_SOURCE_MIC;
501         status_t cmdStatus;
502         uint32_t replySize = sizeof(cmdStatus);
503         EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_AUDIO_SOURCE, sizeof(uint32_t), &source,
504                                          &replySize, &cmdStatus));
505     }
506 }
507 
508 INSTANTIATE_TEST_SUITE_P(
509         libAudioHalEffectParamTest, libAudioHalEffectParamTest, ::testing::ValuesIn(testPairs),
__anon059b18210402(const testing::TestParamInfo<libAudioHalEffectParamTest::ParamType>& info) 510         [](const testing::TestParamInfo<libAudioHalEffectParamTest::ParamType>& info) {
511             AudioUuid uuid = ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(
512                                      *std::get<TUPLE_UUID>(info.param))
513                                      .value();
514             std::string name = "UUID_" + toString(uuid) + "_";
515             name += std::get<TUPLE_IS_INPUT>(info.param) ? "_input" : "_output";
516             std::replace_if(
517                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
518             return name;
519         });
520 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(libAudioHalEffectParamTest);
521 
main(int argc,char ** argv)522 int main(int argc, char** argv) {
523     ::testing::InitGoogleTest(&argc, argv);
524     return RUN_ALL_TESTS();
525 }
526 
527 } // namespace android
528