blob: bc05aa0513f1769416748c28821e9a6b34a8e591 [file] [log] [blame]
Shunkai Yaodca65ce2022-12-02 05:35:41 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Shunkai Yao51202502022-12-12 06:11:46 +000017#include <algorithm>
Shunkai Yao5c718342023-02-23 23:49:51 +000018#include <cstddef>
Shunkai Yao51202502022-12-12 06:11:46 +000019#include <cstdint>
Shunkai Yao5c718342023-02-23 23:49:51 +000020#include <iterator>
Shunkai Yao51202502022-12-12 06:11:46 +000021#include <memory>
Shunkai Yaodca65ce2022-12-02 05:35:41 +000022#define LOG_TAG "EffectsFactoryHalAidl"
23//#define LOG_NDEBUG 0
24
Shunkai Yao284bb0d2023-01-10 00:42:36 +000025#include <error/expected_utils.h>
Shunkai Yaodca65ce2022-12-02 05:35:41 +000026#include <android/binder_manager.h>
Shunkai Yao51202502022-12-12 06:11:46 +000027#include <media/AidlConversionCppNdk.h>
Shunkai Yaoa03533e2023-01-25 06:38:10 +000028#include <media/AidlConversionEffect.h>
Shunkai Yao284bb0d2023-01-10 00:42:36 +000029#include <system/audio.h>
Shunkai Yaodca65ce2022-12-02 05:35:41 +000030#include <utils/Log.h>
31
Shunkai Yao51202502022-12-12 06:11:46 +000032#include "EffectBufferHalAidl.h"
33#include "EffectHalAidl.h"
Shunkai Yao5c718342023-02-23 23:49:51 +000034#include "EffectProxy.h"
Shunkai Yaodca65ce2022-12-02 05:35:41 +000035#include "EffectsFactoryHalAidl.h"
36
Shunkai Yao284bb0d2023-01-10 00:42:36 +000037using ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid;
Sebastian Pickl30c8c362023-04-21 08:29:27 +000038using aidl::android::aidl_utils::statusTFromBinderStatus;
39using aidl::android::hardware::audio::effect::Descriptor;
40using aidl::android::hardware::audio::effect::IFactory;
41using aidl::android::media::audio::common::AudioUuid;
42using android::detail::AudioHalVersionInfo;
Shunkai Yaodca65ce2022-12-02 05:35:41 +000043
44namespace android {
45namespace effect {
46
Shunkai Yao51202502022-12-12 06:11:46 +000047EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory)
48 : mFactory(effectsFactory),
Shunkai Yao5c718342023-02-23 23:49:51 +000049 mHalVersion(AudioHalVersionInfo(
50 AudioHalVersionInfo::Type::AIDL,
51 [this]() {
52 int32_t majorVersion = 0;
53 return (mFactory && mFactory->getInterfaceVersion(&majorVersion).isOk())
54 ? majorVersion
55 : 0;
56 }())),
57 mHalDescList([this]() {
58 std::vector<Descriptor> list;
59 if (mFactory) {
60 mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &list).isOk();
61 }
62 return list;
63 }()),
64 mUuidProxyMap([this]() {
65 std::map<AudioUuid, std::shared_ptr<EffectProxy>> proxyMap;
66 for (const auto& desc : mHalDescList) {
67 // create EffectProxy
68 if (desc.common.id.proxy.has_value()) {
69 const auto& uuid = desc.common.id.proxy.value();
70 if (0 == proxyMap.count(uuid)) {
71 proxyMap.insert({uuid, ndk::SharedRefBase::make<EffectProxy>(desc.common.id,
72 mFactory)});
73 }
74 proxyMap[uuid]->addSubEffect(desc);
75 ALOGI("%s addSubEffect %s", __func__, desc.common.toString().c_str());
76 }
77 }
78 return proxyMap;
79 }()),
80 mProxyDescList([this]() {
81 std::vector<Descriptor> list;
82 for (const auto& proxy : mUuidProxyMap) {
83 if (Descriptor desc; proxy.second && proxy.second->getDescriptor(&desc).isOk()) {
84 list.emplace_back(std::move(desc));
85 }
86 }
87 return list;
88 }()),
89 mNonProxyDescList([this]() {
90 std::vector<Descriptor> list;
91 std::copy_if(mHalDescList.begin(), mHalDescList.end(), std::back_inserter(list),
92 [](const Descriptor& desc) { return !desc.common.id.proxy.has_value(); });
93 return list;
94 }()),
Sebastian Pickl30c8c362023-04-21 08:29:27 +000095 mEffectCount(mNonProxyDescList.size() + mProxyDescList.size()) {
Shunkai Yao5c718342023-02-23 23:49:51 +000096 ALOG_ASSERT(mFactory != nullptr, "Provided IEffectsFactory service is NULL");
97 ALOGI("%s with %zu nonProxyEffects and %zu proxyEffects", __func__, mNonProxyDescList.size(),
98 mProxyDescList.size());
Shunkai Yaodca65ce2022-12-02 05:35:41 +000099}
100
101status_t EffectsFactoryHalAidl::queryNumberEffects(uint32_t *pNumEffects) {
102 if (pNumEffects == nullptr) {
103 return BAD_VALUE;
104 }
Shunkai Yao51202502022-12-12 06:11:46 +0000105
Shunkai Yao5c718342023-02-23 23:49:51 +0000106 *pNumEffects = mEffectCount;
Shunkai Yao51202502022-12-12 06:11:46 +0000107 ALOGI("%s %d", __func__, *pNumEffects);
108 return OK;
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000109}
110
111status_t EffectsFactoryHalAidl::getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) {
Shunkai Yao51202502022-12-12 06:11:46 +0000112 if (pDescriptor == nullptr) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000113 return BAD_VALUE;
114 }
Shunkai Yao51202502022-12-12 06:11:46 +0000115
Shunkai Yao5c718342023-02-23 23:49:51 +0000116 if (index >= mEffectCount) {
117 ALOGE("%s index %d exceed max number %zu", __func__, index, mEffectCount);
Shunkai Yao51202502022-12-12 06:11:46 +0000118 return INVALID_OPERATION;
119 }
120
Shunkai Yao5c718342023-02-23 23:49:51 +0000121 if (index >= mNonProxyDescList.size()) {
122 *pDescriptor =
123 VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_Descriptor_effect_descriptor(
124 mProxyDescList.at(index - mNonProxyDescList.size())));
125 } else {
126 *pDescriptor =
127 VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_Descriptor_effect_descriptor(
128 mNonProxyDescList.at(index)));
129 }
Shunkai Yao51202502022-12-12 06:11:46 +0000130 return OK;
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000131}
132
Shunkai Yao51202502022-12-12 06:11:46 +0000133status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* halUuid,
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000134 effect_descriptor_t* pDescriptor) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000135 if (halUuid == nullptr) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000136 return BAD_VALUE;
137 }
Shunkai Yao51202502022-12-12 06:11:46 +0000138
Shunkai Yao5c718342023-02-23 23:49:51 +0000139 AudioUuid uuid =
140 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
141 return getHalDescriptorWithImplUuid(uuid, pDescriptor);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000142}
143
Shunkai Yao51202502022-12-12 06:11:46 +0000144status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* halType,
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000145 std::vector<effect_descriptor_t>* descriptors) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000146 if (halType == nullptr) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000147 return BAD_VALUE;
148 }
Shunkai Yao51202502022-12-12 06:11:46 +0000149
Shunkai Yao5c718342023-02-23 23:49:51 +0000150 AudioUuid type =
151 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*halType));
152 return getHalDescriptorWithTypeUuid(type, descriptors);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000153}
154
Shunkai Yao51202502022-12-12 06:11:46 +0000155status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* uuid, int32_t sessionId,
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000156 int32_t ioId, int32_t deviceId __unused,
157 sp<EffectHalInterface>* effect) {
Shunkai Yao51202502022-12-12 06:11:46 +0000158 if (uuid == nullptr || effect == nullptr) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000159 return BAD_VALUE;
160 }
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000161 if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
Shunkai Yao51202502022-12-12 06:11:46 +0000162 return INVALID_OPERATION;
163 }
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000164 ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
165
Shunkai Yao5c718342023-02-23 23:49:51 +0000166 AudioUuid aidlUuid =
167 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000168 std::shared_ptr<IEffect> aidlEffect;
Shunkai Yao5c718342023-02-23 23:49:51 +0000169 // Use EffectProxy interface instead of IFactory to create
170 const bool isProxy = isProxyEffect(aidlUuid);
171 if (isProxy) {
172 aidlEffect = mUuidProxyMap.at(aidlUuid);
173 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mUuidProxyMap.at(aidlUuid)->create()));
174 } else {
175 RETURN_STATUS_IF_ERROR(
176 statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
177 }
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000178 if (aidlEffect == nullptr) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000179 ALOGE("%s failed to create effect with UUID: %s", __func__, aidlUuid.toString().c_str());
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000180 return NAME_NOT_FOUND;
181 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000182 Descriptor desc;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000183 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aidlEffect->getDescriptor(&desc)));
184
Shunkai Yao51202502022-12-12 06:11:46 +0000185 uint64_t effectId;
186 {
187 std::lock_guard lg(mLock);
188 effectId = ++mEffectIdCounter;
189 }
190
Shunkai Yao5c718342023-02-23 23:49:51 +0000191 *effect =
192 sp<EffectHalAidl>::make(mFactory, aidlEffect, effectId, sessionId, ioId, desc, isProxy);
Shunkai Yao51202502022-12-12 06:11:46 +0000193 return OK;
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000194}
195
196status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000197 status_t ret = OK;
198 // record the error ret and continue dump as many effects as possible
199 for (const auto& proxy : mUuidProxyMap) {
200 if (proxy.second) {
201 if (status_t temp = proxy.second->dump(fd, nullptr, 0); temp != OK) {
202 ret = temp;
203 }
204 }
205 }
206 RETURN_STATUS_IF_ERROR(mFactory->dump(fd, nullptr, 0));
207 return ret;
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000208}
209
210status_t EffectsFactoryHalAidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
Shunkai Yao51202502022-12-12 06:11:46 +0000211 ALOGI("%s size %zu buffer %p", __func__, size, buffer);
Shunkai Yao51202502022-12-12 06:11:46 +0000212 return EffectBufferHalAidl::allocate(size, buffer);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000213}
214
215status_t EffectsFactoryHalAidl::mirrorBuffer(void* external, size_t size,
216 sp<EffectBufferHalInterface>* buffer) {
Shunkai Yao51202502022-12-12 06:11:46 +0000217 ALOGI("%s extern %p size %zu buffer %p", __func__, external, size, buffer);
Shunkai Yao51202502022-12-12 06:11:46 +0000218 return EffectBufferHalAidl::mirror(external, size, buffer);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000219}
220
221AudioHalVersionInfo EffectsFactoryHalAidl::getHalVersion() const {
Shunkai Yao51202502022-12-12 06:11:46 +0000222 return mHalVersion;
223}
224
Shunkai Yao5c718342023-02-23 23:49:51 +0000225status_t EffectsFactoryHalAidl::getHalDescriptorWithImplUuid(const AudioUuid& uuid,
226 effect_descriptor_t* pDescriptor) {
Shunkai Yao51202502022-12-12 06:11:46 +0000227 if (pDescriptor == nullptr) {
228 return BAD_VALUE;
229 }
Shunkai Yao51202502022-12-12 06:11:46 +0000230
Shunkai Yao5c718342023-02-23 23:49:51 +0000231 const auto& list = isProxyEffect(uuid) ? mProxyDescList : mNonProxyDescList;
232 auto matchIt = std::find_if(list.begin(), list.end(),
233 [&](const auto& desc) { return desc.common.id.uuid == uuid; });
234 if (matchIt == list.end()) {
235 ALOGE("%s UUID not found in HAL and proxy list %s", __func__, uuid.toString().c_str());
Shunkai Yao51202502022-12-12 06:11:46 +0000236 return BAD_VALUE;
237 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000238 ALOGI("%s UUID impl found %s", __func__, uuid.toString().c_str());
Shunkai Yao51202502022-12-12 06:11:46 +0000239
240 *pDescriptor = VALUE_OR_RETURN_STATUS(
241 ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
242 return OK;
243}
244
Shunkai Yao5c718342023-02-23 23:49:51 +0000245status_t EffectsFactoryHalAidl::getHalDescriptorWithTypeUuid(
Shunkai Yao51202502022-12-12 06:11:46 +0000246 const AudioUuid& type, std::vector<effect_descriptor_t>* descriptors) {
247 if (descriptors == nullptr) {
248 return BAD_VALUE;
249 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000250
Shunkai Yao51202502022-12-12 06:11:46 +0000251 std::vector<Descriptor> result;
Shunkai Yao5c718342023-02-23 23:49:51 +0000252 std::copy_if(mNonProxyDescList.begin(), mNonProxyDescList.end(), std::back_inserter(result),
Shunkai Yao51202502022-12-12 06:11:46 +0000253 [&](auto& desc) { return desc.common.id.type == type; });
Shunkai Yao5c718342023-02-23 23:49:51 +0000254 std::copy_if(mProxyDescList.begin(), mProxyDescList.end(), std::back_inserter(result),
255 [&](auto& desc) { return desc.common.id.type == type; });
256 if (result.empty()) {
257 ALOGW("%s UUID type not found in HAL and proxy list %s", __func__, type.toString().c_str());
Shunkai Yao51202502022-12-12 06:11:46 +0000258 return BAD_VALUE;
259 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000260 ALOGI("%s UUID type found %zu \n %s", __func__, result.size(), type.toString().c_str());
Shunkai Yao51202502022-12-12 06:11:46 +0000261
262 *descriptors = VALUE_OR_RETURN_STATUS(
263 aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
264 result, ::aidl::android::aidl2legacy_Descriptor_effect_descriptor));
265 return OK;
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000266}
267
Shunkai Yao5c718342023-02-23 23:49:51 +0000268bool EffectsFactoryHalAidl::isProxyEffect(const AudioUuid& uuid) const {
269 return 0 != mUuidProxyMap.count(uuid);
270}
271
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000272} // namespace effect
273
274// When a shared library is built from a static library, even explicit
275// exports from a static library are optimized out unless actually used by
276// the shared library. See EffectsFactoryHalEntry.cpp.
277extern "C" void* createIEffectsFactoryImpl() {
Shunkai Yao51202502022-12-12 06:11:46 +0000278 auto serviceName = std::string(IFactory::descriptor) + "/default";
279 auto service = IFactory::fromBinder(
280 ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
281 if (!service) {
282 ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
283 return nullptr;
284 }
285 return new effect::EffectsFactoryHalAidl(service);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000286}
287
288} // namespace android