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 
isEffectExistsOnAudioSession(const effect_uuid_t * type,const effect_uuid_t * uuid,int priority,audio_session_t sessionId)73 status_t isEffectExistsOnAudioSession(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,
276               isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
277                                            kDefaultInputEffectPriority - 1,
278                                            capture->getAudioRecordHandle()->getSessionId()))
279             << "Effect should not have been added. " << type;
280     EXPECT_EQ(OK, capture->audioProcess());
281     EXPECT_EQ(OK, capture->stop());
282 
283     String16 name{gPackageName};
284     audio_unique_id_t effectId;
285     status_t status = AudioEffect::addSourceDefaultEffect(type.c_str(), name, uuid.c_str(),
286                                                           kDefaultInputEffectPriority,
287                                                           AUDIO_SOURCE_MIC, &effectId);
288     EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
289 
290     capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
291     ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
292     EXPECT_EQ(NO_ERROR, capture->create());
293     EXPECT_EQ(NO_ERROR, capture->start());
294     ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
295     EXPECT_TRUE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
296                                         capture->getAudioRecordHandle()))
297             << "Effect should have been default on record. " << type;
298     EXPECT_EQ(ALREADY_EXISTS,
299               isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
300                                            kDefaultInputEffectPriority - 1,
301                                            capture->getAudioRecordHandle()->getSessionId()))
302             << "Effect should have been added. " << type;
303     EXPECT_EQ(OK, capture->audioProcess());
304     EXPECT_EQ(OK, capture->stop());
305 
306     status = AudioEffect::removeSourceDefaultEffect(effectId);
307     EXPECT_EQ(NO_ERROR, status);
308     capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
309     ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
310     EXPECT_EQ(NO_ERROR, capture->create());
311     EXPECT_EQ(NO_ERROR, capture->start());
312     ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
313     EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
314                                          capture->getAudioRecordHandle()))
315             << "Effect should not have been default on record. " << type;
316     EXPECT_EQ(NO_ERROR,
317               isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
318                                            kDefaultInputEffectPriority - 1,
319                                            capture->getAudioRecordHandle()->getSessionId()))
320             << "Effect should not have been added. " << type;
321     EXPECT_EQ(OK, capture->audioProcess());
322     EXPECT_EQ(OK, capture->stop());
323 }
324 
TEST(AudioEffectTest,AuxEffectSanityTest)325 TEST(AudioEffectTest, AuxEffectSanityTest) {
326     int32_t selectedEffect = -1;
327     std::vector<effect_descriptor_t> descriptors;
328     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
329     for (auto i = 0; i < descriptors.size(); i++) {
330         if (isAux(descriptors[i])) {
331             selectedEffect = i;
332             break;
333         }
334     }
335     if (selectedEffect == -1) GTEST_SKIP() << "expected at least one aux effect";
336     effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
337     effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
338     auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
339     String16 name{gPackageName};
340     audio_session_t sessionId =
341             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
342     sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
343                                                kDefaultInputEffectPriority, sessionId);
344     EXPECT_EQ(NO_INIT, audioEffect->initCheck())
345             << "error, creating auxiliary effect (" << type << ") on session id " << (int)sessionId
346             << " successful ";
347     audio_unique_id_t id;
348     status_t status = AudioEffect::addStreamDefaultEffect(
349             type.c_str(), name, uuid.c_str(), kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
350     if (status == NO_ERROR) {
351         EXPECT_EQ(NO_ERROR, AudioEffect::removeStreamDefaultEffect(id));
352         EXPECT_NE(NO_ERROR, status) << "error, adding auxiliary effect (" << type
353                                     << ") as stream default effect is successful";
354     }
355 }
356 
357 class AudioPlaybackEffectTest : public ::testing::TestWithParam<bool> {
358   public:
AudioPlaybackEffectTest()359     AudioPlaybackEffectTest() : mSelectFastMode(GetParam()){};
360 
361     const bool mSelectFastMode;
362 
363     bool mIsFastCompatibleEffect;
364     effect_uuid_t mType;
365     effect_uuid_t mUuid;
366     std::string mTypeStr;
367     std::string mUuidStr;
368 
SetUp()369     void SetUp() override {
370         if (mSelectFastMode) {
371             std::vector<struct audio_port_v7> ports;
372             ASSERT_EQ(OK, listAudioPorts(ports));
373             if (!doesDeviceSupportLowLatencyMode(ports)) {
374                 GTEST_SKIP() << "device does not support low latency mode";
375             }
376         }
377 
378         int32_t selectedEffect = -1;
379         std::vector<effect_descriptor_t> descriptors;
380         ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
381         for (auto i = 0; i < descriptors.size(); i++) {
382             if (isSpatializer(descriptors[i])) continue;
383             if (isHapticGenerator(descriptors[i]) && !AudioSystem::isHapticPlaybackSupported())
384                 continue;
385             if (!isInsert(descriptors[i])) continue;
386             selectedEffect = i;
387             mIsFastCompatibleEffect = isFastCompatible(descriptors[i]);
388             // in fast mode, pick fast compatible effect if available
389             if (mSelectFastMode == mIsFastCompatibleEffect) break;
390         }
391         if (selectedEffect == -1) {
392             GTEST_SKIP() << "expected at least one valid effect";
393         }
394 
395         mType = descriptors[selectedEffect].type;
396         mUuid = descriptors[selectedEffect].uuid;
397         std::tie(mTypeStr, mUuidStr) = typeAndUuidToString(descriptors[selectedEffect]);
398     }
399 };
400 
TEST_P(AudioPlaybackEffectTest,StreamDefaultEffectTest)401 TEST_P(AudioPlaybackEffectTest, StreamDefaultEffectTest) {
402     SCOPED_TRACE(testing::Message()
403                  << "\n selected effect type is :: " << mTypeStr
404                  << "\n selected effect uuid is :: " << mUuidStr
405                  << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
406                  << "\n audio effect is fast compatible : "
407                  << (mIsFastCompatibleEffect ? "yes" : "no"));
408 
409     bool compatCheck = !mSelectFastMode || (mSelectFastMode && mIsFastCompatibleEffect);
410 
411     // create track
412     audio_attributes_t attributes;
413     attributes.usage = AUDIO_USAGE_MEDIA;
414     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
415     auto playback = sp<AudioPlayback>::make(
416             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
417             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
418             AudioTrack::TRANSFER_SHARED, &attributes);
419     ASSERT_NE(nullptr, playback);
420     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
421     EXPECT_EQ(NO_ERROR, playback->create());
422     EXPECT_EQ(NO_ERROR, playback->start());
423     EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
424               isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
425                                            playback->getAudioTrackHandle()->getSessionId()))
426             << "Effect should not have been added. " << mTypeStr;
427     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
428     playback->stop();
429     playback.clear();
430 
431     String16 name{gPackageName};
432     audio_unique_id_t id;
433     status_t status = AudioEffect::addStreamDefaultEffect(mTypeStr.c_str(), name, mUuidStr.c_str(),
434                                                           kDefaultOutputEffectPriority,
435                                                           AUDIO_USAGE_MEDIA, &id);
436     EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << mTypeStr;
437 
438     playback = sp<AudioPlayback>::make(
439             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
440             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
441             AudioTrack::TRANSFER_SHARED, &attributes);
442     ASSERT_NE(nullptr, playback);
443     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
444     EXPECT_EQ(NO_ERROR, playback->create());
445     EXPECT_EQ(NO_ERROR, playback->start());
446     // If effect chosen is not compatible with the session, then effect won't be applied
447     EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
448               isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
449                                            playback->getAudioTrackHandle()->getSessionId()))
450             << "Effect should have been added. " << mTypeStr;
451     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
452     if (mSelectFastMode) {
453         EXPECT_EQ(AUDIO_OUTPUT_FLAG_FAST,
454                   playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
455     }
456     playback->stop();
457     playback.clear();
458 
459     status = AudioEffect::removeStreamDefaultEffect(id);
460     EXPECT_EQ(NO_ERROR, status);
461     playback = sp<AudioPlayback>::make(
462             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
463             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
464             AudioTrack::TRANSFER_SHARED, &attributes);
465     ASSERT_NE(nullptr, playback);
466     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
467     EXPECT_EQ(NO_ERROR, playback->create());
468     EXPECT_EQ(NO_ERROR, playback->start());
469     EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
470               isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
471                                            playback->getAudioTrackHandle()->getSessionId()))
472             << "Effect should not have been added. " << mTypeStr;
473     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
474     playback->stop();
475     playback.clear();
476 }
477 
TEST_P(AudioPlaybackEffectTest,CheckOutputFlagCompatibility)478 TEST_P(AudioPlaybackEffectTest, CheckOutputFlagCompatibility) {
479     SCOPED_TRACE(testing::Message()
480                  << "\n selected effect type is :: " << mTypeStr
481                  << "\n selected effect uuid is :: " << mUuidStr
482                  << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
483                  << "\n audio effect is fast compatible : "
484                  << (mIsFastCompatibleEffect ? "yes" : "no"));
485 
486     audio_attributes_t attributes;
487     attributes.usage = AUDIO_USAGE_MEDIA;
488     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
489     audio_session_t sessionId =
490             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
491     sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
492     sp<AudioEffect> audioEffect =
493             createEffect(&mType, &mUuid, kDefaultOutputEffectPriority, sessionId, cb);
494     ASSERT_EQ(OK, audioEffect->initCheck());
495     ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
496     auto playback = sp<AudioPlayback>::make(
497             0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO,
498             mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, sessionId,
499             AudioTrack::TRANSFER_SHARED, &attributes);
500     ASSERT_NE(nullptr, playback);
501     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"));
502     EXPECT_EQ(NO_ERROR, playback->create());
503     EXPECT_EQ(NO_ERROR, playback->start());
504 
505     EXPECT_EQ(ALREADY_EXISTS, isEffectExistsOnAudioSession(
506                                       &mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
507             << "Effect should have been added. " << mTypeStr;
508     if (mSelectFastMode) {
509         EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
510                   playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
511     }
512     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
513     EXPECT_EQ(NO_ERROR, playback->getAudioTrackHandle()->attachAuxEffect(0));
514     playback->stop();
515     playback.clear();
516     EXPECT_TRUE(cb->receivedFramesProcessed)
517             << "AudioEffect frames processed callback not received";
518 }
519 
520 INSTANTIATE_TEST_SUITE_P(EffectParameterizedTests, AudioPlaybackEffectTest, ::testing::Bool());
521 
TEST(AudioEffectTest,TestHapticEffect)522 TEST(AudioEffectTest, TestHapticEffect) {
523     if (!AudioSystem::isHapticPlaybackSupported())
524         GTEST_SKIP() << "Haptic playback is not supported";
525     int32_t selectedEffect = -1;
526     std::vector<effect_descriptor_t> descriptors;
527     ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
528     for (auto i = 0; i < descriptors.size(); i++) {
529         if (!isHapticGenerator(descriptors[i])) continue;
530         selectedEffect = i;
531         break;
532     }
533     if (selectedEffect == -1) GTEST_SKIP() << "expected at least one valid effect";
534 
535     effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
536     effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
537     auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
538 
539     SCOPED_TRACE(testing::Message() << "\n selected effect type is :: " << type
540                                     << "\n selected effect uuid is :: " << uuid);
541 
542     audio_attributes_t attributes;
543     attributes.usage = AUDIO_USAGE_MEDIA;
544     attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
545     audio_session_t sessionId =
546             (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
547     sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
548     sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
549                                                kDefaultOutputEffectPriority, sessionId, cb);
550     ASSERT_EQ(OK, audioEffect->initCheck());
551     ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
552     auto playback = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
553                                             AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
554                                             sessionId, AudioTrack::TRANSFER_SHARED, &attributes);
555     ASSERT_NE(nullptr, playback);
556     ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
557     EXPECT_EQ(NO_ERROR, playback->create());
558     EXPECT_EQ(NO_ERROR, playback->start());
559     EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
560                                              kDefaultOutputEffectPriority - 1, sessionId))
561             << "Effect should have been added. " << type;
562     EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
563     playback->stop();
564     playback.clear();
565     EXPECT_TRUE(cb->receivedFramesProcessed)
566             << "AudioEffect frames processed callback not received";
567 }
568 
main(int argc,char ** argv)569 int main(int argc, char** argv) {
570     android::ProcessState::self()->startThreadPool();
571     ::testing::InitGoogleTest(&argc, argv);
572     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
573     return RUN_ALL_TESTS();
574 }
575