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