blob: 172ebdfc6bfa57421bdd9723ec9ccc598a8a03b3 [file] [log] [blame]
Mikhail Naganovf558e022016-11-14 17:45:17 -08001/*
2 * Copyright (C) 2016 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
17#define LOG_TAG "EffectsFactoryHalHidl"
18//#define LOG_NDEBUG 0
19
Mikhail Naganov0288c752022-09-02 02:16:09 +000020#include <optional>
21#include <tuple>
22
Mikhail Naganovf558e022016-11-14 17:45:17 -080023#include <cutils/native_handle.h>
Mikhail Naganovf558e022016-11-14 17:45:17 -080024
Mikhail Naganov247b5f92021-01-15 19:16:12 +000025#include <UuidUtils.h>
26#include <util/EffectUtils.h>
Mikhail Naganov288a3432022-03-25 00:29:56 +000027#include <utils/Log.h>
Mikhail Naganov247b5f92021-01-15 19:16:12 +000028
Mikhail Naganov288a3432022-03-25 00:29:56 +000029#include "EffectConversionHelperHidl.h"
Kevin Rocard7588ff42018-01-08 11:11:30 -080030#include "EffectBufferHalHidl.h"
Mikhail Naganovf558e022016-11-14 17:45:17 -080031#include "EffectHalHidl.h"
Kevin Rocard00538f12019-06-25 14:26:29 -070032#include "EffectsFactoryHalHidl.h"
Mikhail Naganovf558e022016-11-14 17:45:17 -080033
Shunkai Yaodca65ce2022-12-02 05:35:41 +000034#include "android/media/AudioHalVersion.h"
35
36using ::android::detail::AudioHalVersionInfo;
Mikhail Naganov76956002020-10-30 09:40:21 -070037using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
Mikhail Naganov247b5f92021-01-15 19:16:12 +000038using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
Sebastian Pickl30c8c362023-04-21 08:29:27 +000039using ::android::hardware::Return;
Mikhail Naganovf558e022016-11-14 17:45:17 -080040
41namespace android {
Mikhail Naganov595caa32018-12-13 11:08:28 -080042namespace effect {
Mikhail Naganovf558e022016-11-14 17:45:17 -080043
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080044using namespace ::android::hardware::audio::common::CPP_VERSION;
Mikhail Naganov595caa32018-12-13 11:08:28 -080045using namespace ::android::hardware::audio::effect::CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080046
Mikhail Naganov0288c752022-09-02 02:16:09 +000047class EffectDescriptorCache {
48 public:
49 using QueryResult = std::tuple<Return<void>, Result, hidl_vec<EffectDescriptor>>;
50 QueryResult queryAllDescriptors(IEffectsFactory* effectsFactory);
51 private:
52 std::mutex mLock;
53 std::optional<hidl_vec<EffectDescriptor>> mLastDescriptors; // GUARDED_BY(mLock)
54};
55
56EffectDescriptorCache::QueryResult EffectDescriptorCache::queryAllDescriptors(
57 IEffectsFactory* effectsFactory) {
58 {
59 std::lock_guard l(mLock);
60 if (mLastDescriptors.has_value()) {
61 return {::android::hardware::Void(), Result::OK, mLastDescriptors.value()};
62 }
63 }
64 Result retval = Result::NOT_INITIALIZED;
65 hidl_vec<EffectDescriptor> descriptors;
66 Return<void> ret = effectsFactory->getAllDescriptors(
67 [&](Result r, const hidl_vec<EffectDescriptor>& result) {
68 retval = r;
69 if (retval == Result::OK) {
70 descriptors = result;
71 }
72 });
73 if (ret.isOk() && retval == Result::OK) {
74 std::lock_guard l(mLock);
75 mLastDescriptors = descriptors;
76 }
77 return {std::move(ret), retval, std::move(descriptors)};
78}
79
Kevin Rocarda8f13932019-06-25 16:08:29 -070080EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
Sebastian Pickl30c8c362023-04-21 08:29:27 +000081 : EffectConversionHelperHidl("EffectsFactory"), mCache(new EffectDescriptorCache) {
Eric Laurent9289bde2020-08-18 12:49:17 -070082 ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
Sebastian Pickl4b7f1de2023-04-21 08:31:51 +000083 mEffectsFactory = std::move(effectsFactory);
Mikhail Naganovf558e022016-11-14 17:45:17 -080084}
85
Mikhail Naganovf558e022016-11-14 17:45:17 -080086status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
Mikhail Naganov0288c752022-09-02 02:16:09 +000087 if (mEffectsFactory == 0) return NO_INIT;
88 auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
89 if (ret.isOk() && retval == Result::OK) {
90 *pNumEffects = descriptors.size();
91 return OK;
92 } else if (ret.isOk()) {
93 return NO_INIT;
Mikhail Naganovf558e022016-11-14 17:45:17 -080094 }
Mikhail Naganov0288c752022-09-02 02:16:09 +000095 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -080096}
97
98status_t EffectsFactoryHalHidl::getDescriptor(
99 uint32_t index, effect_descriptor_t *pDescriptor) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200100 if (pDescriptor == nullptr) {
101 return BAD_VALUE;
102 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000103 if (mEffectsFactory == 0) return NO_INIT;
104 auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
105 if (ret.isOk() && retval == Result::OK) {
106 if (index >= descriptors.size()) return NAME_NOT_FOUND;
107 EffectUtils::effectDescriptorToHal(descriptors[index], pDescriptor);
108 } else if (ret.isOk()) {
109 return NO_INIT;
Mikhail Naganovf558e022016-11-14 17:45:17 -0800110 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000111 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800112}
113
114status_t EffectsFactoryHalHidl::getDescriptor(
115 const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200116 if (pDescriptor == nullptr || pEffectUuid == nullptr) {
117 return BAD_VALUE;
118 }
Mikhail Naganovf558e022016-11-14 17:45:17 -0800119 if (mEffectsFactory == 0) return NO_INIT;
120 Uuid hidlUuid;
Mikhail Naganov76956002020-10-30 09:40:21 -0700121 UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800122 Result retval = Result::NOT_INITIALIZED;
123 Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
124 [&](Result r, const EffectDescriptor& result) {
125 retval = r;
126 if (retval == Result::OK) {
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000127 EffectUtils::effectDescriptorToHal(result, pDescriptor);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800128 }
129 });
Steven Morelande83be8a2017-01-06 11:06:33 -0800130 if (ret.isOk()) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800131 if (retval == Result::OK) return OK;
132 else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
133 else return NO_INIT;
134 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800135 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800136}
137
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200138status_t EffectsFactoryHalHidl::getDescriptors(const effect_uuid_t *pEffectType,
139 std::vector<effect_descriptor_t> *descriptors) {
140 if (pEffectType == nullptr || descriptors == nullptr) {
141 return BAD_VALUE;
142 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000143 if (mEffectsFactory == 0) return NO_INIT;
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200144
Mikhail Naganov0288c752022-09-02 02:16:09 +0000145 auto [ret, retval, hidlDescs] = mCache->queryAllDescriptors(mEffectsFactory.get());
146 if (!ret.isOk() || retval != Result::OK) {
147 return processReturn(__FUNCTION__, ret, retval);
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200148 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000149 for (const auto& hidlDesc : hidlDescs) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200150 effect_descriptor_t descriptor;
Mikhail Naganov0288c752022-09-02 02:16:09 +0000151 EffectUtils::effectDescriptorToHal(hidlDesc, &descriptor);
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200152 if (memcmp(&descriptor.type, pEffectType, sizeof(effect_uuid_t)) == 0) {
153 descriptors->push_back(descriptor);
154 }
155 }
156 return descriptors->empty() ? NAME_NOT_FOUND : NO_ERROR;
157}
158
Mikhail Naganovf558e022016-11-14 17:45:17 -0800159status_t EffectsFactoryHalHidl::createEffect(
160 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
Eric Laurentd7005292019-11-13 12:57:33 -0800161 int32_t deviceId __unused, sp<EffectHalInterface> *effect) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800162 if (mEffectsFactory == 0) return NO_INIT;
163 Uuid hidlUuid;
Mikhail Naganov76956002020-10-30 09:40:21 -0700164 UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800165 Result retval = Result::NOT_INITIALIZED;
Eric Laurentd7005292019-11-13 12:57:33 -0800166 Return<void> ret;
167#if MAJOR_VERSION >= 6
168 ret = mEffectsFactory->createEffect(
169 hidlUuid, sessionId, ioId, deviceId,
170 [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
171 retval = r;
172 if (retval == Result::OK) {
173 *effect = new EffectHalHidl(result, effectId);
174 }
175 });
176#else
177 if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
178 return INVALID_OPERATION;
179 }
180 ret = mEffectsFactory->createEffect(
Mikhail Naganovf558e022016-11-14 17:45:17 -0800181 hidlUuid, sessionId, ioId,
182 [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
183 retval = r;
184 if (retval == Result::OK) {
185 *effect = new EffectHalHidl(result, effectId);
186 }
187 });
Eric Laurentd7005292019-11-13 12:57:33 -0800188#endif
Steven Morelande83be8a2017-01-06 11:06:33 -0800189 if (ret.isOk()) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800190 if (retval == Result::OK) return OK;
191 else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
192 else return NO_INIT;
193 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800194 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800195}
196
197status_t EffectsFactoryHalHidl::dumpEffects(int fd) {
198 if (mEffectsFactory == 0) return NO_INIT;
199 native_handle_t* hidlHandle = native_handle_create(1, 0);
200 hidlHandle->data[0] = fd;
Kevin Rocarddf9b4202018-05-10 19:56:08 -0700201 Return<void> ret = mEffectsFactory->debug(hidlHandle, {} /* options */);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800202 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700203
204 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
205 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
206 // when the remote binder thread removes the last refcount to the fd blocks in the
207 // kernel for binder activity. We send a Binder ping() command to unblock the thread
208 // and complete the fd close / release.
209 //
210 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
211 // EffectsFactoryHalHidl::dumpEffects().
212
213 (void)mEffectsFactory->ping(); // synchronous Binder call
214
Steven Morelande83be8a2017-01-06 11:06:33 -0800215 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800216}
217
Kevin Rocard7588ff42018-01-08 11:11:30 -0800218status_t EffectsFactoryHalHidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
219 return EffectBufferHalHidl::allocate(size, buffer);
220}
221
222status_t EffectsFactoryHalHidl::mirrorBuffer(void* external, size_t size,
223 sp<EffectBufferHalInterface>* buffer) {
224 return EffectBufferHalHidl::mirror(external, size, buffer);
225}
226
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000227AudioHalVersionInfo EffectsFactoryHalHidl::getHalVersion() const {
228 return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
229}
230
Mikhail Naganov595caa32018-12-13 11:08:28 -0800231} // namespace effect
Kevin Rocard00538f12019-06-25 14:26:29 -0700232
Mikhail Naganov288a3432022-03-25 00:29:56 +0000233// When a shared library is built from a static library, even explicit
234// exports from a static library are optimized out unless actually used by
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000235// the shared library. See EffectsFactoryHalEntry.cpp.
Mikhail Naganov288a3432022-03-25 00:29:56 +0000236extern "C" void* createIEffectsFactoryImpl() {
Kevin Rocard00538f12019-06-25 14:26:29 -0700237 auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
Mikhail Naganov6718c392022-01-27 22:17:21 +0000238 return service ? new effect::EffectsFactoryHalHidl(service) : nullptr;
Kevin Rocard00538f12019-06-25 14:26:29 -0700239}
240
Mikhail Naganovf558e022016-11-14 17:45:17 -0800241} // namespace android