• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2012, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 
19 #define LOG_TAG "AudioFlinger"
20 //#define LOG_NDEBUG 0
21 
22 #include "Configuration.h"
23 #include <utils/Log.h>
24 #include <audio_effects/effect_visualizer.h>
25 #include <audio_utils/primitives.h>
26 #include <private/media/AudioEffectShared.h>
27 #include <media/EffectsFactoryApi.h>
28 
29 #include "AudioFlinger.h"
30 #include "ServiceUtilities.h"
31 
32 // ----------------------------------------------------------------------------
33 
34 // Note: the following macro is used for extremely verbose logging message.  In
35 // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
36 // 0; but one side effect of this is to turn all LOGV's as well.  Some messages
37 // are so verbose that we want to suppress them even when we have ALOG_ASSERT
38 // turned on.  Do not uncomment the #def below unless you really know what you
39 // are doing and want to see all of the extremely verbose messages.
40 //#define VERY_VERY_VERBOSE_LOGGING
41 #ifdef VERY_VERY_VERBOSE_LOGGING
42 #define ALOGVV ALOGV
43 #else
44 #define ALOGVV(a...) do { } while(0)
45 #endif
46 
47 #define min(a, b) ((a) < (b) ? (a) : (b))
48 
49 namespace android {
50 
51 // ----------------------------------------------------------------------------
52 //  EffectModule implementation
53 // ----------------------------------------------------------------------------
54 
55 #undef LOG_TAG
56 #define LOG_TAG "AudioFlinger::EffectModule"
57 
EffectModule(ThreadBase * thread,const wp<AudioFlinger::EffectChain> & chain,effect_descriptor_t * desc,int id,audio_session_t sessionId)58 AudioFlinger::EffectModule::EffectModule(ThreadBase *thread,
59                                         const wp<AudioFlinger::EffectChain>& chain,
60                                         effect_descriptor_t *desc,
61                                         int id,
62                                         audio_session_t sessionId)
63     : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX),
64       mThread(thread), mChain(chain), mId(id), mSessionId(sessionId),
65       mDescriptor(*desc),
66       // mConfig is set by configure() and not used before then
67       mEffectInterface(NULL),
68       mStatus(NO_INIT), mState(IDLE),
69       // mMaxDisableWaitCnt is set by configure() and not used before then
70       // mDisableWaitCnt is set by process() and updateState() and not used before then
71       mSuspended(false),
72       mAudioFlinger(thread->mAudioFlinger)
73 {
74     ALOGV("Constructor %p", this);
75     int lStatus;
76 
77     // create effect engine from effect factory
78     mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface);
79 
80     if (mStatus != NO_ERROR) {
81         return;
82     }
83     lStatus = init();
84     if (lStatus < 0) {
85         mStatus = lStatus;
86         goto Error;
87     }
88 
89     ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
90     return;
91 Error:
92     EffectRelease(mEffectInterface);
93     mEffectInterface = NULL;
94     ALOGV("Constructor Error %d", mStatus);
95 }
96 
~EffectModule()97 AudioFlinger::EffectModule::~EffectModule()
98 {
99     ALOGV("Destructor %p", this);
100     if (mEffectInterface != NULL) {
101         remove_effect_from_hal_l();
102         // release effect engine
103         EffectRelease(mEffectInterface);
104     }
105 }
106 
addHandle(EffectHandle * handle)107 status_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle)
108 {
109     status_t status;
110 
111     Mutex::Autolock _l(mLock);
112     int priority = handle->priority();
113     size_t size = mHandles.size();
114     EffectHandle *controlHandle = NULL;
115     size_t i;
116     for (i = 0; i < size; i++) {
117         EffectHandle *h = mHandles[i];
118         if (h == NULL || h->destroyed_l()) {
119             continue;
120         }
121         // first non destroyed handle is considered in control
122         if (controlHandle == NULL) {
123             controlHandle = h;
124         }
125         if (h->priority() <= priority) {
126             break;
127         }
128     }
129     // if inserted in first place, move effect control from previous owner to this handle
130     if (i == 0) {
131         bool enabled = false;
132         if (controlHandle != NULL) {
133             enabled = controlHandle->enabled();
134             controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
135         }
136         handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
137         status = NO_ERROR;
138     } else {
139         status = ALREADY_EXISTS;
140     }
141     ALOGV("addHandle() %p added handle %p in position %zu", this, handle, i);
142     mHandles.insertAt(handle, i);
143     return status;
144 }
145 
removeHandle(EffectHandle * handle)146 size_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
147 {
148     Mutex::Autolock _l(mLock);
149     size_t size = mHandles.size();
150     size_t i;
151     for (i = 0; i < size; i++) {
152         if (mHandles[i] == handle) {
153             break;
154         }
155     }
156     if (i == size) {
157         return size;
158     }
159     ALOGV("removeHandle() %p removed handle %p in position %zu", this, handle, i);
160 
161     mHandles.removeAt(i);
162     // if removed from first place, move effect control from this handle to next in line
163     if (i == 0) {
164         EffectHandle *h = controlHandle_l();
165         if (h != NULL) {
166             h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
167         }
168     }
169 
170     // Prevent calls to process() and other functions on effect interface from now on.
171     // The effect engine will be released by the destructor when the last strong reference on
172     // this object is released which can happen after next process is called.
173     if (mHandles.size() == 0 && !mPinned) {
174         mState = DESTROYED;
175     }
176 
177     return mHandles.size();
178 }
179 
180 // must be called with EffectModule::mLock held
controlHandle_l()181 AudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l()
182 {
183     // the first valid handle in the list has control over the module
184     for (size_t i = 0; i < mHandles.size(); i++) {
185         EffectHandle *h = mHandles[i];
186         if (h != NULL && !h->destroyed_l()) {
187             return h;
188         }
189     }
190 
191     return NULL;
192 }
193 
disconnect(EffectHandle * handle,bool unpinIfLast)194 size_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast)
195 {
196     ALOGV("disconnect() %p handle %p", this, handle);
197     // keep a strong reference on this EffectModule to avoid calling the
198     // destructor before we exit
199     sp<EffectModule> keep(this);
200     {
201         if (removeHandle(handle) == 0) {
202             if (!isPinned() || unpinIfLast) {
203                 sp<ThreadBase> thread = mThread.promote();
204                 if (thread != 0) {
205                     Mutex::Autolock _l(thread->mLock);
206                     thread->removeEffect_l(this);
207                 }
208                 sp<AudioFlinger> af = mAudioFlinger.promote();
209                 if (af != 0) {
210                     af->updateOrphanEffectChains(this);
211                 }
212                 AudioSystem::unregisterEffect(mId);
213             }
214         }
215     }
216     return mHandles.size();
217 }
218 
updateState()219 bool AudioFlinger::EffectModule::updateState() {
220     Mutex::Autolock _l(mLock);
221 
222     bool started = false;
223     switch (mState) {
224     case RESTART:
225         reset_l();
226         // FALL THROUGH
227 
228     case STARTING:
229         // clear auxiliary effect input buffer for next accumulation
230         if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
231             memset(mConfig.inputCfg.buffer.raw,
232                    0,
233                    mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
234         }
235         if (start_l() == NO_ERROR) {
236             mState = ACTIVE;
237             started = true;
238         } else {
239             mState = IDLE;
240         }
241         break;
242     case STOPPING:
243         if (stop_l() == NO_ERROR) {
244             mDisableWaitCnt = mMaxDisableWaitCnt;
245         } else {
246             mDisableWaitCnt = 1; // will cause immediate transition to IDLE
247         }
248         mState = STOPPED;
249         break;
250     case STOPPED:
251         // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
252         // turn off sequence.
253         if (--mDisableWaitCnt == 0) {
254             reset_l();
255             mState = IDLE;
256         }
257         break;
258     default: //IDLE , ACTIVE, DESTROYED
259         break;
260     }
261 
262     return started;
263 }
264 
process()265 void AudioFlinger::EffectModule::process()
266 {
267     Mutex::Autolock _l(mLock);
268 
269     if (mState == DESTROYED || mEffectInterface == NULL ||
270             mConfig.inputCfg.buffer.raw == NULL ||
271             mConfig.outputCfg.buffer.raw == NULL) {
272         return;
273     }
274 
275     if (isProcessEnabled()) {
276         // do 32 bit to 16 bit conversion for auxiliary effect input buffer
277         if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
278             ditherAndClamp(mConfig.inputCfg.buffer.s32,
279                                         mConfig.inputCfg.buffer.s32,
280                                         mConfig.inputCfg.buffer.frameCount/2);
281         }
282 
283         // do the actual processing in the effect engine
284         int ret = (*mEffectInterface)->process(mEffectInterface,
285                                                &mConfig.inputCfg.buffer,
286                                                &mConfig.outputCfg.buffer);
287 
288         // force transition to IDLE state when engine is ready
289         if (mState == STOPPED && ret == -ENODATA) {
290             mDisableWaitCnt = 1;
291         }
292 
293         // clear auxiliary effect input buffer for next accumulation
294         if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
295             memset(mConfig.inputCfg.buffer.raw, 0,
296                    mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
297         }
298     } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
299                 mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
300         // If an insert effect is idle and input buffer is different from output buffer,
301         // accumulate input onto output
302         sp<EffectChain> chain = mChain.promote();
303         if (chain != 0 && chain->activeTrackCnt() != 0) {
304             size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2;  //always stereo here
305             int16_t *in = mConfig.inputCfg.buffer.s16;
306             int16_t *out = mConfig.outputCfg.buffer.s16;
307             for (size_t i = 0; i < frameCnt; i++) {
308                 out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
309             }
310         }
311     }
312 }
313 
reset_l()314 void AudioFlinger::EffectModule::reset_l()
315 {
316     if (mStatus != NO_ERROR || mEffectInterface == NULL) {
317         return;
318     }
319     (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL);
320 }
321 
configure()322 status_t AudioFlinger::EffectModule::configure()
323 {
324     status_t status;
325     sp<ThreadBase> thread;
326     uint32_t size;
327     audio_channel_mask_t channelMask;
328 
329     if (mEffectInterface == NULL) {
330         status = NO_INIT;
331         goto exit;
332     }
333 
334     thread = mThread.promote();
335     if (thread == 0) {
336         status = DEAD_OBJECT;
337         goto exit;
338     }
339 
340     // TODO: handle configuration of effects replacing track process
341     channelMask = thread->channelMask();
342     mConfig.outputCfg.channels = channelMask;
343 
344     if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
345         mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
346     } else {
347         mConfig.inputCfg.channels = channelMask;
348         // TODO: Update this logic when multichannel effects are implemented.
349         // For offloaded tracks consider mono output as stereo for proper effect initialization
350         if (channelMask == AUDIO_CHANNEL_OUT_MONO) {
351             mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
352             mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
353             ALOGV("Overriding effect input and output as STEREO");
354         }
355     }
356 
357     mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
358     mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
359     mConfig.inputCfg.samplingRate = thread->sampleRate();
360     mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
361     mConfig.inputCfg.bufferProvider.cookie = NULL;
362     mConfig.inputCfg.bufferProvider.getBuffer = NULL;
363     mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
364     mConfig.outputCfg.bufferProvider.cookie = NULL;
365     mConfig.outputCfg.bufferProvider.getBuffer = NULL;
366     mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
367     mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
368     // Insert effect:
369     // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE,
370     // always overwrites output buffer: input buffer == output buffer
371     // - in other sessions:
372     //      last effect in the chain accumulates in output buffer: input buffer != output buffer
373     //      other effect: overwrites output buffer: input buffer == output buffer
374     // Auxiliary effect:
375     //      accumulates in output buffer: input buffer != output buffer
376     // Therefore: accumulate <=> input buffer != output buffer
377     if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
378         mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
379     } else {
380         mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
381     }
382     mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
383     mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
384     mConfig.inputCfg.buffer.frameCount = thread->frameCount();
385     mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
386 
387     ALOGV("configure() %p thread %p buffer %p framecount %zu",
388             this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
389 
390     status_t cmdStatus;
391     size = sizeof(int);
392     status = (*mEffectInterface)->command(mEffectInterface,
393                                                    EFFECT_CMD_SET_CONFIG,
394                                                    sizeof(effect_config_t),
395                                                    &mConfig,
396                                                    &size,
397                                                    &cmdStatus);
398     if (status == 0) {
399         status = cmdStatus;
400     }
401 
402     if (status == 0 &&
403             (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0)) {
404         uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
405         effect_param_t *p = (effect_param_t *)buf32;
406 
407         p->psize = sizeof(uint32_t);
408         p->vsize = sizeof(uint32_t);
409         size = sizeof(int);
410         *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
411 
412         uint32_t latency = 0;
413         PlaybackThread *pbt = thread->mAudioFlinger->checkPlaybackThread_l(thread->mId);
414         if (pbt != NULL) {
415             latency = pbt->latency_l();
416         }
417 
418         *((int32_t *)p->data + 1)= latency;
419         (*mEffectInterface)->command(mEffectInterface,
420                                      EFFECT_CMD_SET_PARAM,
421                                      sizeof(effect_param_t) + 8,
422                                      &buf32,
423                                      &size,
424                                      &cmdStatus);
425     }
426 
427     mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
428             (1000 * mConfig.outputCfg.buffer.frameCount);
429 
430 exit:
431     mStatus = status;
432     return status;
433 }
434 
init()435 status_t AudioFlinger::EffectModule::init()
436 {
437     Mutex::Autolock _l(mLock);
438     if (mEffectInterface == NULL) {
439         return NO_INIT;
440     }
441     status_t cmdStatus;
442     uint32_t size = sizeof(status_t);
443     status_t status = (*mEffectInterface)->command(mEffectInterface,
444                                                    EFFECT_CMD_INIT,
445                                                    0,
446                                                    NULL,
447                                                    &size,
448                                                    &cmdStatus);
449     if (status == 0) {
450         status = cmdStatus;
451     }
452     return status;
453 }
454 
addEffectToHal_l()455 void AudioFlinger::EffectModule::addEffectToHal_l()
456 {
457     if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
458          (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
459         sp<ThreadBase> thread = mThread.promote();
460         if (thread != 0) {
461             audio_stream_t *stream = thread->stream();
462             if (stream != NULL) {
463                 stream->add_audio_effect(stream, mEffectInterface);
464             }
465         }
466     }
467 }
468 
469 // start() must be called with PlaybackThread::mLock or EffectChain::mLock held
start()470 status_t AudioFlinger::EffectModule::start()
471 {
472     sp<EffectChain> chain;
473     status_t status;
474     {
475         Mutex::Autolock _l(mLock);
476         status = start_l();
477         if (status == NO_ERROR) {
478             chain = mChain.promote();
479         }
480     }
481     if (chain != 0) {
482         chain->resetVolume_l();
483     }
484     return status;
485 }
486 
start_l()487 status_t AudioFlinger::EffectModule::start_l()
488 {
489     if (mEffectInterface == NULL) {
490         return NO_INIT;
491     }
492     if (mStatus != NO_ERROR) {
493         return mStatus;
494     }
495     status_t cmdStatus;
496     uint32_t size = sizeof(status_t);
497     status_t status = (*mEffectInterface)->command(mEffectInterface,
498                                                    EFFECT_CMD_ENABLE,
499                                                    0,
500                                                    NULL,
501                                                    &size,
502                                                    &cmdStatus);
503     if (status == 0) {
504         status = cmdStatus;
505     }
506     if (status == 0) {
507         addEffectToHal_l();
508     }
509     return status;
510 }
511 
stop()512 status_t AudioFlinger::EffectModule::stop()
513 {
514     Mutex::Autolock _l(mLock);
515     return stop_l();
516 }
517 
stop_l()518 status_t AudioFlinger::EffectModule::stop_l()
519 {
520     if (mEffectInterface == NULL) {
521         return NO_INIT;
522     }
523     if (mStatus != NO_ERROR) {
524         return mStatus;
525     }
526     status_t cmdStatus = NO_ERROR;
527     uint32_t size = sizeof(status_t);
528     status_t status = (*mEffectInterface)->command(mEffectInterface,
529                                                    EFFECT_CMD_DISABLE,
530                                                    0,
531                                                    NULL,
532                                                    &size,
533                                                    &cmdStatus);
534     if (status == NO_ERROR) {
535         status = cmdStatus;
536     }
537     if (status == NO_ERROR) {
538         status = remove_effect_from_hal_l();
539     }
540     return status;
541 }
542 
remove_effect_from_hal_l()543 status_t AudioFlinger::EffectModule::remove_effect_from_hal_l()
544 {
545     if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
546              (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
547         sp<ThreadBase> thread = mThread.promote();
548         if (thread != 0) {
549             audio_stream_t *stream = thread->stream();
550             if (stream != NULL) {
551                 stream->remove_audio_effect(stream, mEffectInterface);
552             }
553         }
554     }
555     return NO_ERROR;
556 }
557 
558 // round up delta valid if value and divisor are positive.
559 template <typename T>
roundUpDelta(const T & value,const T & divisor)560 static T roundUpDelta(const T &value, const T &divisor) {
561     T remainder = value % divisor;
562     return remainder == 0 ? 0 : divisor - remainder;
563 }
564 
command(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)565 status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
566                                              uint32_t cmdSize,
567                                              void *pCmdData,
568                                              uint32_t *replySize,
569                                              void *pReplyData)
570 {
571     Mutex::Autolock _l(mLock);
572     ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
573 
574     if (mState == DESTROYED || mEffectInterface == NULL) {
575         return NO_INIT;
576     }
577     if (mStatus != NO_ERROR) {
578         return mStatus;
579     }
580     if (cmdCode == EFFECT_CMD_GET_PARAM &&
581             (*replySize < sizeof(effect_param_t) ||
582                     ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t))) {
583         android_errorWriteLog(0x534e4554, "29251553");
584         return -EINVAL;
585     }
586     if ((cmdCode == EFFECT_CMD_SET_PARAM
587             || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) &&  // DEFERRED not generally used
588         (sizeof(effect_param_t) > cmdSize
589             || ((effect_param_t *)pCmdData)->psize > cmdSize
590                                                      - sizeof(effect_param_t)
591             || ((effect_param_t *)pCmdData)->vsize > cmdSize
592                                                      - sizeof(effect_param_t)
593                                                      - ((effect_param_t *)pCmdData)->psize
594             || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) >
595                                                      cmdSize
596                                                      - sizeof(effect_param_t)
597                                                      - ((effect_param_t *)pCmdData)->psize
598                                                      - ((effect_param_t *)pCmdData)->vsize)) {
599         android_errorWriteLog(0x534e4554, "30204301");
600         return -EINVAL;
601     }
602     status_t status = (*mEffectInterface)->command(mEffectInterface,
603                                                    cmdCode,
604                                                    cmdSize,
605                                                    pCmdData,
606                                                    replySize,
607                                                    pReplyData);
608     if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
609         uint32_t size = (replySize == NULL) ? 0 : *replySize;
610         for (size_t i = 1; i < mHandles.size(); i++) {
611             EffectHandle *h = mHandles[i];
612             if (h != NULL && !h->destroyed_l()) {
613                 h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
614             }
615         }
616     }
617     return status;
618 }
619 
setEnabled(bool enabled)620 status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
621 {
622     Mutex::Autolock _l(mLock);
623     return setEnabled_l(enabled);
624 }
625 
626 // must be called with EffectModule::mLock held
setEnabled_l(bool enabled)627 status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
628 {
629 
630     ALOGV("setEnabled %p enabled %d", this, enabled);
631 
632     if (enabled != isEnabled()) {
633         status_t status = AudioSystem::setEffectEnabled(mId, enabled);
634         if (enabled && status != NO_ERROR) {
635             return status;
636         }
637 
638         switch (mState) {
639         // going from disabled to enabled
640         case IDLE:
641             mState = STARTING;
642             break;
643         case STOPPED:
644             mState = RESTART;
645             break;
646         case STOPPING:
647             mState = ACTIVE;
648             break;
649 
650         // going from enabled to disabled
651         case RESTART:
652             mState = STOPPED;
653             break;
654         case STARTING:
655             mState = IDLE;
656             break;
657         case ACTIVE:
658             mState = STOPPING;
659             break;
660         case DESTROYED:
661             return NO_ERROR; // simply ignore as we are being destroyed
662         }
663         for (size_t i = 1; i < mHandles.size(); i++) {
664             EffectHandle *h = mHandles[i];
665             if (h != NULL && !h->destroyed_l()) {
666                 h->setEnabled(enabled);
667             }
668         }
669     }
670     return NO_ERROR;
671 }
672 
isEnabled() const673 bool AudioFlinger::EffectModule::isEnabled() const
674 {
675     switch (mState) {
676     case RESTART:
677     case STARTING:
678     case ACTIVE:
679         return true;
680     case IDLE:
681     case STOPPING:
682     case STOPPED:
683     case DESTROYED:
684     default:
685         return false;
686     }
687 }
688 
isProcessEnabled() const689 bool AudioFlinger::EffectModule::isProcessEnabled() const
690 {
691     if (mStatus != NO_ERROR) {
692         return false;
693     }
694 
695     switch (mState) {
696     case RESTART:
697     case ACTIVE:
698     case STOPPING:
699     case STOPPED:
700         return true;
701     case IDLE:
702     case STARTING:
703     case DESTROYED:
704     default:
705         return false;
706     }
707 }
708 
setVolume(uint32_t * left,uint32_t * right,bool controller)709 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
710 {
711     Mutex::Autolock _l(mLock);
712     if (mStatus != NO_ERROR) {
713         return mStatus;
714     }
715     status_t status = NO_ERROR;
716     // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
717     // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
718     if (isProcessEnabled() &&
719             ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
720             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
721         uint32_t volume[2];
722         uint32_t *pVolume = NULL;
723         uint32_t size = sizeof(volume);
724         volume[0] = *left;
725         volume[1] = *right;
726         if (controller) {
727             pVolume = volume;
728         }
729         status = (*mEffectInterface)->command(mEffectInterface,
730                                               EFFECT_CMD_SET_VOLUME,
731                                               size,
732                                               volume,
733                                               &size,
734                                               pVolume);
735         if (controller && status == NO_ERROR && size == sizeof(volume)) {
736             *left = volume[0];
737             *right = volume[1];
738         }
739     }
740     return status;
741 }
742 
setDevice(audio_devices_t device)743 status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
744 {
745     if (device == AUDIO_DEVICE_NONE) {
746         return NO_ERROR;
747     }
748 
749     Mutex::Autolock _l(mLock);
750     if (mStatus != NO_ERROR) {
751         return mStatus;
752     }
753     status_t status = NO_ERROR;
754     if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
755         status_t cmdStatus;
756         uint32_t size = sizeof(status_t);
757         uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
758                             EFFECT_CMD_SET_INPUT_DEVICE;
759         status = (*mEffectInterface)->command(mEffectInterface,
760                                               cmd,
761                                               sizeof(uint32_t),
762                                               &device,
763                                               &size,
764                                               &cmdStatus);
765     }
766     return status;
767 }
768 
setMode(audio_mode_t mode)769 status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
770 {
771     Mutex::Autolock _l(mLock);
772     if (mStatus != NO_ERROR) {
773         return mStatus;
774     }
775     status_t status = NO_ERROR;
776     if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
777         status_t cmdStatus;
778         uint32_t size = sizeof(status_t);
779         status = (*mEffectInterface)->command(mEffectInterface,
780                                               EFFECT_CMD_SET_AUDIO_MODE,
781                                               sizeof(audio_mode_t),
782                                               &mode,
783                                               &size,
784                                               &cmdStatus);
785         if (status == NO_ERROR) {
786             status = cmdStatus;
787         }
788     }
789     return status;
790 }
791 
setAudioSource(audio_source_t source)792 status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
793 {
794     Mutex::Autolock _l(mLock);
795     if (mStatus != NO_ERROR) {
796         return mStatus;
797     }
798     status_t status = NO_ERROR;
799     if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
800         uint32_t size = 0;
801         status = (*mEffectInterface)->command(mEffectInterface,
802                                               EFFECT_CMD_SET_AUDIO_SOURCE,
803                                               sizeof(audio_source_t),
804                                               &source,
805                                               &size,
806                                               NULL);
807     }
808     return status;
809 }
810 
setSuspended(bool suspended)811 void AudioFlinger::EffectModule::setSuspended(bool suspended)
812 {
813     Mutex::Autolock _l(mLock);
814     mSuspended = suspended;
815 }
816 
suspended() const817 bool AudioFlinger::EffectModule::suspended() const
818 {
819     Mutex::Autolock _l(mLock);
820     return mSuspended;
821 }
822 
purgeHandles()823 bool AudioFlinger::EffectModule::purgeHandles()
824 {
825     bool enabled = false;
826     Mutex::Autolock _l(mLock);
827     for (size_t i = 0; i < mHandles.size(); i++) {
828         EffectHandle *handle = mHandles[i];
829         if (handle != NULL && !handle->destroyed_l()) {
830             handle->effect().clear();
831             if (handle->hasControl()) {
832                 enabled = handle->enabled();
833             }
834         }
835     }
836     return enabled;
837 }
838 
setOffloaded(bool offloaded,audio_io_handle_t io)839 status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
840 {
841     Mutex::Autolock _l(mLock);
842     if (mStatus != NO_ERROR) {
843         return mStatus;
844     }
845     status_t status = NO_ERROR;
846     if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) {
847         status_t cmdStatus;
848         uint32_t size = sizeof(status_t);
849         effect_offload_param_t cmd;
850 
851         cmd.isOffload = offloaded;
852         cmd.ioHandle = io;
853         status = (*mEffectInterface)->command(mEffectInterface,
854                                               EFFECT_CMD_OFFLOAD,
855                                               sizeof(effect_offload_param_t),
856                                               &cmd,
857                                               &size,
858                                               &cmdStatus);
859         if (status == NO_ERROR) {
860             status = cmdStatus;
861         }
862         mOffloaded = (status == NO_ERROR) ? offloaded : false;
863     } else {
864         if (offloaded) {
865             status = INVALID_OPERATION;
866         }
867         mOffloaded = false;
868     }
869     ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status);
870     return status;
871 }
872 
isOffloaded() const873 bool AudioFlinger::EffectModule::isOffloaded() const
874 {
875     Mutex::Autolock _l(mLock);
876     return mOffloaded;
877 }
878 
effectFlagsToString(uint32_t flags)879 String8 effectFlagsToString(uint32_t flags) {
880     String8 s;
881 
882     s.append("conn. mode: ");
883     switch (flags & EFFECT_FLAG_TYPE_MASK) {
884     case EFFECT_FLAG_TYPE_INSERT: s.append("insert"); break;
885     case EFFECT_FLAG_TYPE_AUXILIARY: s.append("auxiliary"); break;
886     case EFFECT_FLAG_TYPE_REPLACE: s.append("replace"); break;
887     case EFFECT_FLAG_TYPE_PRE_PROC: s.append("preproc"); break;
888     case EFFECT_FLAG_TYPE_POST_PROC: s.append("postproc"); break;
889     default: s.append("unknown/reserved"); break;
890     }
891     s.append(", ");
892 
893     s.append("insert pref: ");
894     switch (flags & EFFECT_FLAG_INSERT_MASK) {
895     case EFFECT_FLAG_INSERT_ANY: s.append("any"); break;
896     case EFFECT_FLAG_INSERT_FIRST: s.append("first"); break;
897     case EFFECT_FLAG_INSERT_LAST: s.append("last"); break;
898     case EFFECT_FLAG_INSERT_EXCLUSIVE: s.append("exclusive"); break;
899     default: s.append("unknown/reserved"); break;
900     }
901     s.append(", ");
902 
903     s.append("volume mgmt: ");
904     switch (flags & EFFECT_FLAG_VOLUME_MASK) {
905     case EFFECT_FLAG_VOLUME_NONE: s.append("none"); break;
906     case EFFECT_FLAG_VOLUME_CTRL: s.append("implements control"); break;
907     case EFFECT_FLAG_VOLUME_IND: s.append("requires indication"); break;
908     default: s.append("unknown/reserved"); break;
909     }
910     s.append(", ");
911 
912     uint32_t devind = flags & EFFECT_FLAG_DEVICE_MASK;
913     if (devind) {
914         s.append("device indication: ");
915         switch (devind) {
916         case EFFECT_FLAG_DEVICE_IND: s.append("requires updates"); break;
917         default: s.append("unknown/reserved"); break;
918         }
919         s.append(", ");
920     }
921 
922     s.append("input mode: ");
923     switch (flags & EFFECT_FLAG_INPUT_MASK) {
924     case EFFECT_FLAG_INPUT_DIRECT: s.append("direct"); break;
925     case EFFECT_FLAG_INPUT_PROVIDER: s.append("provider"); break;
926     case EFFECT_FLAG_INPUT_BOTH: s.append("direct+provider"); break;
927     default: s.append("not set"); break;
928     }
929     s.append(", ");
930 
931     s.append("output mode: ");
932     switch (flags & EFFECT_FLAG_OUTPUT_MASK) {
933     case EFFECT_FLAG_OUTPUT_DIRECT: s.append("direct"); break;
934     case EFFECT_FLAG_OUTPUT_PROVIDER: s.append("provider"); break;
935     case EFFECT_FLAG_OUTPUT_BOTH: s.append("direct+provider"); break;
936     default: s.append("not set"); break;
937     }
938     s.append(", ");
939 
940     uint32_t accel = flags & EFFECT_FLAG_HW_ACC_MASK;
941     if (accel) {
942         s.append("hardware acceleration: ");
943         switch (accel) {
944         case EFFECT_FLAG_HW_ACC_SIMPLE: s.append("non-tunneled"); break;
945         case EFFECT_FLAG_HW_ACC_TUNNEL: s.append("tunneled"); break;
946         default: s.append("unknown/reserved"); break;
947         }
948         s.append(", ");
949     }
950 
951     uint32_t modeind = flags & EFFECT_FLAG_AUDIO_MODE_MASK;
952     if (modeind) {
953         s.append("mode indication: ");
954         switch (modeind) {
955         case EFFECT_FLAG_AUDIO_MODE_IND: s.append("required"); break;
956         default: s.append("unknown/reserved"); break;
957         }
958         s.append(", ");
959     }
960 
961     uint32_t srcind = flags & EFFECT_FLAG_AUDIO_SOURCE_MASK;
962     if (srcind) {
963         s.append("source indication: ");
964         switch (srcind) {
965         case EFFECT_FLAG_AUDIO_SOURCE_IND: s.append("required"); break;
966         default: s.append("unknown/reserved"); break;
967         }
968         s.append(", ");
969     }
970 
971     if (flags & EFFECT_FLAG_OFFLOAD_MASK) {
972         s.append("offloadable, ");
973     }
974 
975     int len = s.length();
976     if (s.length() > 2) {
977         (void) s.lockBuffer(len);
978         s.unlockBuffer(len - 2);
979     }
980     return s;
981 }
982 
983 
dump(int fd,const Vector<String16> & args __unused)984 void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args __unused)
985 {
986     const size_t SIZE = 256;
987     char buffer[SIZE];
988     String8 result;
989 
990     snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
991     result.append(buffer);
992 
993     bool locked = AudioFlinger::dumpTryLock(mLock);
994     // failed to lock - AudioFlinger is probably deadlocked
995     if (!locked) {
996         result.append("\t\tCould not lock Fx mutex:\n");
997     }
998 
999     result.append("\t\tSession Status State Engine:\n");
1000     snprintf(buffer, SIZE, "\t\t%05d   %03d    %03d   %p\n",
1001             mSessionId, mStatus, mState, mEffectInterface);
1002     result.append(buffer);
1003 
1004     result.append("\t\tDescriptor:\n");
1005     snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
1006             mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
1007             mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],
1008                     mDescriptor.uuid.node[2],
1009             mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
1010     result.append(buffer);
1011     snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
1012                 mDescriptor.type.timeLow, mDescriptor.type.timeMid,
1013                     mDescriptor.type.timeHiAndVersion,
1014                 mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],
1015                     mDescriptor.type.node[2],
1016                 mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
1017     result.append(buffer);
1018     snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X (%s)\n",
1019             mDescriptor.apiVersion,
1020             mDescriptor.flags,
1021             effectFlagsToString(mDescriptor.flags).string());
1022     result.append(buffer);
1023     snprintf(buffer, SIZE, "\t\t- name: %s\n",
1024             mDescriptor.name);
1025     result.append(buffer);
1026     snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
1027             mDescriptor.implementor);
1028     result.append(buffer);
1029 
1030     result.append("\t\t- Input configuration:\n");
1031     result.append("\t\t\tFrames  Smp rate Channels Format Buffer\n");
1032     snprintf(buffer, SIZE, "\t\t\t%05zu   %05d    %08x %6d (%s) %p\n",
1033             mConfig.inputCfg.buffer.frameCount,
1034             mConfig.inputCfg.samplingRate,
1035             mConfig.inputCfg.channels,
1036             mConfig.inputCfg.format,
1037             formatToString((audio_format_t)mConfig.inputCfg.format),
1038             mConfig.inputCfg.buffer.raw);
1039     result.append(buffer);
1040 
1041     result.append("\t\t- Output configuration:\n");
1042     result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
1043     snprintf(buffer, SIZE, "\t\t\t%p %05zu   %05d    %08x %d (%s)\n",
1044             mConfig.outputCfg.buffer.raw,
1045             mConfig.outputCfg.buffer.frameCount,
1046             mConfig.outputCfg.samplingRate,
1047             mConfig.outputCfg.channels,
1048             mConfig.outputCfg.format,
1049             formatToString((audio_format_t)mConfig.outputCfg.format));
1050     result.append(buffer);
1051 
1052     snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size());
1053     result.append(buffer);
1054     result.append("\t\t\t  Pid Priority Ctrl Locked client server\n");
1055     for (size_t i = 0; i < mHandles.size(); ++i) {
1056         EffectHandle *handle = mHandles[i];
1057         if (handle != NULL && !handle->destroyed_l()) {
1058             handle->dumpToBuffer(buffer, SIZE);
1059             result.append(buffer);
1060         }
1061     }
1062 
1063     write(fd, result.string(), result.length());
1064 
1065     if (locked) {
1066         mLock.unlock();
1067     }
1068 }
1069 
1070 // ----------------------------------------------------------------------------
1071 //  EffectHandle implementation
1072 // ----------------------------------------------------------------------------
1073 
1074 #undef LOG_TAG
1075 #define LOG_TAG "AudioFlinger::EffectHandle"
1076 
EffectHandle(const sp<EffectModule> & effect,const sp<AudioFlinger::Client> & client,const sp<IEffectClient> & effectClient,int32_t priority)1077 AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
1078                                         const sp<AudioFlinger::Client>& client,
1079                                         const sp<IEffectClient>& effectClient,
1080                                         int32_t priority)
1081     : BnEffect(),
1082     mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
1083     mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
1084 {
1085     ALOGV("constructor %p", this);
1086 
1087     if (client == 0) {
1088         return;
1089     }
1090     int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
1091     mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
1092     if (mCblkMemory == 0 ||
1093             (mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer())) == NULL) {
1094         ALOGE("not enough memory for Effect size=%zu", EFFECT_PARAM_BUFFER_SIZE +
1095                 sizeof(effect_param_cblk_t));
1096         mCblkMemory.clear();
1097         return;
1098     }
1099     new(mCblk) effect_param_cblk_t();
1100     mBuffer = (uint8_t *)mCblk + bufOffset;
1101 }
1102 
~EffectHandle()1103 AudioFlinger::EffectHandle::~EffectHandle()
1104 {
1105     ALOGV("Destructor %p", this);
1106 
1107     if (mEffect == 0) {
1108         mDestroyed = true;
1109         return;
1110     }
1111     mEffect->lock();
1112     mDestroyed = true;
1113     mEffect->unlock();
1114     disconnect(false);
1115 }
1116 
initCheck()1117 status_t AudioFlinger::EffectHandle::initCheck()
1118 {
1119     return mClient == 0 || mCblkMemory != 0 ? OK : NO_MEMORY;
1120 }
1121 
enable()1122 status_t AudioFlinger::EffectHandle::enable()
1123 {
1124     ALOGV("enable %p", this);
1125     if (!mHasControl) {
1126         return INVALID_OPERATION;
1127     }
1128     if (mEffect == 0) {
1129         return DEAD_OBJECT;
1130     }
1131 
1132     if (mEnabled) {
1133         return NO_ERROR;
1134     }
1135 
1136     mEnabled = true;
1137 
1138     sp<ThreadBase> thread = mEffect->thread().promote();
1139     if (thread != 0) {
1140         thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
1141     }
1142 
1143     // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
1144     if (mEffect->suspended()) {
1145         return NO_ERROR;
1146     }
1147 
1148     status_t status = mEffect->setEnabled(true);
1149     if (status != NO_ERROR) {
1150         if (thread != 0) {
1151             thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
1152         }
1153         mEnabled = false;
1154     } else {
1155         if (thread != 0) {
1156             if (thread->type() == ThreadBase::OFFLOAD) {
1157                 PlaybackThread *t = (PlaybackThread *)thread.get();
1158                 Mutex::Autolock _l(t->mLock);
1159                 t->broadcast_l();
1160             }
1161             if (!mEffect->isOffloadable()) {
1162                 if (thread->type() == ThreadBase::OFFLOAD) {
1163                     PlaybackThread *t = (PlaybackThread *)thread.get();
1164                     t->invalidateTracks(AUDIO_STREAM_MUSIC);
1165                 }
1166                 if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
1167                     thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
1168                 }
1169             }
1170         }
1171     }
1172     return status;
1173 }
1174 
disable()1175 status_t AudioFlinger::EffectHandle::disable()
1176 {
1177     ALOGV("disable %p", this);
1178     if (!mHasControl) {
1179         return INVALID_OPERATION;
1180     }
1181     if (mEffect == 0) {
1182         return DEAD_OBJECT;
1183     }
1184 
1185     if (!mEnabled) {
1186         return NO_ERROR;
1187     }
1188     mEnabled = false;
1189 
1190     if (mEffect->suspended()) {
1191         return NO_ERROR;
1192     }
1193 
1194     status_t status = mEffect->setEnabled(false);
1195 
1196     sp<ThreadBase> thread = mEffect->thread().promote();
1197     if (thread != 0) {
1198         thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
1199         if (thread->type() == ThreadBase::OFFLOAD) {
1200             PlaybackThread *t = (PlaybackThread *)thread.get();
1201             Mutex::Autolock _l(t->mLock);
1202             t->broadcast_l();
1203         }
1204     }
1205 
1206     return status;
1207 }
1208 
disconnect()1209 void AudioFlinger::EffectHandle::disconnect()
1210 {
1211     disconnect(true);
1212 }
1213 
disconnect(bool unpinIfLast)1214 void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
1215 {
1216     ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false");
1217     if (mEffect == 0) {
1218         return;
1219     }
1220     // restore suspended effects if the disconnected handle was enabled and the last one.
1221     if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
1222         sp<ThreadBase> thread = mEffect->thread().promote();
1223         if (thread != 0) {
1224             thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
1225         }
1226     }
1227 
1228     // release sp on module => module destructor can be called now
1229     mEffect.clear();
1230     if (mClient != 0) {
1231         if (mCblk != NULL) {
1232             // unlike ~TrackBase(), mCblk is never a local new, so don't delete
1233             mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
1234         }
1235         mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
1236         // Client destructor must run with AudioFlinger client mutex locked
1237         Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
1238         mClient.clear();
1239     }
1240 }
1241 
command(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)1242 status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
1243                                              uint32_t cmdSize,
1244                                              void *pCmdData,
1245                                              uint32_t *replySize,
1246                                              void *pReplyData)
1247 {
1248     ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
1249             cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
1250 
1251     // only get parameter command is permitted for applications not controlling the effect
1252     if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
1253         return INVALID_OPERATION;
1254     }
1255     if (mEffect == 0) {
1256         return DEAD_OBJECT;
1257     }
1258     if (mClient == 0) {
1259         return INVALID_OPERATION;
1260     }
1261 
1262     // handle commands that are not forwarded transparently to effect engine
1263     if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
1264         // No need to trylock() here as this function is executed in the binder thread serving a
1265         // particular client process:  no risk to block the whole media server process or mixer
1266         // threads if we are stuck here
1267         Mutex::Autolock _l(mCblk->lock);
1268         if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
1269             mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
1270             mCblk->serverIndex = 0;
1271             mCblk->clientIndex = 0;
1272             return BAD_VALUE;
1273         }
1274         status_t status = NO_ERROR;
1275         while (mCblk->serverIndex < mCblk->clientIndex) {
1276             int reply;
1277             uint32_t rsize = sizeof(int);
1278             int *p = (int *)(mBuffer + mCblk->serverIndex);
1279             int size = *p++;
1280             if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
1281                 ALOGW("command(): invalid parameter block size");
1282                 break;
1283             }
1284             effect_param_t *param = (effect_param_t *)p;
1285             if (param->psize == 0 || param->vsize == 0) {
1286                 ALOGW("command(): null parameter or value size");
1287                 mCblk->serverIndex += size;
1288                 continue;
1289             }
1290             uint32_t psize = sizeof(effect_param_t) +
1291                              ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1292                              param->vsize;
1293             status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM,
1294                                             psize,
1295                                             p,
1296                                             &rsize,
1297                                             &reply);
1298             // stop at first error encountered
1299             if (ret != NO_ERROR) {
1300                 status = ret;
1301                 *(int *)pReplyData = reply;
1302                 break;
1303             } else if (reply != NO_ERROR) {
1304                 *(int *)pReplyData = reply;
1305                 break;
1306             }
1307             mCblk->serverIndex += size;
1308         }
1309         mCblk->serverIndex = 0;
1310         mCblk->clientIndex = 0;
1311         return status;
1312     } else if (cmdCode == EFFECT_CMD_ENABLE) {
1313         *(int *)pReplyData = NO_ERROR;
1314         return enable();
1315     } else if (cmdCode == EFFECT_CMD_DISABLE) {
1316         *(int *)pReplyData = NO_ERROR;
1317         return disable();
1318     }
1319 
1320     return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1321 }
1322 
setControl(bool hasControl,bool signal,bool enabled)1323 void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
1324 {
1325     ALOGV("setControl %p control %d", this, hasControl);
1326 
1327     mHasControl = hasControl;
1328     mEnabled = enabled;
1329 
1330     if (signal && mEffectClient != 0) {
1331         mEffectClient->controlStatusChanged(hasControl);
1332     }
1333 }
1334 
commandExecuted(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t replySize,void * pReplyData)1335 void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
1336                                                  uint32_t cmdSize,
1337                                                  void *pCmdData,
1338                                                  uint32_t replySize,
1339                                                  void *pReplyData)
1340 {
1341     if (mEffectClient != 0) {
1342         mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1343     }
1344 }
1345 
1346 
1347 
setEnabled(bool enabled)1348 void AudioFlinger::EffectHandle::setEnabled(bool enabled)
1349 {
1350     if (mEffectClient != 0) {
1351         mEffectClient->enableStatusChanged(enabled);
1352     }
1353 }
1354 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1355 status_t AudioFlinger::EffectHandle::onTransact(
1356     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1357 {
1358     return BnEffect::onTransact(code, data, reply, flags);
1359 }
1360 
1361 
dumpToBuffer(char * buffer,size_t size)1362 void AudioFlinger::EffectHandle::dumpToBuffer(char* buffer, size_t size)
1363 {
1364     bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
1365 
1366     snprintf(buffer, size, "\t\t\t%5d    %5d  %3s    %3s  %5u  %5u\n",
1367             (mClient == 0) ? getpid_cached : mClient->pid(),
1368             mPriority,
1369             mHasControl ? "yes" : "no",
1370             locked ? "yes" : "no",
1371             mCblk ? mCblk->clientIndex : 0,
1372             mCblk ? mCblk->serverIndex : 0
1373             );
1374 
1375     if (locked) {
1376         mCblk->lock.unlock();
1377     }
1378 }
1379 
1380 #undef LOG_TAG
1381 #define LOG_TAG "AudioFlinger::EffectChain"
1382 
EffectChain(ThreadBase * thread,audio_session_t sessionId)1383 AudioFlinger::EffectChain::EffectChain(ThreadBase *thread,
1384                                         audio_session_t sessionId)
1385     : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
1386       mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
1387       mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
1388 {
1389     mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
1390     if (thread == NULL) {
1391         return;
1392     }
1393     mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
1394                                     thread->frameCount();
1395 }
1396 
~EffectChain()1397 AudioFlinger::EffectChain::~EffectChain()
1398 {
1399     if (mOwnInBuffer) {
1400         delete mInBuffer;
1401     }
1402 
1403 }
1404 
1405 // getEffectFromDesc_l() must be called with ThreadBase::mLock held
getEffectFromDesc_l(effect_descriptor_t * descriptor)1406 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
1407         effect_descriptor_t *descriptor)
1408 {
1409     size_t size = mEffects.size();
1410 
1411     for (size_t i = 0; i < size; i++) {
1412         if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
1413             return mEffects[i];
1414         }
1415     }
1416     return 0;
1417 }
1418 
1419 // getEffectFromId_l() must be called with ThreadBase::mLock held
getEffectFromId_l(int id)1420 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
1421 {
1422     size_t size = mEffects.size();
1423 
1424     for (size_t i = 0; i < size; i++) {
1425         // by convention, return first effect if id provided is 0 (0 is never a valid id)
1426         if (id == 0 || mEffects[i]->id() == id) {
1427             return mEffects[i];
1428         }
1429     }
1430     return 0;
1431 }
1432 
1433 // getEffectFromType_l() must be called with ThreadBase::mLock held
getEffectFromType_l(const effect_uuid_t * type)1434 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
1435         const effect_uuid_t *type)
1436 {
1437     size_t size = mEffects.size();
1438 
1439     for (size_t i = 0; i < size; i++) {
1440         if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
1441             return mEffects[i];
1442         }
1443     }
1444     return 0;
1445 }
1446 
clearInputBuffer()1447 void AudioFlinger::EffectChain::clearInputBuffer()
1448 {
1449     Mutex::Autolock _l(mLock);
1450     sp<ThreadBase> thread = mThread.promote();
1451     if (thread == 0) {
1452         ALOGW("clearInputBuffer(): cannot promote mixer thread");
1453         return;
1454     }
1455     clearInputBuffer_l(thread);
1456 }
1457 
1458 // Must be called with EffectChain::mLock locked
clearInputBuffer_l(sp<ThreadBase> thread)1459 void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
1460 {
1461     // TODO: This will change in the future, depending on multichannel
1462     // and sample format changes for effects.
1463     // Currently effects processing is only available for stereo, AUDIO_FORMAT_PCM_16_BIT
1464     // (4 bytes frame size)
1465     const size_t frameSize =
1466             audio_bytes_per_sample(AUDIO_FORMAT_PCM_16_BIT) * min(FCC_2, thread->channelCount());
1467     memset(mInBuffer, 0, thread->frameCount() * frameSize);
1468 }
1469 
1470 // Must be called with EffectChain::mLock locked
process_l()1471 void AudioFlinger::EffectChain::process_l()
1472 {
1473     sp<ThreadBase> thread = mThread.promote();
1474     if (thread == 0) {
1475         ALOGW("process_l(): cannot promote mixer thread");
1476         return;
1477     }
1478     bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
1479             (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
1480     // never process effects when:
1481     // - on an OFFLOAD thread
1482     // - no more tracks are on the session and the effect tail has been rendered
1483     bool doProcess = (thread->type() != ThreadBase::OFFLOAD);
1484     if (!isGlobalSession) {
1485         bool tracksOnSession = (trackCnt() != 0);
1486 
1487         if (!tracksOnSession && mTailBufferCount == 0) {
1488             doProcess = false;
1489         }
1490 
1491         if (activeTrackCnt() == 0) {
1492             // if no track is active and the effect tail has not been rendered,
1493             // the input buffer must be cleared here as the mixer process will not do it
1494             if (tracksOnSession || mTailBufferCount > 0) {
1495                 clearInputBuffer_l(thread);
1496                 if (mTailBufferCount > 0) {
1497                     mTailBufferCount--;
1498                 }
1499             }
1500         }
1501     }
1502 
1503     size_t size = mEffects.size();
1504     if (doProcess) {
1505         for (size_t i = 0; i < size; i++) {
1506             mEffects[i]->process();
1507         }
1508     }
1509     bool doResetVolume = false;
1510     for (size_t i = 0; i < size; i++) {
1511         doResetVolume = mEffects[i]->updateState() || doResetVolume;
1512     }
1513     if (doResetVolume) {
1514         resetVolume_l();
1515     }
1516 }
1517 
1518 // addEffect_l() must be called with PlaybackThread::mLock held
addEffect_l(const sp<EffectModule> & effect)1519 status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
1520 {
1521     effect_descriptor_t desc = effect->desc();
1522     uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
1523 
1524     Mutex::Autolock _l(mLock);
1525     effect->setChain(this);
1526     sp<ThreadBase> thread = mThread.promote();
1527     if (thread == 0) {
1528         return NO_INIT;
1529     }
1530     effect->setThread(thread);
1531 
1532     if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
1533         // Auxiliary effects are inserted at the beginning of mEffects vector as
1534         // they are processed first and accumulated in chain input buffer
1535         mEffects.insertAt(effect, 0);
1536 
1537         // the input buffer for auxiliary effect contains mono samples in
1538         // 32 bit format. This is to avoid saturation in AudoMixer
1539         // accumulation stage. Saturation is done in EffectModule::process() before
1540         // calling the process in effect engine
1541         size_t numSamples = thread->frameCount();
1542         int32_t *buffer = new int32_t[numSamples];
1543         memset(buffer, 0, numSamples * sizeof(int32_t));
1544         effect->setInBuffer((int16_t *)buffer);
1545         // auxiliary effects output samples to chain input buffer for further processing
1546         // by insert effects
1547         effect->setOutBuffer(mInBuffer);
1548     } else {
1549         // Insert effects are inserted at the end of mEffects vector as they are processed
1550         //  after track and auxiliary effects.
1551         // Insert effect order as a function of indicated preference:
1552         //  if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
1553         //  another effect is present
1554         //  else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
1555         //  last effect claiming first position
1556         //  else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
1557         //  first effect claiming last position
1558         //  else if EFFECT_FLAG_INSERT_ANY insert after first or before last
1559         // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
1560         // already present
1561 
1562         size_t size = mEffects.size();
1563         size_t idx_insert = size;
1564         ssize_t idx_insert_first = -1;
1565         ssize_t idx_insert_last = -1;
1566 
1567         for (size_t i = 0; i < size; i++) {
1568             effect_descriptor_t d = mEffects[i]->desc();
1569             uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
1570             uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
1571             if (iMode == EFFECT_FLAG_TYPE_INSERT) {
1572                 // check invalid effect chaining combinations
1573                 if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
1574                     iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
1575                     ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s",
1576                             desc.name, d.name);
1577                     return INVALID_OPERATION;
1578                 }
1579                 // remember position of first insert effect and by default
1580                 // select this as insert position for new effect
1581                 if (idx_insert == size) {
1582                     idx_insert = i;
1583                 }
1584                 // remember position of last insert effect claiming
1585                 // first position
1586                 if (iPref == EFFECT_FLAG_INSERT_FIRST) {
1587                     idx_insert_first = i;
1588                 }
1589                 // remember position of first insert effect claiming
1590                 // last position
1591                 if (iPref == EFFECT_FLAG_INSERT_LAST &&
1592                     idx_insert_last == -1) {
1593                     idx_insert_last = i;
1594                 }
1595             }
1596         }
1597 
1598         // modify idx_insert from first position if needed
1599         if (insertPref == EFFECT_FLAG_INSERT_LAST) {
1600             if (idx_insert_last != -1) {
1601                 idx_insert = idx_insert_last;
1602             } else {
1603                 idx_insert = size;
1604             }
1605         } else {
1606             if (idx_insert_first != -1) {
1607                 idx_insert = idx_insert_first + 1;
1608             }
1609         }
1610 
1611         // always read samples from chain input buffer
1612         effect->setInBuffer(mInBuffer);
1613 
1614         // if last effect in the chain, output samples to chain
1615         // output buffer, otherwise to chain input buffer
1616         if (idx_insert == size) {
1617             if (idx_insert != 0) {
1618                 mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
1619                 mEffects[idx_insert-1]->configure();
1620             }
1621             effect->setOutBuffer(mOutBuffer);
1622         } else {
1623             effect->setOutBuffer(mInBuffer);
1624         }
1625         mEffects.insertAt(effect, idx_insert);
1626 
1627         ALOGV("addEffect_l() effect %p, added in chain %p at rank %zu", effect.get(), this,
1628                 idx_insert);
1629     }
1630     effect->configure();
1631     return NO_ERROR;
1632 }
1633 
1634 // removeEffect_l() must be called with PlaybackThread::mLock held
removeEffect_l(const sp<EffectModule> & effect)1635 size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
1636 {
1637     Mutex::Autolock _l(mLock);
1638     size_t size = mEffects.size();
1639     uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
1640 
1641     for (size_t i = 0; i < size; i++) {
1642         if (effect == mEffects[i]) {
1643             // calling stop here will remove pre-processing effect from the audio HAL.
1644             // This is safe as we hold the EffectChain mutex which guarantees that we are not in
1645             // the middle of a read from audio HAL
1646             if (mEffects[i]->state() == EffectModule::ACTIVE ||
1647                     mEffects[i]->state() == EffectModule::STOPPING) {
1648                 mEffects[i]->stop();
1649             }
1650             if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
1651                 delete[] effect->inBuffer();
1652             } else {
1653                 if (i == size - 1 && i != 0) {
1654                     mEffects[i - 1]->setOutBuffer(mOutBuffer);
1655                     mEffects[i - 1]->configure();
1656                 }
1657             }
1658             mEffects.removeAt(i);
1659             ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %zu", effect.get(),
1660                     this, i);
1661             break;
1662         }
1663     }
1664 
1665     return mEffects.size();
1666 }
1667 
1668 // setDevice_l() must be called with PlaybackThread::mLock held
setDevice_l(audio_devices_t device)1669 void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
1670 {
1671     size_t size = mEffects.size();
1672     for (size_t i = 0; i < size; i++) {
1673         mEffects[i]->setDevice(device);
1674     }
1675 }
1676 
1677 // setMode_l() must be called with PlaybackThread::mLock held
setMode_l(audio_mode_t mode)1678 void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode)
1679 {
1680     size_t size = mEffects.size();
1681     for (size_t i = 0; i < size; i++) {
1682         mEffects[i]->setMode(mode);
1683     }
1684 }
1685 
1686 // setAudioSource_l() must be called with PlaybackThread::mLock held
setAudioSource_l(audio_source_t source)1687 void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
1688 {
1689     size_t size = mEffects.size();
1690     for (size_t i = 0; i < size; i++) {
1691         mEffects[i]->setAudioSource(source);
1692     }
1693 }
1694 
1695 // setVolume_l() must be called with PlaybackThread::mLock or EffectChain::mLock held
setVolume_l(uint32_t * left,uint32_t * right,bool force)1696 bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
1697 {
1698     uint32_t newLeft = *left;
1699     uint32_t newRight = *right;
1700     bool hasControl = false;
1701     int ctrlIdx = -1;
1702     size_t size = mEffects.size();
1703 
1704     // first update volume controller
1705     for (size_t i = size; i > 0; i--) {
1706         if (mEffects[i - 1]->isProcessEnabled() &&
1707             (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
1708             ctrlIdx = i - 1;
1709             hasControl = true;
1710             break;
1711         }
1712     }
1713 
1714     if (!force && ctrlIdx == mVolumeCtrlIdx &&
1715             *left == mLeftVolume && *right == mRightVolume) {
1716         if (hasControl) {
1717             *left = mNewLeftVolume;
1718             *right = mNewRightVolume;
1719         }
1720         return hasControl;
1721     }
1722 
1723     mVolumeCtrlIdx = ctrlIdx;
1724     mLeftVolume = newLeft;
1725     mRightVolume = newRight;
1726 
1727     // second get volume update from volume controller
1728     if (ctrlIdx >= 0) {
1729         mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
1730         mNewLeftVolume = newLeft;
1731         mNewRightVolume = newRight;
1732     }
1733     // then indicate volume to all other effects in chain.
1734     // Pass altered volume to effects before volume controller
1735     // and requested volume to effects after controller
1736     uint32_t lVol = newLeft;
1737     uint32_t rVol = newRight;
1738 
1739     for (size_t i = 0; i < size; i++) {
1740         if ((int)i == ctrlIdx) {
1741             continue;
1742         }
1743         // this also works for ctrlIdx == -1 when there is no volume controller
1744         if ((int)i > ctrlIdx) {
1745             lVol = *left;
1746             rVol = *right;
1747         }
1748         mEffects[i]->setVolume(&lVol, &rVol, false);
1749     }
1750     *left = newLeft;
1751     *right = newRight;
1752 
1753     return hasControl;
1754 }
1755 
1756 // resetVolume_l() must be called with PlaybackThread::mLock or EffectChain::mLock held
resetVolume_l()1757 void AudioFlinger::EffectChain::resetVolume_l()
1758 {
1759     if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
1760         uint32_t left = mLeftVolume;
1761         uint32_t right = mRightVolume;
1762         (void)setVolume_l(&left, &right, true);
1763     }
1764 }
1765 
syncHalEffectsState()1766 void AudioFlinger::EffectChain::syncHalEffectsState()
1767 {
1768     Mutex::Autolock _l(mLock);
1769     for (size_t i = 0; i < mEffects.size(); i++) {
1770         if (mEffects[i]->state() == EffectModule::ACTIVE ||
1771                 mEffects[i]->state() == EffectModule::STOPPING) {
1772             mEffects[i]->addEffectToHal_l();
1773         }
1774     }
1775 }
1776 
dump(int fd,const Vector<String16> & args)1777 void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
1778 {
1779     const size_t SIZE = 256;
1780     char buffer[SIZE];
1781     String8 result;
1782 
1783     size_t numEffects = mEffects.size();
1784     snprintf(buffer, SIZE, "    %zu effects for session %d\n", numEffects, mSessionId);
1785     result.append(buffer);
1786 
1787     if (numEffects) {
1788         bool locked = AudioFlinger::dumpTryLock(mLock);
1789         // failed to lock - AudioFlinger is probably deadlocked
1790         if (!locked) {
1791             result.append("\tCould not lock mutex:\n");
1792         }
1793 
1794         result.append("\tIn buffer   Out buffer   Active tracks:\n");
1795         snprintf(buffer, SIZE, "\t%p  %p   %d\n",
1796                 mInBuffer,
1797                 mOutBuffer,
1798                 mActiveTrackCnt);
1799         result.append(buffer);
1800         write(fd, result.string(), result.size());
1801 
1802         for (size_t i = 0; i < numEffects; ++i) {
1803             sp<EffectModule> effect = mEffects[i];
1804             if (effect != 0) {
1805                 effect->dump(fd, args);
1806             }
1807         }
1808 
1809         if (locked) {
1810             mLock.unlock();
1811         }
1812     }
1813 }
1814 
1815 // must be called with ThreadBase::mLock held
setEffectSuspended_l(const effect_uuid_t * type,bool suspend)1816 void AudioFlinger::EffectChain::setEffectSuspended_l(
1817         const effect_uuid_t *type, bool suspend)
1818 {
1819     sp<SuspendedEffectDesc> desc;
1820     // use effect type UUID timelow as key as there is no real risk of identical
1821     // timeLow fields among effect type UUIDs.
1822     ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
1823     if (suspend) {
1824         if (index >= 0) {
1825             desc = mSuspendedEffects.valueAt(index);
1826         } else {
1827             desc = new SuspendedEffectDesc();
1828             desc->mType = *type;
1829             mSuspendedEffects.add(type->timeLow, desc);
1830             ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
1831         }
1832         if (desc->mRefCount++ == 0) {
1833             sp<EffectModule> effect = getEffectIfEnabled(type);
1834             if (effect != 0) {
1835                 desc->mEffect = effect;
1836                 effect->setSuspended(true);
1837                 effect->setEnabled(false);
1838             }
1839         }
1840     } else {
1841         if (index < 0) {
1842             return;
1843         }
1844         desc = mSuspendedEffects.valueAt(index);
1845         if (desc->mRefCount <= 0) {
1846             ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
1847             desc->mRefCount = 1;
1848         }
1849         if (--desc->mRefCount == 0) {
1850             ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
1851             if (desc->mEffect != 0) {
1852                 sp<EffectModule> effect = desc->mEffect.promote();
1853                 if (effect != 0) {
1854                     effect->setSuspended(false);
1855                     effect->lock();
1856                     EffectHandle *handle = effect->controlHandle_l();
1857                     if (handle != NULL && !handle->destroyed_l()) {
1858                         effect->setEnabled_l(handle->enabled());
1859                     }
1860                     effect->unlock();
1861                 }
1862                 desc->mEffect.clear();
1863             }
1864             mSuspendedEffects.removeItemsAt(index);
1865         }
1866     }
1867 }
1868 
1869 // must be called with ThreadBase::mLock held
setEffectSuspendedAll_l(bool suspend)1870 void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
1871 {
1872     sp<SuspendedEffectDesc> desc;
1873 
1874     ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1875     if (suspend) {
1876         if (index >= 0) {
1877             desc = mSuspendedEffects.valueAt(index);
1878         } else {
1879             desc = new SuspendedEffectDesc();
1880             mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
1881             ALOGV("setEffectSuspendedAll_l() add entry for 0");
1882         }
1883         if (desc->mRefCount++ == 0) {
1884             Vector< sp<EffectModule> > effects;
1885             getSuspendEligibleEffects(effects);
1886             for (size_t i = 0; i < effects.size(); i++) {
1887                 setEffectSuspended_l(&effects[i]->desc().type, true);
1888             }
1889         }
1890     } else {
1891         if (index < 0) {
1892             return;
1893         }
1894         desc = mSuspendedEffects.valueAt(index);
1895         if (desc->mRefCount <= 0) {
1896             ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
1897             desc->mRefCount = 1;
1898         }
1899         if (--desc->mRefCount == 0) {
1900             Vector<const effect_uuid_t *> types;
1901             for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
1902                 if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
1903                     continue;
1904                 }
1905                 types.add(&mSuspendedEffects.valueAt(i)->mType);
1906             }
1907             for (size_t i = 0; i < types.size(); i++) {
1908                 setEffectSuspended_l(types[i], false);
1909             }
1910             ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
1911                     mSuspendedEffects.keyAt(index));
1912             mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
1913         }
1914     }
1915 }
1916 
1917 
1918 // The volume effect is used for automated tests only
1919 #ifndef OPENSL_ES_H_
1920 static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
1921                                             { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
1922 const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
1923 #endif //OPENSL_ES_H_
1924 
isEffectEligibleForSuspend(const effect_descriptor_t & desc)1925 bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
1926 {
1927     // auxiliary effects and visualizer are never suspended on output mix
1928     if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
1929         (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
1930          (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
1931          (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
1932         return false;
1933     }
1934     return true;
1935 }
1936 
getSuspendEligibleEffects(Vector<sp<AudioFlinger::EffectModule>> & effects)1937 void AudioFlinger::EffectChain::getSuspendEligibleEffects(
1938         Vector< sp<AudioFlinger::EffectModule> > &effects)
1939 {
1940     effects.clear();
1941     for (size_t i = 0; i < mEffects.size(); i++) {
1942         if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
1943             effects.add(mEffects[i]);
1944         }
1945     }
1946 }
1947 
getEffectIfEnabled(const effect_uuid_t * type)1948 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
1949                                                             const effect_uuid_t *type)
1950 {
1951     sp<EffectModule> effect = getEffectFromType_l(type);
1952     return effect != 0 && effect->isEnabled() ? effect : 0;
1953 }
1954 
checkSuspendOnEffectEnabled(const sp<EffectModule> & effect,bool enabled)1955 void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
1956                                                             bool enabled)
1957 {
1958     ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1959     if (enabled) {
1960         if (index < 0) {
1961             // if the effect is not suspend check if all effects are suspended
1962             index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1963             if (index < 0) {
1964                 return;
1965             }
1966             if (!isEffectEligibleForSuspend(effect->desc())) {
1967                 return;
1968             }
1969             setEffectSuspended_l(&effect->desc().type, enabled);
1970             index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1971             if (index < 0) {
1972                 ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
1973                 return;
1974             }
1975         }
1976         ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
1977             effect->desc().type.timeLow);
1978         sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1979         // if effect is requested to suspended but was not yet enabled, supend it now.
1980         if (desc->mEffect == 0) {
1981             desc->mEffect = effect;
1982             effect->setEnabled(false);
1983             effect->setSuspended(true);
1984         }
1985     } else {
1986         if (index < 0) {
1987             return;
1988         }
1989         ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
1990             effect->desc().type.timeLow);
1991         sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1992         desc->mEffect.clear();
1993         effect->setSuspended(false);
1994     }
1995 }
1996 
isNonOffloadableEnabled()1997 bool AudioFlinger::EffectChain::isNonOffloadableEnabled()
1998 {
1999     Mutex::Autolock _l(mLock);
2000     size_t size = mEffects.size();
2001     for (size_t i = 0; i < size; i++) {
2002         if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) {
2003             return true;
2004         }
2005     }
2006     return false;
2007 }
2008 
setThread(const sp<ThreadBase> & thread)2009 void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread)
2010 {
2011     Mutex::Autolock _l(mLock);
2012     mThread = thread;
2013     for (size_t i = 0; i < mEffects.size(); i++) {
2014         mEffects[i]->setThread(thread);
2015     }
2016 }
2017 
hasSoftwareEffect() const2018 bool AudioFlinger::EffectChain::hasSoftwareEffect() const
2019 {
2020     Mutex::Autolock _l(mLock);
2021     for (size_t i = 0; i < mEffects.size(); i++) {
2022         if (mEffects[i]->isImplementationSoftware()) {
2023             return true;
2024         }
2025     }
2026     return false;
2027 }
2028 
2029 // isCompatibleWithThread_l() must be called with thread->mLock held
isCompatibleWithThread_l(const sp<ThreadBase> & thread) const2030 bool AudioFlinger::EffectChain::isCompatibleWithThread_l(const sp<ThreadBase>& thread) const
2031 {
2032     Mutex::Autolock _l(mLock);
2033     for (size_t i = 0; i < mEffects.size(); i++) {
2034         if (thread->checkEffectCompatibility_l(&(mEffects[i]->desc()), mSessionId) != NO_ERROR) {
2035             return false;
2036         }
2037     }
2038     return true;
2039 }
2040 
2041 } // namespace android
2042