xref: /aosp_15_r20/frameworks/av/services/audioflinger/DeviceEffectManager.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2019, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "DeviceEffectManager"
19*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include "DeviceEffectManager.h"
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include "EffectConfiguration.h"
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker #include <afutils/FallibleLockGuard.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/primitives.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/audiohal/EffectsFactoryHalInterface.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker namespace android {
34*ec779b8eSAndroid Build Coastguard Worker 
35*ec779b8eSAndroid Build Coastguard Worker using detail::AudioHalVersionInfo;
36*ec779b8eSAndroid Build Coastguard Worker using media::IEffectClient;
37*ec779b8eSAndroid Build Coastguard Worker 
DeviceEffectManager(const sp<IAfDeviceEffectManagerCallback> & afDeviceEffectManagerCallback)38*ec779b8eSAndroid Build Coastguard Worker DeviceEffectManager::DeviceEffectManager(
39*ec779b8eSAndroid Build Coastguard Worker         const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
40*ec779b8eSAndroid Build Coastguard Worker     : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
41*ec779b8eSAndroid Build Coastguard Worker       mMyCallback(sp<DeviceEffectManagerCallback>::make(*this)) {}
42*ec779b8eSAndroid Build Coastguard Worker 
onFirstRef()43*ec779b8eSAndroid Build Coastguard Worker void DeviceEffectManager::onFirstRef() {
44*ec779b8eSAndroid Build Coastguard Worker     mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
45*ec779b8eSAndroid Build Coastguard Worker }
46*ec779b8eSAndroid Build Coastguard Worker 
addEffectToHal(const struct audio_port_config * device,const sp<EffectHalInterface> & effect)47*ec779b8eSAndroid Build Coastguard Worker status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
48*ec779b8eSAndroid Build Coastguard Worker         const sp<EffectHalInterface>& effect) {
49*ec779b8eSAndroid Build Coastguard Worker     return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
50*ec779b8eSAndroid Build Coastguard Worker };
51*ec779b8eSAndroid Build Coastguard Worker 
removeEffectFromHal(const struct audio_port_config * device,const sp<EffectHalInterface> & effect)52*ec779b8eSAndroid Build Coastguard Worker status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
53*ec779b8eSAndroid Build Coastguard Worker         const sp<EffectHalInterface>& effect) {
54*ec779b8eSAndroid Build Coastguard Worker     return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
55*ec779b8eSAndroid Build Coastguard Worker };
56*ec779b8eSAndroid Build Coastguard Worker 
onCreateAudioPatch(audio_patch_handle_t handle,const IAfPatchPanel::Patch & patch)57*ec779b8eSAndroid Build Coastguard Worker void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
58*ec779b8eSAndroid Build Coastguard Worker         const IAfPatchPanel::Patch& patch) {
59*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s handle %d mHalHandle %d device sink %08x",
60*ec779b8eSAndroid Build Coastguard Worker             __func__, handle, patch.mHalHandle,
61*ec779b8eSAndroid Build Coastguard Worker             patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
62*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
63*ec779b8eSAndroid Build Coastguard Worker     for (auto& effectProxies : mDeviceEffects) {
64*ec779b8eSAndroid Build Coastguard Worker         for (auto& effect : effectProxies.second) {
65*ec779b8eSAndroid Build Coastguard Worker             const status_t status = effect->onCreatePatch(handle, patch);
66*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s Effect onCreatePatch status %d", __func__, status);
67*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
68*ec779b8eSAndroid Build Coastguard Worker         }
69*ec779b8eSAndroid Build Coastguard Worker     }
70*ec779b8eSAndroid Build Coastguard Worker }
71*ec779b8eSAndroid Build Coastguard Worker 
onReleaseAudioPatch(audio_patch_handle_t handle)72*ec779b8eSAndroid Build Coastguard Worker void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
73*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __func__);
74*ec779b8eSAndroid Build Coastguard Worker     // Keep a reference on disconnected handle to delay destruction without lock held.
75*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<IAfEffectHandle>> disconnectedHandles{};
76*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
77*ec779b8eSAndroid Build Coastguard Worker     for (auto& effectProxies : mDeviceEffects) {
78*ec779b8eSAndroid Build Coastguard Worker         for (auto& effect : effectProxies.second) {
79*ec779b8eSAndroid Build Coastguard Worker             sp<IAfEffectHandle> disconnectedHandle = effect->onReleasePatch(handle);
80*ec779b8eSAndroid Build Coastguard Worker             if (disconnectedHandle != nullptr) {
81*ec779b8eSAndroid Build Coastguard Worker                 disconnectedHandles.push_back(std::move(disconnectedHandle));
82*ec779b8eSAndroid Build Coastguard Worker             }
83*ec779b8eSAndroid Build Coastguard Worker         }
84*ec779b8eSAndroid Build Coastguard Worker     }
85*ec779b8eSAndroid Build Coastguard Worker }
86*ec779b8eSAndroid Build Coastguard Worker 
onUpdateAudioPatch(audio_patch_handle_t oldHandle,audio_patch_handle_t newHandle,const IAfPatchPanel::Patch & patch)87*ec779b8eSAndroid Build Coastguard Worker void DeviceEffectManager::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
88*ec779b8eSAndroid Build Coastguard Worker         audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
89*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s oldhandle %d newHandle %d mHalHandle %d device sink %08x",
90*ec779b8eSAndroid Build Coastguard Worker             __func__, oldHandle, newHandle, patch.mHalHandle,
91*ec779b8eSAndroid Build Coastguard Worker             patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
92*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
93*ec779b8eSAndroid Build Coastguard Worker     for (auto& effectProxies : mDeviceEffects) {
94*ec779b8eSAndroid Build Coastguard Worker         for (auto& effect : effectProxies.second) {
95*ec779b8eSAndroid Build Coastguard Worker             const status_t status = effect->onUpdatePatch(oldHandle, newHandle, patch);
96*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s Effect onUpdatePatch status %d", __func__, status);
97*ec779b8eSAndroid Build Coastguard Worker             ALOGW_IF(status != NO_ERROR, "%s onUpdatePatch error %d", __func__, status);
98*ec779b8eSAndroid Build Coastguard Worker         }
99*ec779b8eSAndroid Build Coastguard Worker     }
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker 
102*ec779b8eSAndroid Build Coastguard Worker // DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mutex() held
createEffect_l(effect_descriptor_t * descriptor,const AudioDeviceTypeAddr & device,const sp<Client> & client,const sp<IEffectClient> & effectClient,const std::map<audio_patch_handle_t,IAfPatchPanel::Patch> & patches,int * enabled,status_t * status,bool probe,bool notifyFramesProcessed)103*ec779b8eSAndroid Build Coastguard Worker sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
104*ec779b8eSAndroid Build Coastguard Worker         effect_descriptor_t *descriptor,
105*ec779b8eSAndroid Build Coastguard Worker         const AudioDeviceTypeAddr& device,
106*ec779b8eSAndroid Build Coastguard Worker         const sp<Client>& client,
107*ec779b8eSAndroid Build Coastguard Worker         const sp<IEffectClient>& effectClient,
108*ec779b8eSAndroid Build Coastguard Worker         const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
109*ec779b8eSAndroid Build Coastguard Worker         int *enabled,
110*ec779b8eSAndroid Build Coastguard Worker         status_t *status,
111*ec779b8eSAndroid Build Coastguard Worker         bool probe,
112*ec779b8eSAndroid Build Coastguard Worker         bool notifyFramesProcessed) {
113*ec779b8eSAndroid Build Coastguard Worker     sp<IAfDeviceEffectProxy> effect;
114*ec779b8eSAndroid Build Coastguard Worker     std::vector<sp<IAfDeviceEffectProxy>> effectsForDevice = {};
115*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectHandle> handle;
116*ec779b8eSAndroid Build Coastguard Worker     status_t lStatus;
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker     lStatus = checkEffectCompatibility(descriptor);
119*ec779b8eSAndroid Build Coastguard Worker     if (probe || lStatus != NO_ERROR) {
120*ec779b8eSAndroid Build Coastguard Worker        *status = lStatus;
121*ec779b8eSAndroid Build Coastguard Worker        return handle;
122*ec779b8eSAndroid Build Coastguard Worker     }
123*ec779b8eSAndroid Build Coastguard Worker 
124*ec779b8eSAndroid Build Coastguard Worker     {
125*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
126*ec779b8eSAndroid Build Coastguard Worker         auto iter = mDeviceEffects.find(device);
127*ec779b8eSAndroid Build Coastguard Worker         if (iter != mDeviceEffects.end()) {
128*ec779b8eSAndroid Build Coastguard Worker             effectsForDevice = iter->second;
129*ec779b8eSAndroid Build Coastguard Worker             for (const auto& iterEffect : effectsForDevice) {
130*ec779b8eSAndroid Build Coastguard Worker                 if (memcmp(&iterEffect->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) ==
131*ec779b8eSAndroid Build Coastguard Worker                     0) {
132*ec779b8eSAndroid Build Coastguard Worker                     effect = iterEffect;
133*ec779b8eSAndroid Build Coastguard Worker                     break;
134*ec779b8eSAndroid Build Coastguard Worker                 }
135*ec779b8eSAndroid Build Coastguard Worker             }
136*ec779b8eSAndroid Build Coastguard Worker         }
137*ec779b8eSAndroid Build Coastguard Worker         if (effect == nullptr) {
138*ec779b8eSAndroid Build Coastguard Worker             effect = IAfDeviceEffectProxy::create(device, mMyCallback,
139*ec779b8eSAndroid Build Coastguard Worker                     descriptor,
140*ec779b8eSAndroid Build Coastguard Worker                     mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
141*ec779b8eSAndroid Build Coastguard Worker                     notifyFramesProcessed);
142*ec779b8eSAndroid Build Coastguard Worker             effectsForDevice.push_back(effect);
143*ec779b8eSAndroid Build Coastguard Worker         }
144*ec779b8eSAndroid Build Coastguard Worker         // create effect handle and connect it to effect module
145*ec779b8eSAndroid Build Coastguard Worker         handle = IAfEffectHandle::create(
146*ec779b8eSAndroid Build Coastguard Worker                 effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed);
147*ec779b8eSAndroid Build Coastguard Worker         lStatus = handle->initCheck();
148*ec779b8eSAndroid Build Coastguard Worker         if (lStatus == NO_ERROR) {
149*ec779b8eSAndroid Build Coastguard Worker             lStatus = effect->addHandle(handle.get());
150*ec779b8eSAndroid Build Coastguard Worker             if (lStatus == NO_ERROR) {
151*ec779b8eSAndroid Build Coastguard Worker                 lStatus = effect->init_l(patches);
152*ec779b8eSAndroid Build Coastguard Worker                 if (lStatus == NAME_NOT_FOUND) {
153*ec779b8eSAndroid Build Coastguard Worker                     lStatus = NO_ERROR;
154*ec779b8eSAndroid Build Coastguard Worker                 }
155*ec779b8eSAndroid Build Coastguard Worker                 if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
156*ec779b8eSAndroid Build Coastguard Worker                     mDeviceEffects.erase(device);
157*ec779b8eSAndroid Build Coastguard Worker                     mDeviceEffects.emplace(device, effectsForDevice);
158*ec779b8eSAndroid Build Coastguard Worker                 }
159*ec779b8eSAndroid Build Coastguard Worker             }
160*ec779b8eSAndroid Build Coastguard Worker         }
161*ec779b8eSAndroid Build Coastguard Worker     }
162*ec779b8eSAndroid Build Coastguard Worker     if (enabled != nullptr) {
163*ec779b8eSAndroid Build Coastguard Worker         *enabled = (int)effect->isEnabled();
164*ec779b8eSAndroid Build Coastguard Worker     }
165*ec779b8eSAndroid Build Coastguard Worker     *status = lStatus;
166*ec779b8eSAndroid Build Coastguard Worker     return handle;
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker 
169*ec779b8eSAndroid Build Coastguard Worker /* static */
checkEffectCompatibility(const effect_descriptor_t * desc)170*ec779b8eSAndroid Build Coastguard Worker status_t DeviceEffectManager::checkEffectCompatibility(
171*ec779b8eSAndroid Build Coastguard Worker         const effect_descriptor_t *desc) {
172*ec779b8eSAndroid Build Coastguard Worker     const sp<EffectsFactoryHalInterface> effectsFactory =
173*ec779b8eSAndroid Build Coastguard Worker             audioflinger::EffectConfiguration::getEffectsFactoryHal();
174*ec779b8eSAndroid Build Coastguard Worker     if (effectsFactory == nullptr) {
175*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
176*ec779b8eSAndroid Build Coastguard Worker     }
177*ec779b8eSAndroid Build Coastguard Worker 
178*ec779b8eSAndroid Build Coastguard Worker     static const AudioHalVersionInfo sMinDeviceEffectHalVersion =
179*ec779b8eSAndroid Build Coastguard Worker             AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
180*ec779b8eSAndroid Build Coastguard Worker     static const AudioHalVersionInfo halVersion =
181*ec779b8eSAndroid Build Coastguard Worker             audioflinger::EffectConfiguration::getAudioHalVersionInfo();
182*ec779b8eSAndroid Build Coastguard Worker 
183*ec779b8eSAndroid Build Coastguard Worker     // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
184*ec779b8eSAndroid Build Coastguard Worker     // long as the type, major and minor sequence doesn't change in the definition.
185*ec779b8eSAndroid Build Coastguard Worker     if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
186*ec779b8eSAndroid Build Coastguard Worker             && (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
187*ec779b8eSAndroid Build Coastguard Worker             || halVersion < sMinDeviceEffectHalVersion) {
188*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
189*ec779b8eSAndroid Build Coastguard Worker                 __func__, desc->name, halVersion.toString().c_str());
190*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
191*ec779b8eSAndroid Build Coastguard Worker     }
192*ec779b8eSAndroid Build Coastguard Worker 
193*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
194*ec779b8eSAndroid Build Coastguard Worker }
195*ec779b8eSAndroid Build Coastguard Worker 
196*ec779b8eSAndroid Build Coastguard Worker /* static */
createEffectHal(const effect_uuid_t * pEffectUuid,int32_t sessionId,int32_t deviceId,sp<EffectHalInterface> * effect)197*ec779b8eSAndroid Build Coastguard Worker status_t DeviceEffectManager::createEffectHal(
198*ec779b8eSAndroid Build Coastguard Worker         const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
199*ec779b8eSAndroid Build Coastguard Worker         sp<EffectHalInterface> *effect) {
200*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_INIT;
201*ec779b8eSAndroid Build Coastguard Worker     const sp<EffectsFactoryHalInterface> effectsFactory =
202*ec779b8eSAndroid Build Coastguard Worker             audioflinger::EffectConfiguration::getEffectsFactoryHal();
203*ec779b8eSAndroid Build Coastguard Worker     if (effectsFactory != 0) {
204*ec779b8eSAndroid Build Coastguard Worker         status = effectsFactory->createEffect(
205*ec779b8eSAndroid Build Coastguard Worker                 pEffectUuid, sessionId, AUDIO_IO_HANDLE_NONE, deviceId, effect);
206*ec779b8eSAndroid Build Coastguard Worker     }
207*ec779b8eSAndroid Build Coastguard Worker     return status;
208*ec779b8eSAndroid Build Coastguard Worker }
209*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd)210*ec779b8eSAndroid Build Coastguard Worker void DeviceEffectManager::dump(int fd)
211*ec779b8eSAndroid Build Coastguard Worker {
212*ec779b8eSAndroid Build Coastguard Worker     afutils::FallibleLockGuard l{mutex()};
213*ec779b8eSAndroid Build Coastguard Worker     if (!l) {
214*ec779b8eSAndroid Build Coastguard Worker         String8 result("DeviceEffectManager may be deadlocked\n");
215*ec779b8eSAndroid Build Coastguard Worker         write(fd, result.c_str(), result.size());
216*ec779b8eSAndroid Build Coastguard Worker     }
217*ec779b8eSAndroid Build Coastguard Worker 
218*ec779b8eSAndroid Build Coastguard Worker     String8 heading("\nDevice Effects:\n");
219*ec779b8eSAndroid Build Coastguard Worker     write(fd, heading.c_str(), heading.size());
220*ec779b8eSAndroid Build Coastguard Worker     for (const auto& iter : mDeviceEffects) {
221*ec779b8eSAndroid Build Coastguard Worker         String8 outStr;
222*ec779b8eSAndroid Build Coastguard Worker         outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
223*ec779b8eSAndroid Build Coastguard Worker                 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
224*ec779b8eSAndroid Build Coastguard Worker         for (const auto& effect : iter.second) {
225*ec779b8eSAndroid Build Coastguard Worker             write(fd, outStr.c_str(), outStr.size());
226*ec779b8eSAndroid Build Coastguard Worker             effect->dump2(fd, 4);
227*ec779b8eSAndroid Build Coastguard Worker         }
228*ec779b8eSAndroid Build Coastguard Worker     }
229*ec779b8eSAndroid Build Coastguard Worker }
230*ec779b8eSAndroid Build Coastguard Worker 
removeEffect(const sp<IAfDeviceEffectProxy> & effect)231*ec779b8eSAndroid Build Coastguard Worker size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
232*ec779b8eSAndroid Build Coastguard Worker {
233*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
234*ec779b8eSAndroid Build Coastguard Worker     const auto& iter = mDeviceEffects.find(effect->device());
235*ec779b8eSAndroid Build Coastguard Worker     if (iter != mDeviceEffects.end()) {
236*ec779b8eSAndroid Build Coastguard Worker         const auto& iterEffect = std::find_if(
237*ec779b8eSAndroid Build Coastguard Worker                 iter->second.begin(), iter->second.end(), [&effect](const auto& effectProxy) {
238*ec779b8eSAndroid Build Coastguard Worker                     return memcmp(&effectProxy->desc().uuid, &effect->desc().uuid,
239*ec779b8eSAndroid Build Coastguard Worker                             sizeof(effect_uuid_t)) == 0;
240*ec779b8eSAndroid Build Coastguard Worker                 });
241*ec779b8eSAndroid Build Coastguard Worker         if (iterEffect != iter->second.end()) {
242*ec779b8eSAndroid Build Coastguard Worker             iter->second.erase(iterEffect);
243*ec779b8eSAndroid Build Coastguard Worker             if (iter->second.empty()) {
244*ec779b8eSAndroid Build Coastguard Worker                 mDeviceEffects.erase(effect->device());
245*ec779b8eSAndroid Build Coastguard Worker             }
246*ec779b8eSAndroid Build Coastguard Worker         }
247*ec779b8eSAndroid Build Coastguard Worker     }
248*ec779b8eSAndroid Build Coastguard Worker     return mDeviceEffects.size();
249*ec779b8eSAndroid Build Coastguard Worker }
250*ec779b8eSAndroid Build Coastguard Worker 
disconnectEffectHandle(IAfEffectHandle * handle,bool unpinIfLast)251*ec779b8eSAndroid Build Coastguard Worker bool DeviceEffectManagerCallback::disconnectEffectHandle(
252*ec779b8eSAndroid Build Coastguard Worker         IAfEffectHandle *handle, bool unpinIfLast) {
253*ec779b8eSAndroid Build Coastguard Worker     sp<IAfEffectBase> effectBase = handle->effect().promote();
254*ec779b8eSAndroid Build Coastguard Worker     if (effectBase == nullptr) {
255*ec779b8eSAndroid Build Coastguard Worker         return false;
256*ec779b8eSAndroid Build Coastguard Worker     }
257*ec779b8eSAndroid Build Coastguard Worker 
258*ec779b8eSAndroid Build Coastguard Worker     sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy();
259*ec779b8eSAndroid Build Coastguard Worker     if (effect == nullptr) {
260*ec779b8eSAndroid Build Coastguard Worker         return false;
261*ec779b8eSAndroid Build Coastguard Worker     }
262*ec779b8eSAndroid Build Coastguard Worker     // restore suspended effects if the disconnected handle was enabled and the last one.
263*ec779b8eSAndroid Build Coastguard Worker     bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
264*ec779b8eSAndroid Build Coastguard Worker     if (remove) {
265*ec779b8eSAndroid Build Coastguard Worker         mManager.removeEffect(effect);
266*ec779b8eSAndroid Build Coastguard Worker         if (handle->enabled()) {
267*ec779b8eSAndroid Build Coastguard Worker             effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
268*ec779b8eSAndroid Build Coastguard Worker         }
269*ec779b8eSAndroid Build Coastguard Worker     }
270*ec779b8eSAndroid Build Coastguard Worker     return true;
271*ec779b8eSAndroid Build Coastguard Worker }
272*ec779b8eSAndroid Build Coastguard Worker 
isAudioPolicyReady() const273*ec779b8eSAndroid Build Coastguard Worker bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
274*ec779b8eSAndroid Build Coastguard Worker     return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker 
newEffectId() const277*ec779b8eSAndroid Build Coastguard Worker int DeviceEffectManagerCallback::newEffectId() const {
278*ec779b8eSAndroid Build Coastguard Worker     return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
279*ec779b8eSAndroid Build Coastguard Worker }
280*ec779b8eSAndroid Build Coastguard Worker 
281*ec779b8eSAndroid Build Coastguard Worker } // namespace android
282