blob: e689829cdf607c029545bb9122d3916f3e8ff990 [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
18
Andy Hungbf766942023-07-13 19:54:47 -070019#define LOG_TAG "DeviceEffectManager"
Eric Laurentb82e6b72019-11-22 17:25:04 -080020//#define LOG_NDEBUG 0
21
22#include <utils/Log.h>
23#include <audio_utils/primitives.h>
24
25#include "AudioFlinger.h"
Andy Hungba8e52b2023-05-11 14:33:03 -070026#include "EffectConfiguration.h"
Eric Laurentb82e6b72019-11-22 17:25:04 -080027#include <media/audiohal/EffectsFactoryHalInterface.h>
28
29// ----------------------------------------------------------------------------
30
31
32namespace android {
33
Shunkai Yaod7ea4092022-12-12 00:44:33 +000034using detail::AudioHalVersionInfo;
Ytai Ben-Tsvi9cd89812020-07-01 17:12:06 -070035using media::IEffectClient;
36
Andy Hunge9a1c7a2023-07-17 13:45:55 -070037DeviceEffectManager::DeviceEffectManager(
38 const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
39 : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
Andy Hungbf766942023-07-13 19:54:47 -070040 mMyCallback(new DeviceEffectManagerCallback(*this)) {}
41
42void DeviceEffectManager::onFirstRef() {
Andy Hunge9a1c7a2023-07-17 13:45:55 -070043 mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
Andy Hungbf766942023-07-13 19:54:47 -070044}
45
46status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
47 const sp<EffectHalInterface>& effect) {
Andy Hunge9a1c7a2023-07-17 13:45:55 -070048 return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
Andy Hungbf766942023-07-13 19:54:47 -070049};
50
51status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
52 const sp<EffectHalInterface>& effect) {
Andy Hunge9a1c7a2023-07-17 13:45:55 -070053 return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
Andy Hungbf766942023-07-13 19:54:47 -070054};
55
56void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
Andy Hung07434ef2023-07-13 18:11:33 -070057 const IAfPatchPanel::Patch& patch) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080058 ALOGV("%s handle %d mHalHandle %d device sink %08x",
59 __func__, handle, patch.mHalHandle,
60 patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
61 Mutex::Autolock _l(mLock);
62 for (auto& effect : mDeviceEffects) {
Andy Hung07434ef2023-07-13 18:11:33 -070063 status_t status = effect.second->onCreatePatch(handle, patch);
Eric Laurentb82e6b72019-11-22 17:25:04 -080064 ALOGV("%s Effect onCreatePatch status %d", __func__, status);
65 ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
66 }
67}
68
Andy Hungbf766942023-07-13 19:54:47 -070069void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080070 ALOGV("%s", __func__);
71 Mutex::Autolock _l(mLock);
72 for (auto& effect : mDeviceEffects) {
73 effect.second->onReleasePatch(handle);
74 }
75}
76
77// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
Andy Hungbf766942023-07-13 19:54:47 -070078sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
Eric Laurentb82e6b72019-11-22 17:25:04 -080079 effect_descriptor_t *descriptor,
80 const AudioDeviceTypeAddr& device,
Andy Hungd65869f2023-06-27 17:05:02 -070081 const sp<Client>& client,
Eric Laurentb82e6b72019-11-22 17:25:04 -080082 const sp<IEffectClient>& effectClient,
Andy Hung07434ef2023-07-13 18:11:33 -070083 const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
Eric Laurentb82e6b72019-11-22 17:25:04 -080084 int *enabled,
Eric Laurent2fe0acd2020-03-13 14:30:46 -070085 status_t *status,
Eric Laurentde8caf42021-08-11 17:19:25 +020086 bool probe,
87 bool notifyFramesProcessed) {
Andy Hungbd72c542023-06-20 18:56:17 -070088 sp<IAfDeviceEffectProxy> effect;
89 sp<IAfEffectHandle> handle;
Eric Laurentb82e6b72019-11-22 17:25:04 -080090 status_t lStatus;
91
92 lStatus = checkEffectCompatibility(descriptor);
Eric Laurent2fe0acd2020-03-13 14:30:46 -070093 if (probe || lStatus != NO_ERROR) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080094 *status = lStatus;
95 return handle;
96 }
97
98 {
99 Mutex::Autolock _l(mLock);
100 auto iter = mDeviceEffects.find(device);
101 if (iter != mDeviceEffects.end()) {
102 effect = iter->second;
103 } else {
Andy Hungbd72c542023-06-20 18:56:17 -0700104 effect = IAfDeviceEffectProxy::create(device, mMyCallback,
Andy Hunge9a1c7a2023-07-17 13:45:55 -0700105 descriptor,
106 mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
Eric Laurentde8caf42021-08-11 17:19:25 +0200107 notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800108 }
109 // create effect handle and connect it to effect module
Andy Hungbd72c542023-06-20 18:56:17 -0700110 handle = IAfEffectHandle::create(
111 effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800112 lStatus = handle->initCheck();
113 if (lStatus == NO_ERROR) {
114 lStatus = effect->addHandle(handle.get());
115 if (lStatus == NO_ERROR) {
Andy Hung07434ef2023-07-13 18:11:33 -0700116 lStatus = effect->init(patches);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530117 if (lStatus == NAME_NOT_FOUND) {
118 lStatus = NO_ERROR;
119 }
120 if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
121 mDeviceEffects.emplace(device, effect);
122 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800123 }
124 }
125 }
Vlad Popa5161f8a2022-10-10 16:17:20 +0200126 if (enabled != nullptr) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800127 *enabled = (int)effect->isEnabled();
128 }
129 *status = lStatus;
130 return handle;
131}
132
Andy Hungbf766942023-07-13 19:54:47 -0700133status_t DeviceEffectManager::checkEffectCompatibility(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800134 const effect_descriptor_t *desc) {
Andy Hungba8e52b2023-05-11 14:33:03 -0700135 const sp<EffectsFactoryHalInterface> effectsFactory =
136 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurent9289bde2020-08-18 12:49:17 -0700137 if (effectsFactory == nullptr) {
138 return BAD_VALUE;
139 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800140
Andy Hungba8e52b2023-05-11 14:33:03 -0700141 static const AudioHalVersionInfo sMinDeviceEffectHalVersion =
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000142 AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
Andy Hungba8e52b2023-05-11 14:33:03 -0700143 static const AudioHalVersionInfo halVersion =
144 audioflinger::EffectConfiguration::getAudioHalVersionInfo();
Eric Laurent9289bde2020-08-18 12:49:17 -0700145
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000146 // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
147 // long as the type, major and minor sequence doesn't change in the definition.
Eric Laurent9289bde2020-08-18 12:49:17 -0700148 if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
149 && (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
150 || halVersion < sMinDeviceEffectHalVersion) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000151 ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
152 __func__, desc->name, halVersion.toString().c_str());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800153 return BAD_VALUE;
154 }
155
156 return NO_ERROR;
157}
158
Andy Hungbf766942023-07-13 19:54:47 -0700159status_t DeviceEffectManager::createEffectHal(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800160 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
161 sp<EffectHalInterface> *effect) {
162 status_t status = NO_INIT;
Andy Hungba8e52b2023-05-11 14:33:03 -0700163 const sp<EffectsFactoryHalInterface> effectsFactory =
164 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800165 if (effectsFactory != 0) {
166 status = effectsFactory->createEffect(
167 pEffectUuid, sessionId, AUDIO_IO_HANDLE_NONE, deviceId, effect);
168 }
169 return status;
170}
171
Andy Hungbf766942023-07-13 19:54:47 -0700172void DeviceEffectManager::dump(int fd)
Andy Hung71ba4b32022-10-06 12:09:49 -0700173NO_THREAD_SAFETY_ANALYSIS // conditional try lock
174{
Andy Hungbf766942023-07-13 19:54:47 -0700175 const bool locked = AudioFlinger::dumpTryLock(mLock);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800176 if (!locked) {
177 String8 result("DeviceEffectManager may be deadlocked\n");
Tomasz Wasilczyk8f36f6e2023-08-15 20:59:35 +0000178 write(fd, result.c_str(), result.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800179 }
180
Phil Burk651d0a52020-05-08 14:00:58 -0700181 String8 heading("\nDevice Effects:\n");
Tomasz Wasilczyk8f36f6e2023-08-15 20:59:35 +0000182 write(fd, heading.c_str(), heading.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800183 for (const auto& iter : mDeviceEffects) {
184 String8 outStr;
185 outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
186 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
Tomasz Wasilczyk8f36f6e2023-08-15 20:59:35 +0000187 write(fd, outStr.c_str(), outStr.size());
Andy Hungbd72c542023-06-20 18:56:17 -0700188 iter.second->dump2(fd, 4);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800189 }
190
191 if (locked) {
192 mLock.unlock();
193 }
194}
195
Andy Hungbf766942023-07-13 19:54:47 -0700196size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
Eric Laurentb82e6b72019-11-22 17:25:04 -0800197{
198 Mutex::Autolock _l(mLock);
199 mDeviceEffects.erase(effect->device());
200 return mDeviceEffects.size();
201}
202
Andy Hungbf766942023-07-13 19:54:47 -0700203bool DeviceEffectManagerCallback::disconnectEffectHandle(
Andy Hungbd72c542023-06-20 18:56:17 -0700204 IAfEffectHandle *handle, bool unpinIfLast) {
205 sp<IAfEffectBase> effectBase = handle->effect().promote();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800206 if (effectBase == nullptr) {
207 return false;
208 }
209
Andy Hungbd72c542023-06-20 18:56:17 -0700210 sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800211 if (effect == nullptr) {
212 return false;
213 }
214 // restore suspended effects if the disconnected handle was enabled and the last one.
215 bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
216 if (remove) {
217 mManager.removeEffect(effect);
218 if (handle->enabled()) {
219 effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
220 }
221 }
222 return true;
223}
224
Andy Hungbf766942023-07-13 19:54:47 -0700225bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
Andy Hunge9a1c7a2023-07-17 13:45:55 -0700226 return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
Andy Hungbf766942023-07-13 19:54:47 -0700227}
228
229int DeviceEffectManagerCallback::newEffectId() const {
Andy Hunge9a1c7a2023-07-17 13:45:55 -0700230 return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
Andy Hungbf766942023-07-13 19:54:47 -0700231}
232
Eric Laurentb82e6b72019-11-22 17:25:04 -0800233} // namespace android