xref: /aosp_15_r20/frameworks/av/media/libaudioclient/tests/audioeffect_tests.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2021 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 #define LOG_TAG "AudioEffectTests"
19 
20 #include <binder/ProcessState.h>
21 #include <gtest/gtest.h>
22 #include <media/AudioEffect.h>
23 #include <system/audio_effects/effect_hapticgenerator.h>
24 #include <system/audio_effects/effect_spatializer.h>
25 #include <system/audio_effects/effect_visualizer.h>
26 
27 #include "audio_test_utils.h"
28 #include "test_execution_tracer.h"
29 
30 using namespace android;
31 
32 class AudioEffectCallback : public AudioEffect::IAudioEffectCallback {
33   public:
34     bool receivedFramesProcessed = false;
35 
onFramesProcessed(int32_t framesProcessed)36     void onFramesProcessed(int32_t framesProcessed) override {
37         ALOGE("number of frames processed %d", framesProcessed);
38         receivedFramesProcessed = true;
39     }
40 };
41 
42 static constexpr int kDefaultInputEffectPriority = -1;
43 static constexpr int kDefaultOutputEffectPriority = 0;
44 
45 static const char* gPackageName = "AudioEffectTest";
46 
doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7> & ports)47 bool doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7>& ports) {
48     for (const auto& port : ports) {
49         if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_MIX) {
50             if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_FAST) != 0) {
51                 return true;
52             }
53         }
54     }
55     return false;
56 }
57 
createEffect(const effect_uuid_t * type,const effect_uuid_t * uuid=nullptr,int priority=0,audio_session_t sessionId=AUDIO_SESSION_OUTPUT_MIX,const wp<AudioEffectCallback> & callback=nullptr)58 sp<AudioEffect> createEffect(const effect_uuid_t* type, const effect_uuid_t* uuid = nullptr,
59                              int priority = 0, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
60                              const wp<AudioEffectCallback>& callback = nullptr) {
61     std::string packageName{gPackageName};
62     AttributionSourceState attributionSource;
63     attributionSource.packageName = packageName;
64     attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
65     attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
66     attributionSource.token = sp<BBinder>::make();
67     sp<AudioEffect> effect = new AudioEffect(attributionSource);
68     effect->set(type, uuid, priority, callback, sessionId, AUDIO_IO_HANDLE_NONE, {}, false,
69                 (callback != nullptr));
70     return effect;
71 }
72 
createAndInitCheckEffect(const effect_uuid_t * type,const effect_uuid_t * uuid,int priority,audio_session_t sessionId)73 status_t createAndInitCheckEffect(const effect_uuid_t* type, const effect_uuid_t* uuid,
74                                   int priority, audio_session_t sessionId) {
75     sp<AudioEffect> effect = createEffect(type, uuid, priority, sessionId);
76     return effect->initCheck();
77 }
78 
isEffectDefaultOnRecord(const effect_uuid_t * type,const effect_uuid_t * uuid,const sp<AudioRecord> & audioRecord)79 bool isEffectDefaultOnRecord(const effect_uuid_t* type, const effect_uuid_t* uuid,
80                              const sp<AudioRecord>& audioRecord) {
81     effect_descriptor_t descriptors[AudioEffect::kMaxPreProcessing];
82     uint32_t numEffects = AudioEffect::kMaxPreProcessing;
83     status_t ret = AudioEffect::queryDefaultPreProcessing(audioRecord->getSessionId(), descriptors,
84                                                           &numEffects);
85     if (ret != OK || numEffects > AudioEffect::kMaxPreProcessing) {
86         return false;
87     }
88     for (int i = 0; i < numEffects; i++) {
89         if ((memcmp(&descriptors[i].type, type, sizeof(effect_uuid_t)) == 0) &&
90             (memcmp(&descriptors[i].uuid, uuid, sizeof(effect_uuid_t)) == 0)) {
91             return true;
92         }
93     }
94     return false;
95 }
96 
listEffectsAvailable(std::vector<effect_descriptor_t> & descriptors)97 void listEffectsAvailable(std::vector<effect_descriptor_t>& descriptors) {
98     uint32_t numEffects = 0;
99     ASSERT_EQ(NO_ERROR, AudioEffect::queryNumberEffects(&numEffects));
100     for (auto i = 0; i < numEffects; i++) {
101         effect_descriptor_t des;
102         ASSERT_EQ(NO_ERROR, AudioEffect::queryEffect(i, &des));
103         descriptors.push_back(des);
104     }
105 }
106 
isPreprocessing(effect_descriptor_t & descriptor)107 bool isPreprocessing(effect_descriptor_t& descriptor) {
108     return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC);
109 }
110 
isInsert(effect_descriptor_t & descriptor)111 bool isInsert(effect_descriptor_t& descriptor) {
112     return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT);
113 }
114 
isAux(effect_descriptor_t & descriptor)115 bool isAux(effect_descriptor_t& descriptor) {
116     return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY);
117 }
118 
isPostproc(effect_descriptor_t & descriptor)119 bool isPostproc(effect_descriptor_t& descriptor) {
120     return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC);
121 }
122 
isFastCompatible(effect_descriptor_t & descriptor)123 bool isFastCompatible(effect_descriptor_t& descriptor) {
124     return !(((descriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0) &&
125              ((descriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0));
126 }
127 
isSpatializer(effect_descriptor_t & descriptor)128 bool isSpatializer(effect_descriptor_t& descriptor) {
129     return (memcmp(&descriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0);
130 }
131 
isHapticGenerator(effect_descriptor_t & descriptor)132 bool isHapticGenerator(effect_descriptor_t& descriptor) {
133     return (memcmp(&descriptor.type, FX_IID_HAPTICGENERATOR, sizeof(effect_uuid_t)) == 0);
134 }
135 
typeAndUuidToString(const effect_descriptor_t & desc)136 std::tuple<std::string, std::string> typeAndUuidToString(const effect_descriptor_t& desc) {
137     char type[512];
138     AudioEffect::guidToString(&desc.type, type, sizeof(type));
139     char uuid[512];
140     AudioEffect::guidToString(&desc.uuid, uuid, sizeof(uuid));
141     return std::make_tuple(type, uuid);
142 }
143 
144 // UNIT TESTS
TEST(AudioEffectTest,getEffectDescriptor)145 TEST(AudioEffectTest, getEffectDescriptor) {
146     effect_uuid_t randomType = {
147             0x81781c08, 0x93dd, 0x11ec, 0xb909, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
148     effect_uuid_t randomUuid = {
149             0x653730e1, 0x1be1, 0x438e, 0xa35a, {0xfc, 0x9b, 0xa1, 0x2a, 0x5e, 0xc9}};
150     effect_uuid_t empty = EFFECT_UUID_INITIALIZER;
151 
152     effect_descriptor_t descriptor;
153     EXPECT_EQ(NAME_NOT_FOUND, AudioEffect::getEffectDescriptor(&randomUuid, &randomType,
154                                                                EFFECT_FLAG_TYPE_MASK, &descriptor));
155 
156     std::vector<effect_descriptor_t> descriptors;
157     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
158 
159     for (auto i = 0; i < descriptors.size(); i++) {
160         EXPECT_EQ(NO_ERROR,
161                   AudioEffect::getEffectDescriptor(&descriptors[i].uuid, &descriptors[i].type,
162                                                    EFFECT_FLAG_TYPE_MASK, &descriptor));
163         EXPECT_EQ(0, memcmp(&descriptor, &descriptors[i], sizeof(effect_uuid_t)));
164     }
165     // negative tests
166     if (descriptors.size() > 0) {
167         EXPECT_EQ(BAD_VALUE,
168                   AudioEffect::getEffectDescriptor(&descriptors[0].uuid, &descriptors[0].type,
169                                                    EFFECT_FLAG_TYPE_MASK, nullptr));
170     }
171     EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, nullptr,
172                                                           EFFECT_FLAG_TYPE_PRE_PROC, &descriptor));
173     EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&empty, &randomType,
174                                                           EFFECT_FLAG_TYPE_MASK, nullptr));
175     EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, &randomType,
176                                                           EFFECT_FLAG_TYPE_POST_PROC, &descriptor));
177     EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&randomUuid, nullptr,
178                                                           EFFECT_FLAG_TYPE_INSERT, &descriptor));
179 }
180 
TEST(AudioEffectTest,DISABLED_GetSetParameterForEffect)181 TEST(AudioEffectTest, DISABLED_GetSetParameterForEffect) {
182     sp<AudioEffect> visualizer = createEffect(SL_IID_VISUALIZATION);
183     status_t status = visualizer->initCheck();
184     ASSERT_TRUE(status == NO_ERROR || status == ALREADY_EXISTS) << "Init check error";
185     ASSERT_EQ(NO_ERROR, visualizer->setEnabled(true)) << "visualizer not enabled";
186 
187     uint32_t buf32[3][sizeof(effect_param_t) / sizeof(uint32_t) + 2];
188     effect_param_t* vis_none = (effect_param_t*)(buf32[0]);
189     effect_param_t* vis_rms = (effect_param_t*)(buf32[1]);
190     effect_param_t* vis_tmp = (effect_param_t*)(buf32[2]);
191 
192     // Visualizer::setMeasurementMode()
193     vis_none->psize = sizeof(uint32_t);
194     vis_none->vsize = sizeof(uint32_t);
195     *(int32_t*)vis_none->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
196     *((int32_t*)vis_none->data + 1) = MEASUREMENT_MODE_NONE;
197     EXPECT_EQ(NO_ERROR, visualizer->setParameter(vis_none))
198             << "setMeasurementMode doesn't report success";
199 
200     // Visualizer::getMeasurementMode()
201     vis_tmp->psize = sizeof(uint32_t);
202     vis_tmp->vsize = sizeof(uint32_t);
203     *(int32_t*)vis_tmp->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
204     *((int32_t*)vis_tmp->data + 1) = 23;
205     EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
206             << "getMeasurementMode doesn't report success";
207     EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
208             << "target mode does not match set mode";
209 
210     // Visualizer::setMeasurementModeDeferred()
211     vis_rms->psize = sizeof(uint32_t);
212     vis_rms->vsize = sizeof(uint32_t);
213     *(int32_t*)vis_rms->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
214     *((int32_t*)vis_rms->data + 1) = MEASUREMENT_MODE_PEAK_RMS;
215     EXPECT_EQ(NO_ERROR, visualizer->setParameterDeferred(vis_rms))
216             << "setMeasurementModeDeferred doesn't report success";
217 
218     *((int32_t*)vis_tmp->data + 1) = 23;
219     EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
220             << "getMeasurementMode doesn't report success";
221     EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
222             << "target mode does not match set mode";
223 
224     // setParameterCommit
225     EXPECT_EQ(NO_ERROR, visualizer->setParameterCommit())
226             << "setMeasurementModeCommit does not report success";
227 
228     // validate Params
229     *((int32_t*)vis_tmp->data + 1) = 23;
230     EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
231             << "getMeasurementMode doesn't report success";
232     EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_rms->data + 1))
233             << "target mode does not match set mode";
234 }
235 
TEST(AudioEffectTest,ManageSourceDefaultEffects)236 TEST(AudioEffectTest, ManageSourceDefaultEffects) {
237     int32_t selectedEffect = -1;
238 
239     const uint32_t sampleRate = 44100;
240     const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
241     const audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_STEREO;
242     sp<AudioCapture> capture = nullptr;
243 
244     std::vector<effect_descriptor_t> descriptors;
245     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
246     for (auto i = 0; i < descriptors.size(); i++) {
247         if (isPreprocessing(descriptors[i])) {
248             capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
249             ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
250             EXPECT_EQ(NO_ERROR, capture->create());
251             EXPECT_EQ(NO_ERROR, capture->start());
252             ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
253             if (!isEffectDefaultOnRecord(&descriptors[i].type, &descriptors[i].uuid,
254                                          capture->getAudioRecordHandle())) {
255                 selectedEffect = i;
256                 EXPECT_EQ(OK, capture->stop());
257                 break;
258             }
259             EXPECT_EQ(OK, capture->stop());
260         }
261     }
262     if (selectedEffect == -1) GTEST_SKIP() << " expected at least one preprocessing effect";
263 
264     effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
265     effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
266     auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
267     capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
268     ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
269     EXPECT_EQ(NO_ERROR, capture->create());
270     EXPECT_EQ(NO_ERROR, capture->start());
271     ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
272     EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
273                                          capture->getAudioRecordHandle()))
274             << "Effect should not have been default on record. " << type;
275     EXPECT_EQ(NO_ERROR, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
276                                                  kDefaultInputEffectPriority - 1,
277                                                  capture->getAudioRecordHandle()->getSessionId()))
278             << "Effect should not have been added. " << type;
279     EXPECT_EQ(OK, capture->audioProcess());
280     EXPECT_EQ(OK, capture->stop());
281 
282     String16 name{gPackageName};
283     audio_unique_id_t effectId;
284     status_t status = AudioEffect::addSourceDefaultEffect(type.c_str(), name, uuid.c_str(),
285                                                           kDefaultInputEffectPriority,
286                                                           AUDIO_SOURCE_MIC, &effectId);
287     EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
288 
289     capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
290     ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
291     EXPECT_EQ(NO_ERROR, capture->create());
292     EXPECT_EQ(NO_ERROR, capture->start());
293     ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
294     EXPECT_TRUE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
295                                         capture->getAudioRecordHandle()))
296             << "Effect should have been default on record. " << type;
297     EXPECT_EQ(ALREADY_EXISTS,
298               createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
299                                        kDefaultInputEffectPriority - 1,
300                                        capture->getAudioRecordHandle()->getSessionId()))
301             << "Effect should have been added. " << type;
302     EXPECT_EQ(OK, capture->audioProcess());
303     EXPECT_EQ(OK, capture->stop());
304 
305     status = AudioEffect::removeSourceDefaultEffect(effectId);
306     EXPECT_EQ(NO_ERROR, status);
307     capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
308     ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
309     EXPECT_EQ(NO_ERROR, capture->create());
310     EXPECT_EQ(NO_ERROR, capture->start());
311     ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
312     EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
313                                          capture->getAudioRecordHandle()))
314             << "Effect should not have been default on record. " << type;
315     EXPECT_EQ(NO_ERROR, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
316                                                  kDefaultInputEffectPriority - 1,
317                                                  capture->getAudioRecordHandle()->getSessionId()))
318             << "Effect should not have been added. " << type;
319     EXPECT_EQ(OK, capture->audioProcess());
320     EXPECT_EQ(OK, capture->stop());
321 }
322 
TEST(AudioEffectTest,AuxEffectSanityTest)323 TEST(AudioEffectTest, AuxEffectSanityTest) {
324     int32_t selectedEffect = -1;
325     std::vector<effect_descriptor_t> descriptors;
326     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
327     for (auto i = 0; i < descriptors.size(); i++) {
328         if (isAux(descriptors[i])) {
329             selectedEffect = i;
330             break;
331         }
332     }
333     if (selectedEffect == -1) GTEST_SKIP() << "expected at least one aux effect";
334     effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
335     effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
336     auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
337     String16 name{gPackageName};
338     audio_session_t sessionId =
339             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
340     sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
341                                                kDefaultInputEffectPriority, sessionId);
342     EXPECT_EQ(NO_INIT, audioEffect->initCheck())
343             << "error, creating auxiliary effect (" << type << ") on session id " << (int)sessionId
344             << " successful ";
345     audio_unique_id_t id;
346     status_t status = AudioEffect::addStreamDefaultEffect(
347             type.c_str(), name, uuid.c_str(), kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
348     if (status == NO_ERROR) {
349         EXPECT_EQ(NO_ERROR, AudioEffect::removeStreamDefaultEffect(id));
350         EXPECT_NE(NO_ERROR, status) << "error, adding auxiliary effect (" << type
351                                     << ") as stream default effect is successful";
352     }
353 }
354 
355 class AudioPlaybackEffectTest : public ::testing::TestWithParam<bool> {
356   public:
AudioPlaybackEffectTest()357     AudioPlaybackEffectTest() : mSelectFastMode(GetParam()){};
358 
359     const bool mSelectFastMode;
360 
361     bool mIsFastCompatibleEffect;
362     effect_uuid_t mType;
363     effect_uuid_t mUuid;
364     std::string mTypeStr;
365     std::string mUuidStr;
366 
SetUp()367     void SetUp() override {
368         if (mSelectFastMode) {
369             std::vector<struct audio_port_v7> ports;
370             ASSERT_EQ(OK, listAudioPorts(ports));
371             if (!doesDeviceSupportLowLatencyMode(ports)) {
372                 GTEST_SKIP() << "device does not support low latency mode";
373             }
374         }
375 
376         int32_t selectedEffect = -1;
377         std::vector<effect_descriptor_t> descriptors;
378         ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
379         for (auto i = 0; i < descriptors.size(); i++) {
380             if (isSpatializer(descriptors[i])) continue;
381             if (isHapticGenerator(descriptors[i]) && !AudioSystem::isHapticPlaybackSupported())
382                 continue;
383             if (!isInsert(descriptors[i])) continue;
384             selectedEffect = i;
385             mIsFastCompatibleEffect = isFastCompatible(descriptors[i]);
386             // in fast mode, pick fast compatible effect if available
387             if (mSelectFastMode == mIsFastCompatibleEffect) break;
388         }
389         if (selectedEffect == -1) {
390             GTEST_SKIP() << "expected at least one valid effect";
391         }
392 
393         mType = descriptors[selectedEffect].type;
394         mUuid = descriptors[selectedEffect].uuid;
395         std::tie(mTypeStr, mUuidStr) = typeAndUuidToString(descriptors[selectedEffect]);
396     }
397 };
398 
TEST_P(AudioPlaybackEffectTest,StreamDefaultEffectTest)399 TEST_P(AudioPlaybackEffectTest, StreamDefaultEffectTest) {
400     SCOPED_TRACE(testing::Message()
401                  << "\n selected effect type is :: " << mTypeStr
402                  << "\n selected effect uuid is :: " << mUuidStr
403                  << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
404                  << "\n audio effect is fast compatible : "
405                  << (mIsFastCompatibleEffect ? "yes" : "no"));
406 
407     bool compatCheck = !mSelectFastMode || (mSelectFastMode && mIsFastCompatibleEffect);
408 
409     // create track
410     audio_attributes_t attributes;
411     attributes.usage = AUDIO_USAGE_MEDIA;
412     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
413     auto playback = sp<AudioPlayback>::make(
414             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
415             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
416             AudioTrack::TRANSFER_SHARED, &attributes);
417     ASSERT_NE(nullptr, playback);
418     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
419     EXPECT_EQ(NO_ERROR, playback->create());
420     EXPECT_EQ(NO_ERROR, playback->start());
421     EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
422               createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
423                                        playback->getAudioTrackHandle()->getSessionId()))
424             << "Effect should not have been added. " << mTypeStr;
425     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
426     playback->stop();
427     playback.clear();
428 
429     String16 name{gPackageName};
430     audio_unique_id_t id;
431     status_t status = AudioEffect::addStreamDefaultEffect(mTypeStr.c_str(), name, mUuidStr.c_str(),
432                                                           kDefaultOutputEffectPriority,
433                                                           AUDIO_USAGE_MEDIA, &id);
434     EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << mTypeStr;
435 
436     playback = sp<AudioPlayback>::make(
437             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
438             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
439             AudioTrack::TRANSFER_SHARED, &attributes);
440     ASSERT_NE(nullptr, playback);
441     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
442     EXPECT_EQ(NO_ERROR, playback->create());
443     EXPECT_EQ(NO_ERROR, playback->start());
444     // If effect chosen is not compatible with the session, then effect won't be applied
445     EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
446               createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
447                                        playback->getAudioTrackHandle()->getSessionId()))
448             << "Effect should have been added. " << mTypeStr;
449     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
450     if (mSelectFastMode) {
451         EXPECT_EQ(AUDIO_OUTPUT_FLAG_FAST,
452                   playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
453     }
454     playback->stop();
455     playback.clear();
456 
457     status = AudioEffect::removeStreamDefaultEffect(id);
458     EXPECT_EQ(NO_ERROR, status);
459     playback = sp<AudioPlayback>::make(
460             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
461             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
462             AudioTrack::TRANSFER_SHARED, &attributes);
463     ASSERT_NE(nullptr, playback);
464     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
465     EXPECT_EQ(NO_ERROR, playback->create());
466     EXPECT_EQ(NO_ERROR, playback->start());
467     EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
468               createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
469                                        playback->getAudioTrackHandle()->getSessionId()))
470             << "Effect should not have been added. " << mTypeStr;
471     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
472     playback->stop();
473     playback.clear();
474 }
475 
TEST_P(AudioPlaybackEffectTest,CheckOutputFlagCompatibility)476 TEST_P(AudioPlaybackEffectTest, CheckOutputFlagCompatibility) {
477     SCOPED_TRACE(testing::Message()
478                  << "\n selected effect type is :: " << mTypeStr
479                  << "\n selected effect uuid is :: " << mUuidStr
480                  << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
481                  << "\n audio effect is fast compatible : "
482                  << (mIsFastCompatibleEffect ? "yes" : "no"));
483 
484     audio_attributes_t attributes;
485     attributes.usage = AUDIO_USAGE_MEDIA;
486     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
487     audio_session_t sessionId =
488             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
489     sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
490     sp<AudioEffect> audioEffect =
491             createEffect(&mType, &mUuid, kDefaultOutputEffectPriority, sessionId, cb);
492     ASSERT_EQ(OK, audioEffect->initCheck());
493     ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
494     auto playback = sp<AudioPlayback>::make(
495             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO,
496             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, sessionId,
497             AudioTrack::TRANSFER_SHARED, &attributes);
498     ASSERT_NE(nullptr, playback);
499     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"));
500     EXPECT_EQ(NO_ERROR, playback->create());
501     EXPECT_EQ(NO_ERROR, playback->start());
502 
503     EXPECT_EQ(ALREADY_EXISTS,
504               createAndInitCheckEffect(&mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
505             << "Effect should have been added. " << mTypeStr;
506     if (mSelectFastMode) {
507         EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
508                   playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
509     }
510     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
511     EXPECT_EQ(NO_ERROR, playback->getAudioTrackHandle()->attachAuxEffect(0));
512     playback->stop();
513     playback.clear();
514     EXPECT_TRUE(cb->receivedFramesProcessed)
515             << "AudioEffect frames processed callback not received";
516 }
517 
518 INSTANTIATE_TEST_SUITE_P(EffectParameterizedTests, AudioPlaybackEffectTest, ::testing::Bool());
519 
TEST(AudioEffectTest,TestHapticEffect)520 TEST(AudioEffectTest, TestHapticEffect) {
521     if (!AudioSystem::isHapticPlaybackSupported())
522         GTEST_SKIP() << "Haptic playback is not supported";
523     int32_t selectedEffect = -1;
524     std::vector<effect_descriptor_t> descriptors;
525     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
526     for (auto i = 0; i < descriptors.size(); i++) {
527         if (!isHapticGenerator(descriptors[i])) continue;
528         selectedEffect = i;
529         break;
530     }
531     if (selectedEffect == -1) GTEST_SKIP() << "expected at least one valid effect";
532 
533     effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
534     effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
535     auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
536 
537     SCOPED_TRACE(testing::Message() << "\n selected effect type is :: " << type
538                                     << "\n selected effect uuid is :: " << uuid);
539 
540     audio_attributes_t attributes;
541     attributes.usage = AUDIO_USAGE_MEDIA;
542     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
543     audio_session_t sessionId =
544             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
545     sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
546     sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
547                                                kDefaultOutputEffectPriority, sessionId, cb);
548     ASSERT_EQ(OK, audioEffect->initCheck());
549     ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
550     auto playback = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
551                                             AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
552                                             sessionId, AudioTrack::TRANSFER_SHARED, &attributes);
553     ASSERT_NE(nullptr, playback);
554     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
555     EXPECT_EQ(NO_ERROR, playback->create());
556     EXPECT_EQ(NO_ERROR, playback->start());
557     ASSERT_EQ(ALREADY_EXISTS, createAndInitCheckEffect(selectedEffectType, selectedEffectUuid,
558                                                        kDefaultOutputEffectPriority - 1, sessionId))
559             << "Effect should have been added. " << type;
560     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
561     playback->stop();
562     playback.clear();
563     EXPECT_TRUE(cb->receivedFramesProcessed)
564             << "AudioEffect frames processed callback not received";
565 }
566 
main(int argc,char ** argv)567 int main(int argc, char** argv) {
568     android::ProcessState::self()->startThreadPool();
569     ::testing::InitGoogleTest(&argc, argv);
570     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
571     return RUN_ALL_TESTS();
572 }
573