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