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