Loading services/audioflinger/AudioFlinger.cpp +40 −40 Original line number Diff line number Diff line Loading @@ -2200,7 +2200,7 @@ void AudioFlinger::registerClient(const sp<media::IAudioFlingerClient>& client) void AudioFlinger::removeNotificationClient(pid_t pid) { std::vector< sp<AudioFlinger::EffectModule> > removedEffects; std::vector<sp<IAfEffectModule>> removedEffects; { Mutex::Autolock _l(mLock); { Loading Loading @@ -2536,7 +2536,7 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, // Check if one effect chain was awaiting for an AudioRecord to be created on this // session and move it to this thread. sp<EffectChain> chain = getOrphanEffectChain_l(sessionId); sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId); if (chain != 0) { Mutex::Autolock _l2(thread->mLock); thread->addEffectChain_l(chain); Loading Loading @@ -3216,7 +3216,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) // audioflinger lock is held so order of thread lock acquisition doesn't matter Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(playbackThread->mLock); Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l(); Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), dstThread); Loading Loading @@ -3450,10 +3450,10 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input) // on at least one effect. We must either move the chain to an existing thread with the // same session ID or put it aside in case a new record thread is opened for a // new capture on the same session sp<EffectChain> chain; sp<IAfEffectChain> chain; { Mutex::Autolock _sl(recordThread->mLock); Vector< sp<EffectChain> > effectChains = recordThread->getEffectChains_l(); Vector< sp<IAfEffectChain> > effectChains = recordThread->getEffectChains_l(); // Note: maximum one chain per record thread if (effectChains.size() != 0) { chain = effectChains[0]; Loading Loading @@ -3596,7 +3596,7 @@ void AudioFlinger::acquireAudioSessionId( void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) { std::vector< sp<EffectModule> > removedEffects; std::vector<sp<IAfEffectModule>> removedEffects; { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); Loading @@ -3614,7 +3614,7 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid if (ref->mCnt == 0) { mAudioSessionRefs.removeAt(i); delete ref; std::vector< sp<EffectModule> > effects = purgeStaleEffects_l(); std::vector<sp<IAfEffectModule>> effects = purgeStaleEffects_l(); removedEffects.insert(removedEffects.end(), effects.begin(), effects.end()); } goto Exit; Loading Loading @@ -3644,18 +3644,18 @@ bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) return false; } std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() { std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() { ALOGV("purging stale effects"); Vector< sp<EffectChain> > chains; std::vector< sp<EffectModule> > removedEffects; Vector< sp<IAfEffectChain> > chains; std::vector< sp<IAfEffectModule> > removedEffects; for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> t = mPlaybackThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; if (!audio_is_global_session(ec->sessionId())) { chains.push(ec); } Loading @@ -3666,7 +3666,7 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() sp<RecordThread> t = mRecordThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; chains.push(ec); } } Loading @@ -3675,16 +3675,16 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() sp<MmapThread> t = mMmapThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; chains.push(ec); } } for (size_t i = 0; i < chains.size(); i++) { // clang-tidy suggests const ref sp<EffectChain> ec = chains[i]; // NOLINT(performance-unnecessary-copy-initialization) sp<IAfEffectChain> ec = chains[i]; // NOLINT(performance-unnecessary-copy-initialization) int sessionid = ec->sessionId(); sp<ThreadBase> t = ec->thread().promote(); sp<ThreadBase> t = sp<ThreadBase>::cast(ec->thread().promote()); // TODO(b/288339104) if (t == 0) { continue; } Loading @@ -3702,8 +3702,8 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() if (!found) { Mutex::Autolock _l(t->mLock); // remove all effects from the chain while (ec->mEffects.size()) { sp<EffectModule> effect = ec->mEffects[0]; while (ec->numberOfEffects()) { sp<IAfEffectModule> effect = ec->getEffectModule(0); effect->unPin(); t->removeEffect_l(effect, /*release*/ true); if (effect->purgeHandles()) { Loading Loading @@ -4140,7 +4140,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, aidl2legacy_EffectDescriptor_effect_descriptor_t(request.desc)); const bool probe = request.probe; sp<EffectHandle> handle; sp<IAfEffectHandle> handle; effect_descriptor_t descOut; int enabledOut = 0; int idOut = -1; Loading Loading @@ -4248,7 +4248,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, goto Exit; } const bool hapticPlaybackRequired = EffectModule::isHapticGenerator(&descOut.type); const bool hapticPlaybackRequired = IAfEffectModule::isHapticGenerator(&descOut.type); if (hapticPlaybackRequired && (sessionId == AUDIO_SESSION_DEVICE || sessionId == AUDIO_SESSION_OUTPUT_MIX Loading Loading @@ -4376,7 +4376,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, } else { // Check if one effect chain was awaiting for an effect to be created on this // session and used it instead of creating a new one. sp<EffectChain> chain = getOrphanEffectChain_l(sessionId); sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId); if (chain != 0) { Mutex::Autolock _l2(thread->mLock); thread->addEffectChain_l(chain); Loading Loading @@ -4428,7 +4428,7 @@ Register: response->alreadyExists = false; } // Check CPU and memory usage sp<EffectBase> effect = handle->effect().promote(); sp<IAfEffectBase> effect = handle->effect().promote(); if (effect != nullptr) { status_t rStatus = effect->updatePolicyState(); if (rStatus != NO_ERROR) { Loading @@ -4441,7 +4441,7 @@ Register: response->id = idOut; response->enabled = enabledOut != 0; response->effect = handle; response->effect = handle->asIEffect(); response->desc = VALUE_OR_RETURN_STATUS( legacy2aidl_effect_descriptor_t_EffectDescriptor(descOut)); Loading Loading @@ -4487,7 +4487,7 @@ void AudioFlinger::setEffectSuspended(int effectId, return; } Mutex::Autolock _sl(thread->mLock); sp<EffectModule> effect = thread->getEffect_l(sessionId, effectId); sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId); thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId); } Loading @@ -4501,7 +4501,7 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId); sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId); if (chain == 0) { ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p", sessionId, srcThread); Loading @@ -4525,12 +4525,12 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks // transfer all effects one by one so that new effect chain is created on new thread with // correct buffer sizes and audio parameters and effect engines reconfigured accordingly sp<EffectChain> dstChain; Vector< sp<EffectModule> > removed; sp<IAfEffectChain> dstChain; Vector<sp<IAfEffectModule>> removed; status_t status = NO_ERROR; std::string errorString; // process effects one by one. for (sp<EffectModule> effect = chain->getEffectFromId_l(0); effect != nullptr; for (sp<IAfEffectModule> effect = chain->getEffectFromId_l(0); effect != nullptr; effect = chain->getEffectFromId_l(0)) { srcThread->removeEffect_l(effect); removed.add(effect); Loading Loading @@ -4578,8 +4578,8 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks // see b/202360137. dstChain->lock(); for (const auto& effect : removed) { if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { if (effect->state() == IAfEffectModule::ACTIVE || effect->state() == IAfEffectModule::STOPPING) { ++started; effect->start(); } Loading Loading @@ -4616,13 +4616,13 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, if (EffectId != 0 && thread != 0 && dstThread != thread.get()) { Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(thread->mLock); sp<EffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); sp<EffectChain> dstChain; sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); sp<IAfEffectChain> dstChain; if (srcChain == 0) { return INVALID_OPERATION; } sp<EffectModule> effect = srcChain->getEffectFromId_l(EffectId); sp<IAfEffectModule> effect = srcChain->getEffectFromId_l(EffectId); if (effect == 0) { return INVALID_OPERATION; } Loading @@ -4642,8 +4642,8 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, Exit: // removeEffect_l() has stopped the effect if it was active so it must be restarted if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { if (effect->state() == IAfEffectModule::ACTIVE || effect->state() == IAfEffectModule::STOPPING) { effect->start(); } } Loading @@ -4663,7 +4663,7 @@ NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l. } for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<EffectChain> ec = sp<IAfEffectChain> ec = mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (ec != 0 && ec->isNonOffloadableEnabled()) { return true; Loading @@ -4687,7 +4687,7 @@ void AudioFlinger::onNonOffloadableGlobalEffectEnable() } status_t AudioFlinger::putOrphanEffectChain_l(const sp<AudioFlinger::EffectChain>& chain) status_t AudioFlinger::putOrphanEffectChain_l(const sp<IAfEffectChain>& chain) { // clear possible suspended state before parking the chain so that it starts in default state // when attached to a new record thread Loading @@ -4705,9 +4705,9 @@ status_t AudioFlinger::putOrphanEffectChain_l(const sp<AudioFlinger::EffectChain return NO_ERROR; } sp<AudioFlinger::EffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session_t session) sp<IAfEffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session_t session) { sp<EffectChain> chain; sp<IAfEffectChain> chain; ssize_t index = mOrphanEffectChains.indexOfKey(session); ALOGV("getOrphanEffectChain_l session %d index %zd", session, index); if (index >= 0) { Loading @@ -4717,14 +4717,14 @@ sp<AudioFlinger::EffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session return chain; } bool AudioFlinger::updateOrphanEffectChains(const sp<AudioFlinger::EffectModule>& effect) bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect) { Mutex::Autolock _l(mLock); audio_session_t session = effect->sessionId(); ssize_t index = mOrphanEffectChains.indexOfKey(session); ALOGV("updateOrphanEffectChains session %d index %zd", session, index); if (index >= 0) { sp<EffectChain> chain = mOrphanEffectChains.valueAt(index); sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index); if (chain->removeEffect_l(effect, true) == 0) { ALOGV("updateOrphanEffectChains removing effect chain at index %zd", index); mOrphanEffectChains.removeItemsAt(index); Loading services/audioflinger/AudioFlinger.h +29 −14 Original line number Diff line number Diff line Loading @@ -117,6 +117,9 @@ #include "android/media/BnAudioRecord.h" #include "android/media/BnEffect.h" // include AudioFlinger component interfaces #include "IAfEffect.h" namespace android { class AudioMixer; Loading Loading @@ -478,16 +481,24 @@ private: // Internal dump utilities. static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND; public: // TODO(b/288339104) extract to afutils static bool dumpTryLock(Mutex& mutex); private: void dumpPermissionDenial(int fd, const Vector<String16>& args); void dumpClients(int fd, const Vector<String16>& args); void dumpInternals(int fd, const Vector<String16>& args); SimpleLog mThreadLog{16}; // 16 Thread history limit public: // TODO(b/288339104) class ThreadBase; private: void dumpToThreadLog_l(const sp<ThreadBase> &thread); public: // TODO(b/288339104) Move to separate file // --- Client --- class Client : public RefBase { public: Loading @@ -504,6 +515,7 @@ private: const pid_t mPid; AllocatorFactory::ClientAllocator mClientAllocator; }; private: // --- Notification Client --- class NotificationClient : public IBinder::DeathRecipient { Loading Loading @@ -575,15 +587,12 @@ private: class BitPerfectThread; class Track; class RecordTrack; class EffectBase; class EffectModule; class EffectHandle; class EffectChain; class DeviceEffectProxy; class DeviceEffectManager; // TODO(b/288339104) these should be separate files public: class PatchPanel; class DeviceEffectManagerCallback; private: struct AudioStreamIn; struct TeePatch; using TeePatches = std::vector<TeePatch>; Loading Loading @@ -617,8 +626,6 @@ private: #include "PatchCommandThread.h" #include "Effects.h" #include "DeviceEffectManager.h" #include "MelReporter.h" Loading Loading @@ -819,17 +826,19 @@ private: // return ALREADY_EXISTS if a chain with the same session already exists in // mOrphanEffectChains. Note that this should never happen as there is only one // chain for a given session and it is attached to only one thread at a time. status_t putOrphanEffectChain_l(const sp<EffectChain>& chain); status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain); // Get an effect chain for the specified session in mOrphanEffectChains and remove // it if found. Returns 0 if not found (this is the most common case). sp<EffectChain> getOrphanEffectChain_l(audio_session_t session); sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session); // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. bool updateOrphanEffectChains(const sp<EffectModule>& effect); std::vector< sp<EffectModule> > purgeStaleEffects_l(); public: // TODO(b/288339104) suggest better grouping bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect); private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices); Loading Loading @@ -879,7 +888,10 @@ private: // protects mClients and mNotificationClients. // must be locked after mLock and ThreadBase::mLock if both must be locked // avoids acquiring AudioFlinger::mLock from inside thread loop. public: // TODO(b/288339104) access by getter, mutable Mutex mClientLock; private: // protected by mClientLock DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client() Loading Loading @@ -958,7 +970,7 @@ private: std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents; // Effect chains without a valid thread DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains; DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains; // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds; Loading Loading @@ -1004,7 +1016,10 @@ private: // protected by mLock PatchPanel mPatchPanel; public: // TODO(b/288339104) access by getter. sp<EffectsFactoryHalInterface> mEffectsFactoryHal; private: const sp<PatchCommandThread> mPatchCommandThread; sp<DeviceEffectManager> mDeviceEffectManager; Loading services/audioflinger/DeviceEffectManager.cpp +13 −13 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ void AudioFlinger::DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0); Mutex::Autolock _l(mLock); for (auto& effect : mDeviceEffects) { status_t status = effect.second->onCreatePatch(handle, patch); status_t status = effect.second->onCreatePatch(handle, &patch); // TODO(b/288339104) void* ALOGV("%s Effect onCreatePatch status %d", __func__, status); ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status); } Loading @@ -56,7 +56,7 @@ void AudioFlinger::DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t } // DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l( sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l( effect_descriptor_t *descriptor, const AudioDeviceTypeAddr& device, const sp<AudioFlinger::Client>& client, Loading @@ -66,8 +66,8 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l status_t *status, bool probe, bool notifyFramesProcessed) { sp<DeviceEffectProxy> effect; sp<EffectHandle> handle; sp<IAfDeviceEffectProxy> effect; sp<IAfEffectHandle> handle; status_t lStatus; lStatus = checkEffectCompatibility(descriptor); Loading @@ -82,18 +82,18 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l if (iter != mDeviceEffects.end()) { effect = iter->second; } else { effect = new DeviceEffectProxy(device, mMyCallback, effect = IAfDeviceEffectProxy::create(device, mMyCallback, descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT), notifyFramesProcessed); } // create effect handle and connect it to effect module handle = new EffectHandle(effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed); handle = IAfEffectHandle::create( effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed); lStatus = handle->initCheck(); if (lStatus == NO_ERROR) { lStatus = effect->addHandle(handle.get()); if (lStatus == NO_ERROR) { lStatus = effect->init(patches); lStatus = effect->init(&patches); // TODO(b/288339104) void* if (lStatus == NAME_NOT_FOUND) { lStatus = NO_ERROR; } Loading Loading @@ -165,7 +165,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "", ::android::toString(iter.first.mType).c_str(), iter.first.getAddress()); write(fd, outStr.string(), outStr.size()); iter.second->dump(fd, 4); iter.second->dump2(fd, 4); } if (locked) { Loading @@ -174,7 +174,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock } size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<DeviceEffectProxy>& effect) size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect) { Mutex::Autolock _l(mLock); mDeviceEffects.erase(effect->device()); Loading @@ -182,13 +182,13 @@ size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<DeviceEffectProx } bool AudioFlinger::DeviceEffectManagerCallback::disconnectEffectHandle( EffectHandle *handle, bool unpinIfLast) { sp<EffectBase> effectBase = handle->effect().promote(); IAfEffectHandle *handle, bool unpinIfLast) { sp<IAfEffectBase> effectBase = handle->effect().promote(); if (effectBase == nullptr) { return false; } sp<DeviceEffectProxy> effect = effectBase->asDeviceEffectProxy(); sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy(); if (effect == nullptr) { return false; } Loading services/audioflinger/DeviceEffectManager.h +13 −9 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ public: mAudioFlinger.mPatchCommandThread->addListener(this); } sp<EffectHandle> createEffect_l(effect_descriptor_t *descriptor, sp<IAfEffectHandle> createEffect_l(effect_descriptor_t *descriptor, const AudioDeviceTypeAddr& device, const sp<AudioFlinger::Client>& client, const sp<media::IEffectClient>& effectClient, Loading @@ -40,7 +40,7 @@ public: bool probe, bool notifyFramesProcessed); size_t removeEffect(const sp<DeviceEffectProxy>& effect); size_t removeEffect(const sp<IAfDeviceEffectProxy>& effect); status_t createEffectHal(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect); Loading Loading @@ -69,9 +69,10 @@ private: Mutex mLock; AudioFlinger &mAudioFlinger; const sp<DeviceEffectManagerCallback> mMyCallback; std::map<AudioDeviceTypeAddr, sp<DeviceEffectProxy>> mDeviceEffects; std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects; }; public: // TODO(b/288339104) extract inner class. class DeviceEffectManagerCallback : public EffectCallbackInterface { public: explicit DeviceEffectManagerCallback(DeviceEffectManager& manager) Loading @@ -84,7 +85,9 @@ public: } status_t allocateHalBuffer(size_t size __unused, sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; } bool updateOrphanEffectChains(const sp<EffectBase>& effect __unused) override { return false; } bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) override { return false; } audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; } bool isOutput() const override { return false; } Loading Loading @@ -112,19 +115,19 @@ public: return NO_ERROR; } bool disconnectEffectHandle(EffectHandle *handle, bool unpinIfLast) override; bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) override; void setVolumeForOutput(float left __unused, float right __unused) const override {} // check if effects should be suspended or restored when a given effect is enable or disabled void checkSuspendOnEffectEnabled(const sp<EffectBase>& effect __unused, void checkSuspendOnEffectEnabled(const sp<IAfEffectBase>& effect __unused, bool enabled __unused, bool threadLocked __unused) override {} void resetVolume() override {} product_strategy_t strategy() const override { return static_cast<product_strategy_t>(0); } int32_t activeTrackCnt() const override { return 0; } void onEffectEnable(const sp<EffectBase>& effect __unused) override {} void onEffectDisable(const sp<EffectBase>& effect __unused) override {} void onEffectEnable(const sp<IAfEffectBase>& effect __unused) override {} void onEffectDisable(const sp<IAfEffectBase>& effect __unused) override {} wp<EffectChain> chain() const override { return nullptr; } wp<IAfEffectChain> chain() const override { return nullptr; } bool isAudioPolicyReady() const override { return mManager.audioFlinger().isAudioPolicyReady(); Loading @@ -143,3 +146,4 @@ public: private: DeviceEffectManager& mManager; }; private: services/audioflinger/Effects.cpp +297 −261 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/audioflinger/AudioFlinger.cpp +40 −40 Original line number Diff line number Diff line Loading @@ -2200,7 +2200,7 @@ void AudioFlinger::registerClient(const sp<media::IAudioFlingerClient>& client) void AudioFlinger::removeNotificationClient(pid_t pid) { std::vector< sp<AudioFlinger::EffectModule> > removedEffects; std::vector<sp<IAfEffectModule>> removedEffects; { Mutex::Autolock _l(mLock); { Loading Loading @@ -2536,7 +2536,7 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, // Check if one effect chain was awaiting for an AudioRecord to be created on this // session and move it to this thread. sp<EffectChain> chain = getOrphanEffectChain_l(sessionId); sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId); if (chain != 0) { Mutex::Autolock _l2(thread->mLock); thread->addEffectChain_l(chain); Loading Loading @@ -3216,7 +3216,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) // audioflinger lock is held so order of thread lock acquisition doesn't matter Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(playbackThread->mLock); Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l(); Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), dstThread); Loading Loading @@ -3450,10 +3450,10 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input) // on at least one effect. We must either move the chain to an existing thread with the // same session ID or put it aside in case a new record thread is opened for a // new capture on the same session sp<EffectChain> chain; sp<IAfEffectChain> chain; { Mutex::Autolock _sl(recordThread->mLock); Vector< sp<EffectChain> > effectChains = recordThread->getEffectChains_l(); Vector< sp<IAfEffectChain> > effectChains = recordThread->getEffectChains_l(); // Note: maximum one chain per record thread if (effectChains.size() != 0) { chain = effectChains[0]; Loading Loading @@ -3596,7 +3596,7 @@ void AudioFlinger::acquireAudioSessionId( void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) { std::vector< sp<EffectModule> > removedEffects; std::vector<sp<IAfEffectModule>> removedEffects; { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); Loading @@ -3614,7 +3614,7 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid if (ref->mCnt == 0) { mAudioSessionRefs.removeAt(i); delete ref; std::vector< sp<EffectModule> > effects = purgeStaleEffects_l(); std::vector<sp<IAfEffectModule>> effects = purgeStaleEffects_l(); removedEffects.insert(removedEffects.end(), effects.begin(), effects.end()); } goto Exit; Loading Loading @@ -3644,18 +3644,18 @@ bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) return false; } std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() { std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() { ALOGV("purging stale effects"); Vector< sp<EffectChain> > chains; std::vector< sp<EffectModule> > removedEffects; Vector< sp<IAfEffectChain> > chains; std::vector< sp<IAfEffectModule> > removedEffects; for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> t = mPlaybackThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; if (!audio_is_global_session(ec->sessionId())) { chains.push(ec); } Loading @@ -3666,7 +3666,7 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() sp<RecordThread> t = mRecordThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; chains.push(ec); } } Loading @@ -3675,16 +3675,16 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() sp<MmapThread> t = mMmapThreads.valueAt(i); Mutex::Autolock _l(t->mLock); for (size_t j = 0; j < t->mEffectChains.size(); j++) { sp<EffectChain> ec = t->mEffectChains[j]; sp<IAfEffectChain> ec = t->mEffectChains[j]; chains.push(ec); } } for (size_t i = 0; i < chains.size(); i++) { // clang-tidy suggests const ref sp<EffectChain> ec = chains[i]; // NOLINT(performance-unnecessary-copy-initialization) sp<IAfEffectChain> ec = chains[i]; // NOLINT(performance-unnecessary-copy-initialization) int sessionid = ec->sessionId(); sp<ThreadBase> t = ec->thread().promote(); sp<ThreadBase> t = sp<ThreadBase>::cast(ec->thread().promote()); // TODO(b/288339104) if (t == 0) { continue; } Loading @@ -3702,8 +3702,8 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() if (!found) { Mutex::Autolock _l(t->mLock); // remove all effects from the chain while (ec->mEffects.size()) { sp<EffectModule> effect = ec->mEffects[0]; while (ec->numberOfEffects()) { sp<IAfEffectModule> effect = ec->getEffectModule(0); effect->unPin(); t->removeEffect_l(effect, /*release*/ true); if (effect->purgeHandles()) { Loading Loading @@ -4140,7 +4140,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, aidl2legacy_EffectDescriptor_effect_descriptor_t(request.desc)); const bool probe = request.probe; sp<EffectHandle> handle; sp<IAfEffectHandle> handle; effect_descriptor_t descOut; int enabledOut = 0; int idOut = -1; Loading Loading @@ -4248,7 +4248,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, goto Exit; } const bool hapticPlaybackRequired = EffectModule::isHapticGenerator(&descOut.type); const bool hapticPlaybackRequired = IAfEffectModule::isHapticGenerator(&descOut.type); if (hapticPlaybackRequired && (sessionId == AUDIO_SESSION_DEVICE || sessionId == AUDIO_SESSION_OUTPUT_MIX Loading Loading @@ -4376,7 +4376,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, } else { // Check if one effect chain was awaiting for an effect to be created on this // session and used it instead of creating a new one. sp<EffectChain> chain = getOrphanEffectChain_l(sessionId); sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId); if (chain != 0) { Mutex::Autolock _l2(thread->mLock); thread->addEffectChain_l(chain); Loading Loading @@ -4428,7 +4428,7 @@ Register: response->alreadyExists = false; } // Check CPU and memory usage sp<EffectBase> effect = handle->effect().promote(); sp<IAfEffectBase> effect = handle->effect().promote(); if (effect != nullptr) { status_t rStatus = effect->updatePolicyState(); if (rStatus != NO_ERROR) { Loading @@ -4441,7 +4441,7 @@ Register: response->id = idOut; response->enabled = enabledOut != 0; response->effect = handle; response->effect = handle->asIEffect(); response->desc = VALUE_OR_RETURN_STATUS( legacy2aidl_effect_descriptor_t_EffectDescriptor(descOut)); Loading Loading @@ -4487,7 +4487,7 @@ void AudioFlinger::setEffectSuspended(int effectId, return; } Mutex::Autolock _sl(thread->mLock); sp<EffectModule> effect = thread->getEffect_l(sessionId, effectId); sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId); thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId); } Loading @@ -4501,7 +4501,7 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId); sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId); if (chain == 0) { ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p", sessionId, srcThread); Loading @@ -4525,12 +4525,12 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks // transfer all effects one by one so that new effect chain is created on new thread with // correct buffer sizes and audio parameters and effect engines reconfigured accordingly sp<EffectChain> dstChain; Vector< sp<EffectModule> > removed; sp<IAfEffectChain> dstChain; Vector<sp<IAfEffectModule>> removed; status_t status = NO_ERROR; std::string errorString; // process effects one by one. for (sp<EffectModule> effect = chain->getEffectFromId_l(0); effect != nullptr; for (sp<IAfEffectModule> effect = chain->getEffectFromId_l(0); effect != nullptr; effect = chain->getEffectFromId_l(0)) { srcThread->removeEffect_l(effect); removed.add(effect); Loading Loading @@ -4578,8 +4578,8 @@ NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks // see b/202360137. dstChain->lock(); for (const auto& effect : removed) { if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { if (effect->state() == IAfEffectModule::ACTIVE || effect->state() == IAfEffectModule::STOPPING) { ++started; effect->start(); } Loading Loading @@ -4616,13 +4616,13 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, if (EffectId != 0 && thread != 0 && dstThread != thread.get()) { Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(thread->mLock); sp<EffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); sp<EffectChain> dstChain; sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); sp<IAfEffectChain> dstChain; if (srcChain == 0) { return INVALID_OPERATION; } sp<EffectModule> effect = srcChain->getEffectFromId_l(EffectId); sp<IAfEffectModule> effect = srcChain->getEffectFromId_l(EffectId); if (effect == 0) { return INVALID_OPERATION; } Loading @@ -4642,8 +4642,8 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, Exit: // removeEffect_l() has stopped the effect if it was active so it must be restarted if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { if (effect->state() == IAfEffectModule::ACTIVE || effect->state() == IAfEffectModule::STOPPING) { effect->start(); } } Loading @@ -4663,7 +4663,7 @@ NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l. } for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<EffectChain> ec = sp<IAfEffectChain> ec = mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (ec != 0 && ec->isNonOffloadableEnabled()) { return true; Loading @@ -4687,7 +4687,7 @@ void AudioFlinger::onNonOffloadableGlobalEffectEnable() } status_t AudioFlinger::putOrphanEffectChain_l(const sp<AudioFlinger::EffectChain>& chain) status_t AudioFlinger::putOrphanEffectChain_l(const sp<IAfEffectChain>& chain) { // clear possible suspended state before parking the chain so that it starts in default state // when attached to a new record thread Loading @@ -4705,9 +4705,9 @@ status_t AudioFlinger::putOrphanEffectChain_l(const sp<AudioFlinger::EffectChain return NO_ERROR; } sp<AudioFlinger::EffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session_t session) sp<IAfEffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session_t session) { sp<EffectChain> chain; sp<IAfEffectChain> chain; ssize_t index = mOrphanEffectChains.indexOfKey(session); ALOGV("getOrphanEffectChain_l session %d index %zd", session, index); if (index >= 0) { Loading @@ -4717,14 +4717,14 @@ sp<AudioFlinger::EffectChain> AudioFlinger::getOrphanEffectChain_l(audio_session return chain; } bool AudioFlinger::updateOrphanEffectChains(const sp<AudioFlinger::EffectModule>& effect) bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect) { Mutex::Autolock _l(mLock); audio_session_t session = effect->sessionId(); ssize_t index = mOrphanEffectChains.indexOfKey(session); ALOGV("updateOrphanEffectChains session %d index %zd", session, index); if (index >= 0) { sp<EffectChain> chain = mOrphanEffectChains.valueAt(index); sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index); if (chain->removeEffect_l(effect, true) == 0) { ALOGV("updateOrphanEffectChains removing effect chain at index %zd", index); mOrphanEffectChains.removeItemsAt(index); Loading
services/audioflinger/AudioFlinger.h +29 −14 Original line number Diff line number Diff line Loading @@ -117,6 +117,9 @@ #include "android/media/BnAudioRecord.h" #include "android/media/BnEffect.h" // include AudioFlinger component interfaces #include "IAfEffect.h" namespace android { class AudioMixer; Loading Loading @@ -478,16 +481,24 @@ private: // Internal dump utilities. static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND; public: // TODO(b/288339104) extract to afutils static bool dumpTryLock(Mutex& mutex); private: void dumpPermissionDenial(int fd, const Vector<String16>& args); void dumpClients(int fd, const Vector<String16>& args); void dumpInternals(int fd, const Vector<String16>& args); SimpleLog mThreadLog{16}; // 16 Thread history limit public: // TODO(b/288339104) class ThreadBase; private: void dumpToThreadLog_l(const sp<ThreadBase> &thread); public: // TODO(b/288339104) Move to separate file // --- Client --- class Client : public RefBase { public: Loading @@ -504,6 +515,7 @@ private: const pid_t mPid; AllocatorFactory::ClientAllocator mClientAllocator; }; private: // --- Notification Client --- class NotificationClient : public IBinder::DeathRecipient { Loading Loading @@ -575,15 +587,12 @@ private: class BitPerfectThread; class Track; class RecordTrack; class EffectBase; class EffectModule; class EffectHandle; class EffectChain; class DeviceEffectProxy; class DeviceEffectManager; // TODO(b/288339104) these should be separate files public: class PatchPanel; class DeviceEffectManagerCallback; private: struct AudioStreamIn; struct TeePatch; using TeePatches = std::vector<TeePatch>; Loading Loading @@ -617,8 +626,6 @@ private: #include "PatchCommandThread.h" #include "Effects.h" #include "DeviceEffectManager.h" #include "MelReporter.h" Loading Loading @@ -819,17 +826,19 @@ private: // return ALREADY_EXISTS if a chain with the same session already exists in // mOrphanEffectChains. Note that this should never happen as there is only one // chain for a given session and it is attached to only one thread at a time. status_t putOrphanEffectChain_l(const sp<EffectChain>& chain); status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain); // Get an effect chain for the specified session in mOrphanEffectChains and remove // it if found. Returns 0 if not found (this is the most common case). sp<EffectChain> getOrphanEffectChain_l(audio_session_t session); sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session); // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. bool updateOrphanEffectChains(const sp<EffectModule>& effect); std::vector< sp<EffectModule> > purgeStaleEffects_l(); public: // TODO(b/288339104) suggest better grouping bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect); private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices); Loading Loading @@ -879,7 +888,10 @@ private: // protects mClients and mNotificationClients. // must be locked after mLock and ThreadBase::mLock if both must be locked // avoids acquiring AudioFlinger::mLock from inside thread loop. public: // TODO(b/288339104) access by getter, mutable Mutex mClientLock; private: // protected by mClientLock DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client() Loading Loading @@ -958,7 +970,7 @@ private: std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents; // Effect chains without a valid thread DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains; DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains; // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds; Loading Loading @@ -1004,7 +1016,10 @@ private: // protected by mLock PatchPanel mPatchPanel; public: // TODO(b/288339104) access by getter. sp<EffectsFactoryHalInterface> mEffectsFactoryHal; private: const sp<PatchCommandThread> mPatchCommandThread; sp<DeviceEffectManager> mDeviceEffectManager; Loading
services/audioflinger/DeviceEffectManager.cpp +13 −13 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ void AudioFlinger::DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0); Mutex::Autolock _l(mLock); for (auto& effect : mDeviceEffects) { status_t status = effect.second->onCreatePatch(handle, patch); status_t status = effect.second->onCreatePatch(handle, &patch); // TODO(b/288339104) void* ALOGV("%s Effect onCreatePatch status %d", __func__, status); ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status); } Loading @@ -56,7 +56,7 @@ void AudioFlinger::DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t } // DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l( sp<IAfEffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l( effect_descriptor_t *descriptor, const AudioDeviceTypeAddr& device, const sp<AudioFlinger::Client>& client, Loading @@ -66,8 +66,8 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l status_t *status, bool probe, bool notifyFramesProcessed) { sp<DeviceEffectProxy> effect; sp<EffectHandle> handle; sp<IAfDeviceEffectProxy> effect; sp<IAfEffectHandle> handle; status_t lStatus; lStatus = checkEffectCompatibility(descriptor); Loading @@ -82,18 +82,18 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::DeviceEffectManager::createEffect_l if (iter != mDeviceEffects.end()) { effect = iter->second; } else { effect = new DeviceEffectProxy(device, mMyCallback, effect = IAfDeviceEffectProxy::create(device, mMyCallback, descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT), notifyFramesProcessed); } // create effect handle and connect it to effect module handle = new EffectHandle(effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed); handle = IAfEffectHandle::create( effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed); lStatus = handle->initCheck(); if (lStatus == NO_ERROR) { lStatus = effect->addHandle(handle.get()); if (lStatus == NO_ERROR) { lStatus = effect->init(patches); lStatus = effect->init(&patches); // TODO(b/288339104) void* if (lStatus == NAME_NOT_FOUND) { lStatus = NO_ERROR; } Loading Loading @@ -165,7 +165,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "", ::android::toString(iter.first.mType).c_str(), iter.first.getAddress()); write(fd, outStr.string(), outStr.size()); iter.second->dump(fd, 4); iter.second->dump2(fd, 4); } if (locked) { Loading @@ -174,7 +174,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock } size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<DeviceEffectProxy>& effect) size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect) { Mutex::Autolock _l(mLock); mDeviceEffects.erase(effect->device()); Loading @@ -182,13 +182,13 @@ size_t AudioFlinger::DeviceEffectManager::removeEffect(const sp<DeviceEffectProx } bool AudioFlinger::DeviceEffectManagerCallback::disconnectEffectHandle( EffectHandle *handle, bool unpinIfLast) { sp<EffectBase> effectBase = handle->effect().promote(); IAfEffectHandle *handle, bool unpinIfLast) { sp<IAfEffectBase> effectBase = handle->effect().promote(); if (effectBase == nullptr) { return false; } sp<DeviceEffectProxy> effect = effectBase->asDeviceEffectProxy(); sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy(); if (effect == nullptr) { return false; } Loading
services/audioflinger/DeviceEffectManager.h +13 −9 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ public: mAudioFlinger.mPatchCommandThread->addListener(this); } sp<EffectHandle> createEffect_l(effect_descriptor_t *descriptor, sp<IAfEffectHandle> createEffect_l(effect_descriptor_t *descriptor, const AudioDeviceTypeAddr& device, const sp<AudioFlinger::Client>& client, const sp<media::IEffectClient>& effectClient, Loading @@ -40,7 +40,7 @@ public: bool probe, bool notifyFramesProcessed); size_t removeEffect(const sp<DeviceEffectProxy>& effect); size_t removeEffect(const sp<IAfDeviceEffectProxy>& effect); status_t createEffectHal(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect); Loading Loading @@ -69,9 +69,10 @@ private: Mutex mLock; AudioFlinger &mAudioFlinger; const sp<DeviceEffectManagerCallback> mMyCallback; std::map<AudioDeviceTypeAddr, sp<DeviceEffectProxy>> mDeviceEffects; std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects; }; public: // TODO(b/288339104) extract inner class. class DeviceEffectManagerCallback : public EffectCallbackInterface { public: explicit DeviceEffectManagerCallback(DeviceEffectManager& manager) Loading @@ -84,7 +85,9 @@ public: } status_t allocateHalBuffer(size_t size __unused, sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; } bool updateOrphanEffectChains(const sp<EffectBase>& effect __unused) override { return false; } bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) override { return false; } audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; } bool isOutput() const override { return false; } Loading Loading @@ -112,19 +115,19 @@ public: return NO_ERROR; } bool disconnectEffectHandle(EffectHandle *handle, bool unpinIfLast) override; bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) override; void setVolumeForOutput(float left __unused, float right __unused) const override {} // check if effects should be suspended or restored when a given effect is enable or disabled void checkSuspendOnEffectEnabled(const sp<EffectBase>& effect __unused, void checkSuspendOnEffectEnabled(const sp<IAfEffectBase>& effect __unused, bool enabled __unused, bool threadLocked __unused) override {} void resetVolume() override {} product_strategy_t strategy() const override { return static_cast<product_strategy_t>(0); } int32_t activeTrackCnt() const override { return 0; } void onEffectEnable(const sp<EffectBase>& effect __unused) override {} void onEffectDisable(const sp<EffectBase>& effect __unused) override {} void onEffectEnable(const sp<IAfEffectBase>& effect __unused) override {} void onEffectDisable(const sp<IAfEffectBase>& effect __unused) override {} wp<EffectChain> chain() const override { return nullptr; } wp<IAfEffectChain> chain() const override { return nullptr; } bool isAudioPolicyReady() const override { return mManager.audioFlinger().isAudioPolicyReady(); Loading @@ -143,3 +146,4 @@ public: private: DeviceEffectManager& mManager; }; private:
services/audioflinger/Effects.cpp +297 −261 File changed.Preview size limit exceeded, changes collapsed. Show changes