blob: 0f645cd106675584df153e0a56745c2bdcb34c89 [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 Hung55a74fd2023-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 Hung55a74fd2023-07-13 19:54:47 -070037DeviceEffectManager::DeviceEffectManager(AudioFlinger& audioFlinger)
38 : mAudioFlinger(audioFlinger),
39 mMyCallback(new DeviceEffectManagerCallback(*this)) {}
40
41void DeviceEffectManager::onFirstRef() {
42 mAudioFlinger.mPatchCommandThread->addListener(this);
43}
44
45status_t DeviceEffectManager::addEffectToHal(const struct audio_port_config* device,
46 const sp<EffectHalInterface>& effect) {
47 return mAudioFlinger.addEffectToHal(device, effect);
48};
49
50status_t DeviceEffectManager::removeEffectFromHal(const struct audio_port_config* device,
51 const sp<EffectHalInterface>& effect) {
52 return mAudioFlinger.removeEffectFromHal(device, effect);
53};
54
55void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070056 const IAfPatchPanel::Patch& patch) {
Eric Laurentb82e6b72019-11-22 17:25:04 -080057 ALOGV("%s handle %d mHalHandle %d device sink %08x",
58 __func__, handle, patch.mHalHandle,
59 patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
60 Mutex::Autolock _l(mLock);
François Gaffie0f660582023-06-27 15:15:26 +020061 for (auto& effectProxies : mDeviceEffects) {
62 for (auto& effect : effectProxies.second) {
Andy Hung8e6b62a2023-07-13 18:11:33 -070063 const status_t status = effect->onCreatePatch(handle, patch);
François Gaffie0f660582023-06-27 15:15:26 +020064 ALOGV("%s Effect onCreatePatch status %d", __func__, status);
65 ALOGW_IF(status == BAD_VALUE, "%s onCreatePatch error %d", __func__, status);
66 }
Eric Laurentb82e6b72019-11-22 17:25:04 -080067 }
68}
69
Andy Hung55a74fd2023-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);
François Gaffie0f660582023-06-27 15:15:26 +020073 for (auto& effectProxies : mDeviceEffects) {
74 for (auto& effect : effectProxies.second) {
75 effect->onReleasePatch(handle);
76 }
Eric Laurentb82e6b72019-11-22 17:25:04 -080077 }
78}
79
Andy Hung55a74fd2023-07-13 19:54:47 -070080void DeviceEffectManager::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
Andy Hung8e6b62a2023-07-13 18:11:33 -070081 audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
François Gaffie58e73af2023-02-15 11:47:24 +010082 ALOGV("%s oldhandle %d newHandle %d mHalHandle %d device sink %08x",
83 __func__, oldHandle, newHandle, patch.mHalHandle,
84 patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
85 Mutex::Autolock _l(mLock);
François Gaffie0f660582023-06-27 15:15:26 +020086 for (auto& effectProxies : mDeviceEffects) {
87 for (auto& effect : effectProxies.second) {
Andy Hung8e6b62a2023-07-13 18:11:33 -070088 const status_t status = effect->onUpdatePatch(oldHandle, newHandle, patch);
François Gaffie0f660582023-06-27 15:15:26 +020089 ALOGV("%s Effect onUpdatePatch status %d", __func__, status);
90 ALOGW_IF(status != NO_ERROR, "%s onUpdatePatch error %d", __func__, status);
91 }
François Gaffie58e73af2023-02-15 11:47:24 +010092 }
93}
94
Eric Laurentb82e6b72019-11-22 17:25:04 -080095// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
Andy Hung55a74fd2023-07-13 19:54:47 -070096sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
Eric Laurentb82e6b72019-11-22 17:25:04 -080097 effect_descriptor_t *descriptor,
98 const AudioDeviceTypeAddr& device,
Andy Hung59867e42023-06-27 17:05:02 -070099 const sp<Client>& client,
Eric Laurentb82e6b72019-11-22 17:25:04 -0800100 const sp<IEffectClient>& effectClient,
Andy Hung8e6b62a2023-07-13 18:11:33 -0700101 const std::map<audio_patch_handle_t, IAfPatchPanel::Patch>& patches,
Eric Laurentb82e6b72019-11-22 17:25:04 -0800102 int *enabled,
Eric Laurent2fe0acd2020-03-13 14:30:46 -0700103 status_t *status,
Eric Laurentde8caf42021-08-11 17:19:25 +0200104 bool probe,
105 bool notifyFramesProcessed) {
Andy Hung6ac17eb2023-06-20 18:56:17 -0700106 sp<IAfDeviceEffectProxy> effect;
François Gaffie0f660582023-06-27 15:15:26 +0200107 std::vector<sp<IAfDeviceEffectProxy>> effectsForDevice = {};
Andy Hung6ac17eb2023-06-20 18:56:17 -0700108 sp<IAfEffectHandle> handle;
Eric Laurentb82e6b72019-11-22 17:25:04 -0800109 status_t lStatus;
110
111 lStatus = checkEffectCompatibility(descriptor);
Eric Laurent2fe0acd2020-03-13 14:30:46 -0700112 if (probe || lStatus != NO_ERROR) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800113 *status = lStatus;
114 return handle;
115 }
116
117 {
118 Mutex::Autolock _l(mLock);
119 auto iter = mDeviceEffects.find(device);
120 if (iter != mDeviceEffects.end()) {
François Gaffie0f660582023-06-27 15:15:26 +0200121 effectsForDevice = iter->second;
122 for (const auto& iterEffect : effectsForDevice) {
123 if (memcmp(&iterEffect->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) ==
124 0) {
125 effect = iterEffect;
126 break;
127 }
128 }
129 }
130 if (effect == nullptr) {
Andy Hung6ac17eb2023-06-20 18:56:17 -0700131 effect = IAfDeviceEffectProxy::create(device, mMyCallback,
Eric Laurentde8caf42021-08-11 17:19:25 +0200132 descriptor, mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT),
133 notifyFramesProcessed);
François Gaffie0f660582023-06-27 15:15:26 +0200134 effectsForDevice.push_back(effect);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800135 }
136 // create effect handle and connect it to effect module
Andy Hung6ac17eb2023-06-20 18:56:17 -0700137 handle = IAfEffectHandle::create(
138 effect, client, effectClient, 0 /*priority*/, notifyFramesProcessed);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800139 lStatus = handle->initCheck();
140 if (lStatus == NO_ERROR) {
141 lStatus = effect->addHandle(handle.get());
142 if (lStatus == NO_ERROR) {
Andy Hung8e6b62a2023-07-13 18:11:33 -0700143 lStatus = effect->init(patches);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530144 if (lStatus == NAME_NOT_FOUND) {
145 lStatus = NO_ERROR;
146 }
147 if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
François Gaffie0f660582023-06-27 15:15:26 +0200148 mDeviceEffects.erase(device);
149 mDeviceEffects.emplace(device, effectsForDevice);
Ram Mohan M2a05df22022-08-28 11:46:23 +0530150 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800151 }
152 }
153 }
Vlad Popa5161f8a2022-10-10 16:17:20 +0200154 if (enabled != nullptr) {
Eric Laurentb82e6b72019-11-22 17:25:04 -0800155 *enabled = (int)effect->isEnabled();
156 }
157 *status = lStatus;
158 return handle;
159}
160
Andy Hung55a74fd2023-07-13 19:54:47 -0700161status_t DeviceEffectManager::checkEffectCompatibility(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800162 const effect_descriptor_t *desc) {
Andy Hungba8e52b2023-05-11 14:33:03 -0700163 const sp<EffectsFactoryHalInterface> effectsFactory =
164 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurent9289bde2020-08-18 12:49:17 -0700165 if (effectsFactory == nullptr) {
166 return BAD_VALUE;
167 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800168
Andy Hungba8e52b2023-05-11 14:33:03 -0700169 static const AudioHalVersionInfo sMinDeviceEffectHalVersion =
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000170 AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
Andy Hungba8e52b2023-05-11 14:33:03 -0700171 static const AudioHalVersionInfo halVersion =
172 audioflinger::EffectConfiguration::getAudioHalVersionInfo();
Eric Laurent9289bde2020-08-18 12:49:17 -0700173
Shunkai Yaod7ea4092022-12-12 00:44:33 +0000174 // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
175 // long as the type, major and minor sequence doesn't change in the definition.
Eric Laurent9289bde2020-08-18 12:49:17 -0700176 if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
177 && (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
178 || halVersion < sMinDeviceEffectHalVersion) {
Shunkai Yao489c5a92022-12-02 05:35:41 +0000179 ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
180 __func__, desc->name, halVersion.toString().c_str());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800181 return BAD_VALUE;
182 }
183
184 return NO_ERROR;
185}
186
Andy Hung55a74fd2023-07-13 19:54:47 -0700187status_t DeviceEffectManager::createEffectHal(
Eric Laurentb82e6b72019-11-22 17:25:04 -0800188 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
189 sp<EffectHalInterface> *effect) {
190 status_t status = NO_INIT;
Andy Hungba8e52b2023-05-11 14:33:03 -0700191 const sp<EffectsFactoryHalInterface> effectsFactory =
192 audioflinger::EffectConfiguration::getEffectsFactoryHal();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800193 if (effectsFactory != 0) {
194 status = effectsFactory->createEffect(
195 pEffectUuid, sessionId, AUDIO_IO_HANDLE_NONE, deviceId, effect);
196 }
197 return status;
198}
199
Andy Hung55a74fd2023-07-13 19:54:47 -0700200void DeviceEffectManager::dump(int fd)
Andy Hung920f6572022-10-06 12:09:49 -0700201NO_THREAD_SAFETY_ANALYSIS // conditional try lock
202{
Andy Hung55a74fd2023-07-13 19:54:47 -0700203 const bool locked = AudioFlinger::dumpTryLock(mLock);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800204 if (!locked) {
205 String8 result("DeviceEffectManager may be deadlocked\n");
206 write(fd, result.string(), result.size());
207 }
208
Phil Burk651d0a52020-05-08 14:00:58 -0700209 String8 heading("\nDevice Effects:\n");
210 write(fd, heading.string(), heading.size());
Eric Laurentb82e6b72019-11-22 17:25:04 -0800211 for (const auto& iter : mDeviceEffects) {
212 String8 outStr;
213 outStr.appendFormat("%*sEffect for device %s address %s:\n", 2, "",
214 ::android::toString(iter.first.mType).c_str(), iter.first.getAddress());
François Gaffie0f660582023-06-27 15:15:26 +0200215 for (const auto& effect : iter.second) {
216 write(fd, outStr.string(), outStr.size());
217 effect->dump2(fd, 4);
218 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800219 }
220
221 if (locked) {
222 mLock.unlock();
223 }
224}
225
Andy Hung55a74fd2023-07-13 19:54:47 -0700226size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
Eric Laurentb82e6b72019-11-22 17:25:04 -0800227{
228 Mutex::Autolock _l(mLock);
François Gaffie0f660582023-06-27 15:15:26 +0200229 const auto& iter = mDeviceEffects.find(effect->device());
230 if (iter != mDeviceEffects.end()) {
231 const auto& iterEffect = std::find_if(
232 iter->second.begin(), iter->second.end(), [&effect](const auto& effectProxy) {
233 return memcmp(&effectProxy->desc().uuid, &effect->desc().uuid,
234 sizeof(effect_uuid_t)) == 0;
235 });
236 if (iterEffect != iter->second.end()) {
237 iter->second.erase(iterEffect);
238 if (iter->second.empty()) {
239 mDeviceEffects.erase(effect->device());
240 }
241 }
242 }
Eric Laurentb82e6b72019-11-22 17:25:04 -0800243 return mDeviceEffects.size();
244}
245
Andy Hung55a74fd2023-07-13 19:54:47 -0700246bool DeviceEffectManagerCallback::disconnectEffectHandle(
Andy Hung6ac17eb2023-06-20 18:56:17 -0700247 IAfEffectHandle *handle, bool unpinIfLast) {
248 sp<IAfEffectBase> effectBase = handle->effect().promote();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800249 if (effectBase == nullptr) {
250 return false;
251 }
252
Andy Hung6ac17eb2023-06-20 18:56:17 -0700253 sp<IAfDeviceEffectProxy> effect = effectBase->asDeviceEffectProxy();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800254 if (effect == nullptr) {
255 return false;
256 }
257 // restore suspended effects if the disconnected handle was enabled and the last one.
258 bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
259 if (remove) {
260 mManager.removeEffect(effect);
261 if (handle->enabled()) {
262 effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
263 }
264 }
265 return true;
266}
267
Andy Hung55a74fd2023-07-13 19:54:47 -0700268bool DeviceEffectManagerCallback::isAudioPolicyReady() const {
269 return mManager.audioFlinger().isAudioPolicyReady();
270}
271
272int DeviceEffectManagerCallback::newEffectId() const {
273 return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
274}
275
Eric Laurentb82e6b72019-11-22 17:25:04 -0800276} // namespace android