blob: ebb2428931e0a985b1ad0c70143302707eef815b [file] [log] [blame]
Eric Laurentb82e6b72019-11-22 17:25:04 -08001/*
2**
3** Copyright 2019, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
Andy Hungdf397962023-07-13 19:54:47 -070018#define LOG_TAG "DeviceEffectManager"
Eric Laurentb82e6b72019-11-22 17:25:04 -080019//#define LOG_NDEBUG 0
20
Andy Hungf2f5d642023-07-18 20:54:44 -070021#include "DeviceEffectManager.h"
Eric Laurentb82e6b72019-11-22 17:25:04 -080022
Andy Hungba8e52b2023-05-11 14:33:03 -070023#include "EffectConfiguration.h"
Andy Hungf2f5d642023-07-18 20:54:44 -070024
25#include <afutils/DumpTryLock.h>
26#include <audio_utils/primitives.h>
Eric Laurentb82e6b72019-11-22 17:25:04 -080027#include <media/audiohal/EffectsFactoryHalInterface.h>
Andy Hungf2f5d642023-07-18 20:54:44 -070028#include <utils/Log.h>
Eric Laurentb82e6b72019-11-22 17:25:04 -080029
30// ----------------------------------------------------------------------------
31
32
33namespace android {
34
Shunkai Yaod7ea4092022-12-12 00:44:33 +000035using detail::AudioHalVersionInfo;
Ytai Ben-Tsvi9cd89812020-07-01 17:12:06 -070036using media::IEffectClient;
37
Andy Hung13e99b32023-07-17 13:45:55 -070038DeviceEffectManager::DeviceEffectManager(
39 const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
40 : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
Andy Hungdf397962023-07-13 19:54:47 -070041 mMyCallback(new DeviceEffectManagerCallback(*this)) {}
42
43void DeviceEffectManager::onFirstRef() {
Andy Hung13e99b32023-07-17 13:45:55 -070044 mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
Andy Hungdf397962023-07-13 19:54:47 -070045}
46
47status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
48 const sp<EffectHalInterface>& effect) {
Andy Hung13e99b32023-07-17 13:45:55 -070049 return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
Andy Hungdf397962023-07-13 19:54:47 -070050};
51
52status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
53 const sp<EffectHalInterface>& effect) {
Andy Hung13e99b32023-07-17 13:45:55 -070054 return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
Andy Hungdf397962023-07-13 19:54:47 -070055};
56
57void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
Andy Hungc0ab56b2023-07-13 18:11:33 -070058 const IAfPatchPanel::Patch& patch) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080059 ALOGV("%s handle %d mHalHandle %d device sink %08x",
60 __func__, handle, patch.mHalHandle,
61 patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
62 Mutex::Autolock _l(mLock);
63 for (auto& effect : mDeviceEffects) {
Andy Hungc0ab56b2023-07-13 18:11:33 -070064 status_t status = effect.second->onCreatePatch(handle, patch);
Eric Laurentb82e6b72019-11-22 17:25:04 -080065 ALOGV("%s Effect onCreatePatch status %d", __func__, status);
66 ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
67 }
68}
69
Andy Hungdf397962023-07-13 19:54:47 -070070void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080071 ALOGV("%s", __func__);
72 Mutex::Autolock _l(mLock);
73 for (auto& effect : mDeviceEffects) {
74 effect.second->onReleasePatch(handle);
75 }
76}
77
78// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
Andy Hungdf397962023-07-13 19:54:47 -070079sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
Eric Laurentb82e6b72019-11-22 17:25:04 -080080 effect_descriptor_t *descriptor,
81 const AudioDeviceTypeAddr& device,
Andy Hung88035ac2023-06-27 17:05:02 -070082 const sp<Client>& client,
Eric Laurentb82e6b72019-11-22 17:25:04 -080083 const sp<IEffectClient>& effectClient,
Andy Hungc0ab56b2023-07-13 18:11:33 -070084 const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
Eric Laurentb82e6b72019-11-22 17:25:04 -080085 int *enabled,
Eric Laurent2fe0acd2020-03-13 14:30:46 -070086 status_t *status,
Eric Laurentde8caf42021-08-11 17:19:25 +020087 bool probe,
88 bool notifyFramesProcessed) {
Andy Hung116bc262023-06-20 18:56:17 -070089 sp<IAfDeviceEffectProxy> effect;
90 sp<IAfEffectHandle> handle;
Eric Laurentb82e6b72019-11-22 17:25:04 -080091 status_t lStatus;
92
93 lStatus = checkEffectCompatibility(descriptor);
Eric Laurent2fe0acd2020-03-13 14:30:46 -070094 if (probe || lStatus != NO_ERROR) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080095 *status = lStatus;
96 return handle;
97 }
98
99 {
100 Mutex::Autolock _l(mLock);
101 auto iter = mDeviceEffects.find(device);
102 if (iter != mDeviceEffects.end()) {
103 effect = iter->second;
104 } else {
Andy Hung116bc262023-06-20 18:56:17 -0700105 effect = IAfDeviceEffectProxy::create(device, mMyCallback,
Andy Hung13e99b32023-07-17 13:45:55 -0700106 descriptor,
107 mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
Eric Laurentde8caf42021-08-11 17:19:25 +0200108 notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800109 }
110 // create effect handle and connect it to effect module
Andy Hung116bc262023-06-20 18:56:17 -0700111 handle = IAfEffectHandle::create(
112 effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800113 lStatus = handle->initCheck();
114 if (lStatus == NO_ERROR) {
115 lStatus = effect->addHandle(handle.get());
116 if (lStatus == NO_ERROR) {
Andy Hungc0ab56b2023-07-13 18:11:33 -0700117 lStatus = effect->init(patches);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530118 if (lStatus == NAME_NOT_FOUND) {
119 lStatus = NO_ERROR;
120 }
121 if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
122 mDeviceEffects.emplace(device, effect);
123 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800124 }
125 }
126 }
Vlad Popa5161f8a2022-10-10 16:17:20 +0200127 if (enabled != nullptr) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800128 *enabled = (int)effect->isEnabled();
129 }
130 *status = lStatus;
131 return handle;
132}
133
Andy Hungdf397962023-07-13 19:54:47 -0700134status_t DeviceEffectManager::checkEffectCompatibility(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800135 const effect_descriptor_t *desc) {
Andy Hungba8e52b2023-05-11 14:33:03 -0700136 const sp<EffectsFactoryHalInterface> effectsFactory =
137 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurent9289bde2020-08-18 12:49:17 -0700138 if (effectsFactory == nullptr) {
139 return BAD_VALUE;
140 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800141
Andy Hungba8e52b2023-05-11 14:33:03 -0700142 static const AudioHalVersionInfo sMinDeviceEffectHalVersion =
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000143 AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
Andy Hungba8e52b2023-05-11 14:33:03 -0700144 static const AudioHalVersionInfo halVersion =
145 audioflinger::EffectConfiguration::getAudioHalVersionInfo();
Eric Laurent9289bde2020-08-18 12:49:17 -0700146
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000147 // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
148 // long as the type, major and minor sequence doesn't change in the definition.
Eric Laurent9289bde2020-08-18 12:49:17 -0700149 if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
150 && (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
151 || halVersion < sMinDeviceEffectHalVersion) {
Shunkai Yao489c5a92022-12-02 05:35:41 +0000152 ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
153 __func__, desc->name, halVersion.toString().c_str());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800154 return BAD_VALUE;
155 }
156
157 return NO_ERROR;
158}
159
Andy Hungdf397962023-07-13 19:54:47 -0700160status_t DeviceEffectManager::createEffectHal(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800161 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
162 sp<EffectHalInterface> *effect) {
163 status_t status = NO_INIT;
Andy Hungba8e52b2023-05-11 14:33:03 -0700164 const sp<EffectsFactoryHalInterface> effectsFactory =
165 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800166 if (effectsFactory != 0) {
167 status = effectsFactory->createEffect(
168 pEffectUuid, sessionId, AUDIO_IO_HANDLE_NONE, deviceId, effect);
169 }
170 return status;
171}
172
Andy Hungdf397962023-07-13 19:54:47 -0700173void DeviceEffectManager::dump(int fd)
Andy Hung920f6572022-10-06 12:09:49 -0700174NO_THREAD_SAFETY_ANALYSIS // conditional try lock
175{
Andy Hungf2f5d642023-07-18 20:54:44 -0700176 const bool locked = afutils::dumpTryLock(mLock);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800177 if (!locked) {
178 String8 result("DeviceEffectManager may be deadlocked\n");
179 write(fd, result.string(), result.size());
180 }
181
Phil Burk651d0a52020-05-08 14:00:58 -0700182 String8 heading("\nDevice Effects:\n");
183 write(fd, heading.string(), heading.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800184 for (const auto& iter : mDeviceEffects) {
185 String8 outStr;
186 outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
187 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
188 write(fd, outStr.string(), outStr.size());
Andy Hung116bc262023-06-20 18:56:17 -0700189 iter.second->dump2(fd, 4);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800190 }
191
192 if (locked) {
193 mLock.unlock();
194 }
195}
196
Andy Hungdf397962023-07-13 19:54:47 -0700197size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
Eric Laurentb82e6b72019-11-22 17:25:04 -0800198{
199 Mutex::Autolock _l(mLock);
200 mDeviceEffects.erase(effect->device());
201 return mDeviceEffects.size();
202}
203
Andy Hungdf397962023-07-13 19:54:47 -0700204bool DeviceEffectManagerCallback::disconnectEffectHandle(
Andy Hung116bc262023-06-20 18:56:17 -0700205 IAfEffectHandle *handle, bool unpinIfLast) {
206 sp<IAfEffectBase> effectBase = handle->effect().promote();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800207 if (effectBase == nullptr) {
208 return false;
209 }
210
Andy Hung116bc262023-06-20 18:56:17 -0700211 sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800212 if (effect == nullptr) {
213 return false;
214 }
215 // restore suspended effects if the disconnected handle was enabled and the last one.
216 bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
217 if (remove) {
218 mManager.removeEffect(effect);
219 if (handle->enabled()) {
220 effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
221 }
222 }
223 return true;
224}
225
Andy Hungdf397962023-07-13 19:54:47 -0700226bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
Andy Hung13e99b32023-07-17 13:45:55 -0700227 return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
Andy Hungdf397962023-07-13 19:54:47 -0700228}
229
230int DeviceEffectManagerCallback::newEffectId() const {
Andy Hung13e99b32023-07-17 13:45:55 -0700231 return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
Andy Hungdf397962023-07-13 19:54:47 -0700232}
233
Eric Laurentb82e6b72019-11-22 17:25:04 -0800234} // namespace android