Loading media/libaudioclient/AudioSystem.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -1067,6 +1067,13 @@ status_t AudioSystem::setEffectEnabled(int id, bool enabled) return aps->setEffectEnabled(id, enabled); } status_t AudioSystem::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->moveEffectsToIo(ids, io); } status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); Loading media/libaudioclient/IAudioPolicyService.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ enum { LIST_AUDIO_VOLUME_GROUPS, GET_VOLUME_GROUP_FOR_ATTRIBUTES, SET_ALLOWED_CAPTURE_POLICY, MOVE_EFFECTS_TO_IO, }; #define MAX_ITEMS_PER_LIST 1024 Loading Loading @@ -550,6 +551,22 @@ public: return static_cast <status_t> (reply.readInt32()); } status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(ids.size()); for (auto id : ids) { data.writeInt32(id); } data.writeInt32(io); status_t status = remote()->transact(MOVE_EFFECTS_TO_IO, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const { Parcel data, reply; Loading Loading @@ -1284,6 +1301,7 @@ status_t BnAudioPolicyService::onTransact( case GET_OUTPUT_FOR_ATTR: case ACQUIRE_SOUNDTRIGGER_SESSION: case RELEASE_SOUNDTRIGGER_SESSION: case MOVE_EFFECTS_TO_IO: ALOGW("%s: transaction %d received from PID %d", __func__, code, IPCThreadState::self()->getCallingPid()); // return status only for non void methods Loading Loading @@ -1700,6 +1718,31 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; case MOVE_EFFECTS_TO_IO: { CHECK_INTERFACE(IAudioPolicyService, data, reply); std::vector<int> ids; int32_t size; status_t status = data.readInt32(&size); if (status != NO_ERROR) { return status; } if (size > MAX_ITEMS_PER_LIST) { return BAD_VALUE; } for (int32_t i = 0; i < size; i++) { int id; status = data.readInt32(&id); if (status != NO_ERROR) { return status; } ids.push_back(id); } audio_io_handle_t io = data.readInt32(); reply->writeInt32(static_cast <int32_t>(moveEffectsToIo(ids, io))); return NO_ERROR; } break; case IS_STREAM_ACTIVE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_stream_type_t stream = (audio_stream_type_t) data.readInt32(); Loading media/libaudioclient/include/media/AudioSystem.h +1 −0 Original line number Diff line number Diff line Loading @@ -286,6 +286,7 @@ public: int id); static status_t unregisterEffect(int id); static status_t setEffectEnabled(int id, bool enabled); static status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io); // clear stream to output mapping cache (gStreamOutputMap) // and output configuration cache (gOutputs) Loading media/libaudioclient/include/media/IAudioPolicyService.h +1 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ public: int id) = 0; virtual status_t unregisterEffect(int id) = 0; virtual status_t setEffectEnabled(int id, bool enabled) = 0; virtual status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) = 0; virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0; virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0; Loading services/audioflinger/AudioFlinger.cpp +149 −71 Original line number Diff line number Diff line Loading @@ -687,6 +687,10 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, bool updatePid = (input.clientInfo.clientPid == -1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = input.clientInfo.clientUid; audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE; std::vector<int> effectIds; if (!isAudioServerOrMediaServerUid(callingUid)) { ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", Loading Loading @@ -851,7 +855,10 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, // no risk of deadlock because AudioFlinger::mLock is held Mutex::Autolock _dl(thread->mLock); Mutex::Autolock _sl(effectThread->mLock); moveEffectChain_l(sessionId, effectThread, thread, true); if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) { effectThreadId = thread->id(); effectIds = thread->getEffectIds_l(sessionId); } } // Look for sync events awaiting for a session to be used. Loading Loading @@ -885,6 +892,12 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, goto Exit; } // effectThreadId is not NONE if an effect chain corresponding to the track session // was found on another thread and must be moved on this thread if (effectThreadId != AUDIO_IO_HANDLE_NONE) { AudioSystem::moveEffectsToIo(effectIds, effectThreadId); } // return handle to client trackHandle = new TrackHandle(track); Loading Loading @@ -1225,7 +1238,8 @@ status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, if (output == AUDIO_IO_HANDLE_NONE) { return BAD_VALUE; } ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to change AUDIO_STREAM_PATCH volume"); ALOG_ASSERT(stream != AUDIO_STREAM_PATCH || value == 1.0, "attempt to change AUDIO_STREAM_PATCH volume"); AutoMutex lock(mLock); VolumeInterface *volumeInterface = getVolumeInterface_l(output); Loading Loading @@ -1629,6 +1643,8 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) } void AudioFlinger::removeNotificationClient(pid_t pid) { std::vector< sp<AudioFlinger::EffectModule> > removedEffects; { Mutex::Autolock _l(mLock); { Loading @@ -1653,7 +1669,11 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } } if (removed) { purgeStaleEffects_l(); removedEffects = purgeStaleEffects_l(); } } for (auto& effect : removedEffects) { effect->updatePolicyState(); } } Loading Loading @@ -2425,7 +2445,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), dstThread, true); dstThread); } } } Loading Loading @@ -2791,6 +2811,8 @@ void AudioFlinger::acquireAudioSessionId(audio_session_t audioSession, pid_t pid } void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) { std::vector< sp<EffectModule> > removedEffects; { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); Loading @@ -2808,9 +2830,10 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid if (ref->mCnt == 0) { mAudioSessionRefs.removeAt(i); delete ref; purgeStaleEffects_l(); std::vector< sp<EffectModule> > effects = purgeStaleEffects_l(); removedEffects.insert(removedEffects.end(), effects.begin(), effects.end()); } return; goto Exit; } } // If the caller is audioserver it is likely that the session being released was acquired Loading @@ -2819,6 +2842,12 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid "session id %d not found for pid %d", audioSession, caller); } Exit: for (auto& effect : removedEffects) { effect->updatePolicyState(); } } bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) { size_t num = mAudioSessionRefs.size(); Loading @@ -2831,11 +2860,12 @@ bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) return false; } void AudioFlinger::purgeStaleEffects_l() { std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() { ALOGV("purging stale effects"); Vector< sp<EffectChain> > chains; std::vector< sp<EffectModule> > removedEffects; for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> t = mPlaybackThreads.valueAt(i); Loading @@ -2847,6 +2877,7 @@ void AudioFlinger::purgeStaleEffects_l() { } } } for (size_t i = 0; i < mRecordThreads.size(); i++) { sp<RecordThread> t = mRecordThreads.valueAt(i); Mutex::Autolock _l(t->mLock); Loading @@ -2856,6 +2887,15 @@ void AudioFlinger::purgeStaleEffects_l() { } } for (size_t i = 0; i < mMmapThreads.size(); i++) { 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]; chains.push(ec); } } for (size_t i = 0; i < chains.size(); i++) { sp<EffectChain> ec = chains[i]; int sessionid = ec->sessionId(); Loading Loading @@ -2884,11 +2924,11 @@ void AudioFlinger::purgeStaleEffects_l() { if (effect->purgeHandles()) { t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId()); } AudioSystem::unregisterEffect(effect->id()); removedEffects.push_back(effect); } } } return; return removedEffects; } // dumpToThreadLog_l() must be called with AudioFlinger::mLock held Loading Loading @@ -3380,8 +3420,16 @@ sp<IEffect> AudioFlinger::createEffect( } } if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) { // handle must be cleared outside lock. if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) { // Check CPU and memory usage sp<EffectModule> effect = handle->effect().promote(); if (effect != nullptr) { status_t rStatus = effect->updatePolicyState(); if (rStatus != NO_ERROR) { lStatus = rStatus; } } } else { handle.clear(); } Loading Loading @@ -3413,14 +3461,13 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(srcThread->mLock); return moveEffectChain_l(sessionId, srcThread, dstThread, false); return moveEffectChain_l(sessionId, srcThread, dstThread); } // moveEffectChain_l must be called with both srcThread and dstThread mLocks held status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, AudioFlinger::PlaybackThread *srcThread, AudioFlinger::PlaybackThread *dstThread, bool reRegister) AudioFlinger::PlaybackThread *dstThread) { ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); Loading Loading @@ -3476,33 +3523,64 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, } strategy = dstChain->strategy(); } if (reRegister) { AudioSystem::unregisterEffect(effect->id()); AudioSystem::registerEffect(&effect->desc(), dstThread->id(), strategy, sessionId, effect->id()); AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } effect = chain->getEffectFromId_l(0); } if (status != NO_ERROR) { for (size_t i = 0; i < removed.size(); i++) { srcThread->addEffect_l(removed[i]); if (dstChain != 0 && reRegister) { AudioSystem::unregisterEffect(removed[i]->id()); AudioSystem::registerEffect(&removed[i]->desc(), srcThread->id(), strategy, sessionId, removed[i]->id()); AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } } return status; } status_t AudioFlinger::moveAuxEffectToIo(int EffectId, const sp<PlaybackThread>& dstThread, sp<PlaybackThread> *srcThread) { status_t status = NO_ERROR; Mutex::Autolock _l(mLock); sp<PlaybackThread> thread = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, 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; if (srcChain == 0) { return INVALID_OPERATION; } sp<EffectModule> effect = srcChain->getEffectFromId_l(EffectId); if (effect == 0) { return INVALID_OPERATION; } thread->removeEffect_l(effect); status = dstThread->addEffect_l(effect); if (status != NO_ERROR) { thread->addEffect_l(effect); status = INVALID_OPERATION; goto Exit; } dstChain = effect->chain().promote(); if (dstChain == 0) { thread->addEffect_l(effect); status = INVALID_OPERATION; } 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) { effect->start(); } } if (status == NO_ERROR && srcThread != nullptr) { *srcThread = thread; } return status; } Loading Loading
media/libaudioclient/AudioSystem.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -1067,6 +1067,13 @@ status_t AudioSystem::setEffectEnabled(int id, bool enabled) return aps->setEffectEnabled(id, enabled); } status_t AudioSystem::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->moveEffectsToIo(ids, io); } status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); Loading
media/libaudioclient/IAudioPolicyService.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ enum { LIST_AUDIO_VOLUME_GROUPS, GET_VOLUME_GROUP_FOR_ATTRIBUTES, SET_ALLOWED_CAPTURE_POLICY, MOVE_EFFECTS_TO_IO, }; #define MAX_ITEMS_PER_LIST 1024 Loading Loading @@ -550,6 +551,22 @@ public: return static_cast <status_t> (reply.readInt32()); } status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(ids.size()); for (auto id : ids) { data.writeInt32(id); } data.writeInt32(io); status_t status = remote()->transact(MOVE_EFFECTS_TO_IO, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const { Parcel data, reply; Loading Loading @@ -1284,6 +1301,7 @@ status_t BnAudioPolicyService::onTransact( case GET_OUTPUT_FOR_ATTR: case ACQUIRE_SOUNDTRIGGER_SESSION: case RELEASE_SOUNDTRIGGER_SESSION: case MOVE_EFFECTS_TO_IO: ALOGW("%s: transaction %d received from PID %d", __func__, code, IPCThreadState::self()->getCallingPid()); // return status only for non void methods Loading Loading @@ -1700,6 +1718,31 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; case MOVE_EFFECTS_TO_IO: { CHECK_INTERFACE(IAudioPolicyService, data, reply); std::vector<int> ids; int32_t size; status_t status = data.readInt32(&size); if (status != NO_ERROR) { return status; } if (size > MAX_ITEMS_PER_LIST) { return BAD_VALUE; } for (int32_t i = 0; i < size; i++) { int id; status = data.readInt32(&id); if (status != NO_ERROR) { return status; } ids.push_back(id); } audio_io_handle_t io = data.readInt32(); reply->writeInt32(static_cast <int32_t>(moveEffectsToIo(ids, io))); return NO_ERROR; } break; case IS_STREAM_ACTIVE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_stream_type_t stream = (audio_stream_type_t) data.readInt32(); Loading
media/libaudioclient/include/media/AudioSystem.h +1 −0 Original line number Diff line number Diff line Loading @@ -286,6 +286,7 @@ public: int id); static status_t unregisterEffect(int id); static status_t setEffectEnabled(int id, bool enabled); static status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io); // clear stream to output mapping cache (gStreamOutputMap) // and output configuration cache (gOutputs) Loading
media/libaudioclient/include/media/IAudioPolicyService.h +1 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ public: int id) = 0; virtual status_t unregisterEffect(int id) = 0; virtual status_t setEffectEnabled(int id, bool enabled) = 0; virtual status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) = 0; virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0; virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0; Loading
services/audioflinger/AudioFlinger.cpp +149 −71 Original line number Diff line number Diff line Loading @@ -687,6 +687,10 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, bool updatePid = (input.clientInfo.clientPid == -1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = input.clientInfo.clientUid; audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE; std::vector<int> effectIds; if (!isAudioServerOrMediaServerUid(callingUid)) { ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", Loading Loading @@ -851,7 +855,10 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, // no risk of deadlock because AudioFlinger::mLock is held Mutex::Autolock _dl(thread->mLock); Mutex::Autolock _sl(effectThread->mLock); moveEffectChain_l(sessionId, effectThread, thread, true); if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) { effectThreadId = thread->id(); effectIds = thread->getEffectIds_l(sessionId); } } // Look for sync events awaiting for a session to be used. Loading Loading @@ -885,6 +892,12 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input, goto Exit; } // effectThreadId is not NONE if an effect chain corresponding to the track session // was found on another thread and must be moved on this thread if (effectThreadId != AUDIO_IO_HANDLE_NONE) { AudioSystem::moveEffectsToIo(effectIds, effectThreadId); } // return handle to client trackHandle = new TrackHandle(track); Loading Loading @@ -1225,7 +1238,8 @@ status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, if (output == AUDIO_IO_HANDLE_NONE) { return BAD_VALUE; } ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to change AUDIO_STREAM_PATCH volume"); ALOG_ASSERT(stream != AUDIO_STREAM_PATCH || value == 1.0, "attempt to change AUDIO_STREAM_PATCH volume"); AutoMutex lock(mLock); VolumeInterface *volumeInterface = getVolumeInterface_l(output); Loading Loading @@ -1629,6 +1643,8 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) } void AudioFlinger::removeNotificationClient(pid_t pid) { std::vector< sp<AudioFlinger::EffectModule> > removedEffects; { Mutex::Autolock _l(mLock); { Loading @@ -1653,7 +1669,11 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } } if (removed) { purgeStaleEffects_l(); removedEffects = purgeStaleEffects_l(); } } for (auto& effect : removedEffects) { effect->updatePolicyState(); } } Loading Loading @@ -2425,7 +2445,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), dstThread, true); dstThread); } } } Loading Loading @@ -2791,6 +2811,8 @@ void AudioFlinger::acquireAudioSessionId(audio_session_t audioSession, pid_t pid } void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) { std::vector< sp<EffectModule> > removedEffects; { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); Loading @@ -2808,9 +2830,10 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid if (ref->mCnt == 0) { mAudioSessionRefs.removeAt(i); delete ref; purgeStaleEffects_l(); std::vector< sp<EffectModule> > effects = purgeStaleEffects_l(); removedEffects.insert(removedEffects.end(), effects.begin(), effects.end()); } return; goto Exit; } } // If the caller is audioserver it is likely that the session being released was acquired Loading @@ -2819,6 +2842,12 @@ void AudioFlinger::releaseAudioSessionId(audio_session_t audioSession, pid_t pid "session id %d not found for pid %d", audioSession, caller); } Exit: for (auto& effect : removedEffects) { effect->updatePolicyState(); } } bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) { size_t num = mAudioSessionRefs.size(); Loading @@ -2831,11 +2860,12 @@ bool AudioFlinger::isSessionAcquired_l(audio_session_t audioSession) return false; } void AudioFlinger::purgeStaleEffects_l() { std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l() { ALOGV("purging stale effects"); Vector< sp<EffectChain> > chains; std::vector< sp<EffectModule> > removedEffects; for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> t = mPlaybackThreads.valueAt(i); Loading @@ -2847,6 +2877,7 @@ void AudioFlinger::purgeStaleEffects_l() { } } } for (size_t i = 0; i < mRecordThreads.size(); i++) { sp<RecordThread> t = mRecordThreads.valueAt(i); Mutex::Autolock _l(t->mLock); Loading @@ -2856,6 +2887,15 @@ void AudioFlinger::purgeStaleEffects_l() { } } for (size_t i = 0; i < mMmapThreads.size(); i++) { 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]; chains.push(ec); } } for (size_t i = 0; i < chains.size(); i++) { sp<EffectChain> ec = chains[i]; int sessionid = ec->sessionId(); Loading Loading @@ -2884,11 +2924,11 @@ void AudioFlinger::purgeStaleEffects_l() { if (effect->purgeHandles()) { t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId()); } AudioSystem::unregisterEffect(effect->id()); removedEffects.push_back(effect); } } } return; return removedEffects; } // dumpToThreadLog_l() must be called with AudioFlinger::mLock held Loading Loading @@ -3380,8 +3420,16 @@ sp<IEffect> AudioFlinger::createEffect( } } if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) { // handle must be cleared outside lock. if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) { // Check CPU and memory usage sp<EffectModule> effect = handle->effect().promote(); if (effect != nullptr) { status_t rStatus = effect->updatePolicyState(); if (rStatus != NO_ERROR) { lStatus = rStatus; } } } else { handle.clear(); } Loading Loading @@ -3413,14 +3461,13 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(srcThread->mLock); return moveEffectChain_l(sessionId, srcThread, dstThread, false); return moveEffectChain_l(sessionId, srcThread, dstThread); } // moveEffectChain_l must be called with both srcThread and dstThread mLocks held status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, AudioFlinger::PlaybackThread *srcThread, AudioFlinger::PlaybackThread *dstThread, bool reRegister) AudioFlinger::PlaybackThread *dstThread) { ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); Loading Loading @@ -3476,33 +3523,64 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, } strategy = dstChain->strategy(); } if (reRegister) { AudioSystem::unregisterEffect(effect->id()); AudioSystem::registerEffect(&effect->desc(), dstThread->id(), strategy, sessionId, effect->id()); AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } effect = chain->getEffectFromId_l(0); } if (status != NO_ERROR) { for (size_t i = 0; i < removed.size(); i++) { srcThread->addEffect_l(removed[i]); if (dstChain != 0 && reRegister) { AudioSystem::unregisterEffect(removed[i]->id()); AudioSystem::registerEffect(&removed[i]->desc(), srcThread->id(), strategy, sessionId, removed[i]->id()); AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } } return status; } status_t AudioFlinger::moveAuxEffectToIo(int EffectId, const sp<PlaybackThread>& dstThread, sp<PlaybackThread> *srcThread) { status_t status = NO_ERROR; Mutex::Autolock _l(mLock); sp<PlaybackThread> thread = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, 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; if (srcChain == 0) { return INVALID_OPERATION; } sp<EffectModule> effect = srcChain->getEffectFromId_l(EffectId); if (effect == 0) { return INVALID_OPERATION; } thread->removeEffect_l(effect); status = dstThread->addEffect_l(effect); if (status != NO_ERROR) { thread->addEffect_l(effect); status = INVALID_OPERATION; goto Exit; } dstChain = effect->chain().promote(); if (dstChain == 0) { thread->addEffect_l(effect); status = INVALID_OPERATION; } 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) { effect->start(); } } if (status == NO_ERROR && srcThread != nullptr) { *srcThread = thread; } return status; } Loading