blob: 42c64018846a82a83493f83f70ddf7a8e8110472 [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 Hung55a74fd2023-07-13 19:54:47 -070018#define LOG_TAG "DeviceEffectManager"
Eric Laurentb82e6b72019-11-22 17:25:04 -080019//#define LOG_NDEBUG 0
20
Andy Hung0a51b5c2023-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 Hung0a51b5c2023-07-18 20:54:44 -070024
Atneya Nairf94040f2024-10-07 16:00:49 -070025#include <afutils/FallibleLockGuard.h>
Andy Hung0a51b5c2023-07-18 20:54:44 -070026#include <audio_utils/primitives.h>
Eric Laurentb82e6b72019-11-22 17:25:04 -080027#include <media/audiohal/EffectsFactoryHalInterface.h>
Andy Hung0a51b5c2023-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 Hung692f0452023-07-17 13:45:55 -070038DeviceEffectManager::DeviceEffectManager(
39 const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
40 : mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
Andy Hung3e07ef02023-09-06 17:37:34 -070041 mMyCallback(sp<DeviceEffectManagerCallback>::make(*this)) {}
Andy Hung55a74fd2023-07-13 19:54:47 -070042
43void DeviceEffectManager::onFirstRef() {
Andy Hung692f0452023-07-17 13:45:55 -070044 mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
Andy Hung55a74fd2023-07-13 19:54:47 -070045}
46
47status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
48 const sp<EffectHalInterface>& effect) {
Andy Hung692f0452023-07-17 13:45:55 -070049 return mAfDeviceEffectManagerCallback->addEffectToHal(device, effect);
Andy Hung55a74fd2023-07-13 19:54:47 -070050};
51
52status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
53 const sp<EffectHalInterface>& effect) {
Andy Hung692f0452023-07-17 13:45:55 -070054 return mAfDeviceEffectManagerCallback->removeEffectFromHal(device, effect);
Andy Hung55a74fd2023-07-13 19:54:47 -070055};
56
57void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
Andy Hung8e6b62a2023-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);
Andy Hungf65f5a72023-08-29 12:19:17 -070062 audio_utils::lock_guard _l(mutex());
François Gaffie0f660582023-06-27 15:15:26 +020063 for (auto& effectProxies : mDeviceEffects) {
64 for (auto& effect : effectProxies.second) {
Andy Hung8e6b62a2023-07-13 18:11:33 -070065 const status_t status = effect->onCreatePatch(handle, patch);
François Gaffie0f660582023-06-27 15:15:26 +020066 ALOGV("%s Effect onCreatePatch status %d", __func__, status);
67 ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
68 }
Eric Laurentb82e6b72019-11-22 17:25:04 -080069 }
70}
71
Andy Hung55a74fd2023-07-13 19:54:47 -070072void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080073 ALOGV("%s", __func__);
François Gaffiefce3b6c2024-05-23 13:52:23 +020074 // Keep a reference on disconnected handle to delay destruction without lock held.
75 std::vector<sp<IAfEffectHandle>> disconnectedHandles{};
Andy Hungf65f5a72023-08-29 12:19:17 -070076 audio_utils::lock_guard _l(mutex());
François Gaffie0f660582023-06-27 15:15:26 +020077 for (auto& effectProxies : mDeviceEffects) {
78 for (auto& effect : effectProxies.second) {
François Gaffiefce3b6c2024-05-23 13:52:23 +020079 sp<IAfEffectHandle> disconnectedHandle = effect->onReleasePatch(handle);
80 if (disconnectedHandle != nullptr) {
81 disconnectedHandles.push_back(std::move(disconnectedHandle));
82 }
François Gaffie0f660582023-06-27 15:15:26 +020083 }
Eric Laurentb82e6b72019-11-22 17:25:04 -080084 }
85}
86
Andy Hung55a74fd2023-07-13 19:54:47 -070087void DeviceEffectManager::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070088 audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
François Gaffie58e73af2023-02-15 11:47:24 +010089 ALOGV("%s oldhandle %d newHandle %d mHalHandle %d device sink %08x",
90 __func__, oldHandle, newHandle, patch.mHalHandle,
91 patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
Andy Hungf65f5a72023-08-29 12:19:17 -070092 audio_utils::lock_guard _l(mutex());
François Gaffie0f660582023-06-27 15:15:26 +020093 for (auto& effectProxies : mDeviceEffects) {
94 for (auto& effect : effectProxies.second) {
Andy Hung8e6b62a2023-07-13 18:11:33 -070095 const status_t status = effect->onUpdatePatch(oldHandle, newHandle, patch);
François Gaffie0f660582023-06-27 15:15:26 +020096 ALOGV("%s Effect onUpdatePatch status %d", __func__, status);
97 ALOGW_IF(status != NO_ERROR, "%s onUpdatePatch error %d", __func__, status);
98 }
François Gaffie58e73af2023-02-15 11:47:24 +010099 }
100}
101
Andy Hungf65f5a72023-08-29 12:19:17 -0700102// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mutex() held
Andy Hung55a74fd2023-07-13 19:54:47 -0700103sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800104 effect_descriptor_t *descriptor,
105 const AudioDeviceTypeAddr& device,
Andy Hung59867e42023-06-27 17:05:02 -0700106 const sp<Client>& client,
Eric Laurentb82e6b72019-11-22 17:25:04 -0800107 const sp<IEffectClient>& effectClient,
Andy Hung8e6b62a2023-07-13 18:11:33 -0700108 const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
Eric Laurentb82e6b72019-11-22 17:25:04 -0800109 int *enabled,
Eric Laurent2fe0acd2020-03-13 14:30:46 -0700110 status_t *status,
Eric Laurentde8caf42021-08-11 17:19:25 +0200111 bool probe,
112 bool notifyFramesProcessed) {
Andy Hung6ac17eb2023-06-20 18:56:17 -0700113 sp<IAfDeviceEffectProxy> effect;
François Gaffie0f660582023-06-27 15:15:26 +0200114 std::vector<sp<IAfDeviceEffectProxy>> effectsForDevice = {};
Andy Hung6ac17eb2023-06-20 18:56:17 -0700115 sp<IAfEffectHandle> handle;
Eric Laurentb82e6b72019-11-22 17:25:04 -0800116 status_t lStatus;
117
118 lStatus = checkEffectCompatibility(descriptor);
Eric Laurent2fe0acd2020-03-13 14:30:46 -0700119 if (probe || lStatus != NO_ERROR) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800120 *status = lStatus;
121 return handle;
122 }
123
124 {
Andy Hungf65f5a72023-08-29 12:19:17 -0700125 audio_utils::lock_guard _l(mutex());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800126 auto iter = mDeviceEffects.find(device);
127 if (iter != mDeviceEffects.end()) {
François Gaffie0f660582023-06-27 15:15:26 +0200128 effectsForDevice = iter->second;
129 for (const auto& iterEffect : effectsForDevice) {
130 if (memcmp(&iterEffect->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) ==
131 0) {
132 effect = iterEffect;
133 break;
134 }
135 }
136 }
137 if (effect == nullptr) {
Andy Hung6ac17eb2023-06-20 18:56:17 -0700138 effect = IAfDeviceEffectProxy::create(device, mMyCallback,
Andy Hung692f0452023-07-17 13:45:55 -0700139 descriptor,
140 mAfDeviceEffectManagerCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
Eric Laurentde8caf42021-08-11 17:19:25 +0200141 notifyFramesProcessed);
François Gaffie0f660582023-06-27 15:15:26 +0200142 effectsForDevice.push_back(effect);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800143 }
144 // create effect handle and connect it to effect module
Andy Hung6ac17eb2023-06-20 18:56:17 -0700145 handle = IAfEffectHandle::create(
146 effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800147 lStatus = handle->initCheck();
148 if (lStatus == NO_ERROR) {
149 lStatus = effect->addHandle(handle.get());
150 if (lStatus == NO_ERROR) {
Shunkai Yaod125e402024-01-20 03:19:06 +0000151 lStatus = effect->init_l(patches);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530152 if (lStatus == NAME_NOT_FOUND) {
153 lStatus = NO_ERROR;
154 }
155 if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
François Gaffie0f660582023-06-27 15:15:26 +0200156 mDeviceEffects.erase(device);
157 mDeviceEffects.emplace(device, effectsForDevice);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530158 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800159 }
160 }
161 }
Vlad Popa5161f8a2022-10-10 16:17:20 +0200162 if (enabled != nullptr) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800163 *enabled = (int)effect->isEnabled();
164 }
165 *status = lStatus;
166 return handle;
167}
168
Andy Hung3e07ef02023-09-06 17:37:34 -0700169/* static */
Andy Hung55a74fd2023-07-13 19:54:47 -0700170status_t DeviceEffectManager::checkEffectCompatibility(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800171 const effect_descriptor_t *desc) {
Andy Hungba8e52b2023-05-11 14:33:03 -0700172 const sp<EffectsFactoryHalInterface> effectsFactory =
173 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurent9289bde2020-08-18 12:49:17 -0700174 if (effectsFactory == nullptr) {
175 return BAD_VALUE;
176 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800177
Andy Hungba8e52b2023-05-11 14:33:03 -0700178 static const AudioHalVersionInfo sMinDeviceEffectHalVersion =
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000179 AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
Andy Hungba8e52b2023-05-11 14:33:03 -0700180 static const AudioHalVersionInfo halVersion =
181 audioflinger::EffectConfiguration::getAudioHalVersionInfo();
Eric Laurent9289bde2020-08-18 12:49:17 -0700182
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000183 // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
184 // long as the type, major and minor sequence doesn't change in the definition.
Eric Laurent9289bde2020-08-18 12:49:17 -0700185 if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
186 && (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
187 || halVersion < sMinDeviceEffectHalVersion) {
Shunkai Yao489c5a92022-12-02 05:35:41 +0000188 ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
189 __func__, desc->name, halVersion.toString().c_str());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800190 return BAD_VALUE;
191 }
192
193 return NO_ERROR;
194}
195
Andy Hung3e07ef02023-09-06 17:37:34 -0700196/* static */
Andy Hung55a74fd2023-07-13 19:54:47 -0700197status_t DeviceEffectManager::createEffectHal(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800198 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
199 sp<EffectHalInterface> *effect) {
200 status_t status = NO_INIT;
Andy Hungba8e52b2023-05-11 14:33:03 -0700201 const sp<EffectsFactoryHalInterface> effectsFactory =
202 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800203 if (effectsFactory != 0) {
204 status = effectsFactory->createEffect(
205 pEffectUuid, sessionId, AUDIO_IO_HANDLE_NONE, deviceId, effect);
206 }
207 return status;
208}
209
Andy Hung55a74fd2023-07-13 19:54:47 -0700210void DeviceEffectManager::dump(int fd)
Andy Hung920f6572022-10-06 12:09:49 -0700211{
Atneya Nairf94040f2024-10-07 16:00:49 -0700212 afutils::FallibleLockGuard l{mutex()};
213 if (!l) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800214 String8 result("DeviceEffectManager may be deadlocked\n");
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +0000215 write(fd, result.c_str(), result.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800216 }
217
Phil Burk651d0a52020-05-08 14:00:58 -0700218 String8 heading("\nDevice Effects:\n");
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +0000219 write(fd, heading.c_str(), heading.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800220 for (const auto& iter : mDeviceEffects) {
221 String8 outStr;
222 outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
223 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
François Gaffie0f660582023-06-27 15:15:26 +0200224 for (const auto& effect : iter.second) {
Tomasz Wasilczyk833345b2023-08-15 20:59:35 +0000225 write(fd, outStr.c_str(), outStr.size());
François Gaffie0f660582023-06-27 15:15:26 +0200226 effect->dump2(fd, 4);
227 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800228 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800229}
230
Andy Hung55a74fd2023-07-13 19:54:47 -0700231size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
Eric Laurentb82e6b72019-11-22 17:25:04 -0800232{
Andy Hungf65f5a72023-08-29 12:19:17 -0700233 audio_utils::lock_guard _l(mutex());
François Gaffie0f660582023-06-27 15:15:26 +0200234 const auto& iter = mDeviceEffects.find(effect->device());
235 if (iter != mDeviceEffects.end()) {
236 const auto& iterEffect = std::find_if(
237 iter->second.begin(), iter->second.end(), [&effect](const auto& effectProxy) {
238 return memcmp(&effectProxy->desc().uuid, &effect->desc().uuid,
239 sizeof(effect_uuid_t)) == 0;
240 });
241 if (iterEffect != iter->second.end()) {
242 iter->second.erase(iterEffect);
243 if (iter->second.empty()) {
244 mDeviceEffects.erase(effect->device());
245 }
246 }
247 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800248 return mDeviceEffects.size();
249}
250
Andy Hung55a74fd2023-07-13 19:54:47 -0700251bool DeviceEffectManagerCallback::disconnectEffectHandle(
Andy Hung6ac17eb2023-06-20 18:56:17 -0700252 IAfEffectHandle *handle, bool unpinIfLast) {
253 sp<IAfEffectBase> effectBase = handle->effect().promote();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800254 if (effectBase == nullptr) {
255 return false;
256 }
257
Andy Hung6ac17eb2023-06-20 18:56:17 -0700258 sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800259 if (effect == nullptr) {
260 return false;
261 }
262 // restore suspended effects if the disconnected handle was enabled and the last one.
263 bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
264 if (remove) {
265 mManager.removeEffect(effect);
266 if (handle->enabled()) {
267 effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
268 }
269 }
270 return true;
271}
272
Andy Hung55a74fd2023-07-13 19:54:47 -0700273bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
Andy Hung692f0452023-07-17 13:45:55 -0700274 return mManager.afDeviceEffectManagerCallback()->isAudioPolicyReady();
Andy Hung55a74fd2023-07-13 19:54:47 -0700275}
276
277int DeviceEffectManagerCallback::newEffectId() const {
Andy Hung692f0452023-07-17 13:45:55 -0700278 return mManager.afDeviceEffectManagerCallback()->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
Andy Hung55a74fd2023-07-13 19:54:47 -0700279}
280
Eric Laurentb82e6b72019-11-22 17:25:04 -0800281} // namespace android