blob: 34703800c7852b10173a43245df58633b0de3b02 [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
Mikhail Naganov76956002020-10-30 09:40:21 -070034using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
Mikhail Naganov247b5f92021-01-15 19:16:12 +000035using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
Mikhail Naganovf558e022016-11-14 17:45:17 -080036using ::android::hardware::Return;
Mikhail Naganovf558e022016-11-14 17:45:17 -080037
38namespace android {
Mikhail Naganov595caa32018-12-13 11:08:28 -080039namespace effect {
Mikhail Naganovf558e022016-11-14 17:45:17 -080040
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080041using namespace ::android::hardware::audio::common::CPP_VERSION;
Mikhail Naganov595caa32018-12-13 11:08:28 -080042using namespace ::android::hardware::audio::effect::CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080043
Mikhail Naganov0288c752022-09-02 02:16:09 +000044class EffectDescriptorCache {
45 public:
46 using QueryResult = std::tuple<Return<void>, Result, hidl_vec<EffectDescriptor>>;
47 QueryResult queryAllDescriptors(IEffectsFactory* effectsFactory);
48 private:
49 std::mutex mLock;
50 std::optional<hidl_vec<EffectDescriptor>> mLastDescriptors; // GUARDED_BY(mLock)
51};
52
53EffectDescriptorCache::QueryResult EffectDescriptorCache::queryAllDescriptors(
54 IEffectsFactory* effectsFactory) {
55 {
56 std::lock_guard l(mLock);
57 if (mLastDescriptors.has_value()) {
58 return {::android::hardware::Void(), Result::OK, mLastDescriptors.value()};
59 }
60 }
61 Result retval = Result::NOT_INITIALIZED;
62 hidl_vec<EffectDescriptor> descriptors;
63 Return<void> ret = effectsFactory->getAllDescriptors(
64 [&](Result r, const hidl_vec<EffectDescriptor>& result) {
65 retval = r;
66 if (retval == Result::OK) {
67 descriptors = result;
68 }
69 });
70 if (ret.isOk() && retval == Result::OK) {
71 std::lock_guard l(mLock);
72 mLastDescriptors = descriptors;
73 }
74 return {std::move(ret), retval, std::move(descriptors)};
75}
76
Kevin Rocarda8f13932019-06-25 16:08:29 -070077EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
Mikhail Naganov0288c752022-09-02 02:16:09 +000078 : EffectConversionHelperHidl("EffectsFactory"), mCache(new EffectDescriptorCache) {
Eric Laurent9289bde2020-08-18 12:49:17 -070079 ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
Kevin Rocarda8f13932019-06-25 16:08:29 -070080 mEffectsFactory = effectsFactory;
Mikhail Naganovf558e022016-11-14 17:45:17 -080081}
82
Mikhail Naganovf558e022016-11-14 17:45:17 -080083status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
Mikhail Naganov0288c752022-09-02 02:16:09 +000084 if (mEffectsFactory == 0) return NO_INIT;
85 auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
86 if (ret.isOk() && retval == Result::OK) {
87 *pNumEffects = descriptors.size();
88 return OK;
89 } else if (ret.isOk()) {
90 return NO_INIT;
Mikhail Naganovf558e022016-11-14 17:45:17 -080091 }
Mikhail Naganov0288c752022-09-02 02:16:09 +000092 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -080093}
94
95status_t EffectsFactoryHalHidl::getDescriptor(
96 uint32_t index, effect_descriptor_t *pDescriptor) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +020097 if (pDescriptor == nullptr) {
98 return BAD_VALUE;
99 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000100 if (mEffectsFactory == 0) return NO_INIT;
101 auto [ret, retval, descriptors] = mCache->queryAllDescriptors(mEffectsFactory.get());
102 if (ret.isOk() && retval == Result::OK) {
103 if (index >= descriptors.size()) return NAME_NOT_FOUND;
104 EffectUtils::effectDescriptorToHal(descriptors[index], pDescriptor);
105 } else if (ret.isOk()) {
106 return NO_INIT;
Mikhail Naganovf558e022016-11-14 17:45:17 -0800107 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000108 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800109}
110
111status_t EffectsFactoryHalHidl::getDescriptor(
112 const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200113 if (pDescriptor == nullptr || pEffectUuid == nullptr) {
114 return BAD_VALUE;
115 }
Mikhail Naganovf558e022016-11-14 17:45:17 -0800116 if (mEffectsFactory == 0) return NO_INIT;
117 Uuid hidlUuid;
Mikhail Naganov76956002020-10-30 09:40:21 -0700118 UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800119 Result retval = Result::NOT_INITIALIZED;
120 Return<void> ret = mEffectsFactory->getDescriptor(hidlUuid,
121 [&](Result r, const EffectDescriptor& result) {
122 retval = r;
123 if (retval == Result::OK) {
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000124 EffectUtils::effectDescriptorToHal(result, pDescriptor);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800125 }
126 });
Steven Morelande83be8a2017-01-06 11:06:33 -0800127 if (ret.isOk()) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800128 if (retval == Result::OK) return OK;
129 else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
130 else return NO_INIT;
131 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800132 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800133}
134
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200135status_t EffectsFactoryHalHidl::getDescriptors(const effect_uuid_t *pEffectType,
136 std::vector<effect_descriptor_t> *descriptors) {
137 if (pEffectType == nullptr || descriptors == nullptr) {
138 return BAD_VALUE;
139 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000140 if (mEffectsFactory == 0) return NO_INIT;
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200141
Mikhail Naganov0288c752022-09-02 02:16:09 +0000142 auto [ret, retval, hidlDescs] = mCache->queryAllDescriptors(mEffectsFactory.get());
143 if (!ret.isOk() || retval != Result::OK) {
144 return processReturn(__FUNCTION__, ret, retval);
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200145 }
Mikhail Naganov0288c752022-09-02 02:16:09 +0000146 for (const auto& hidlDesc : hidlDescs) {
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200147 effect_descriptor_t descriptor;
Mikhail Naganov0288c752022-09-02 02:16:09 +0000148 EffectUtils::effectDescriptorToHal(hidlDesc, &descriptor);
Eric Laurent0ac7f8c2021-07-13 13:37:11 +0200149 if (memcmp(&descriptor.type, pEffectType, sizeof(effect_uuid_t)) == 0) {
150 descriptors->push_back(descriptor);
151 }
152 }
153 return descriptors->empty() ? NAME_NOT_FOUND : NO_ERROR;
154}
155
Mikhail Naganovf558e022016-11-14 17:45:17 -0800156status_t EffectsFactoryHalHidl::createEffect(
157 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
Eric Laurentd7005292019-11-13 12:57:33 -0800158 int32_t deviceId __unused, sp<EffectHalInterface> *effect) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800159 if (mEffectsFactory == 0) return NO_INIT;
160 Uuid hidlUuid;
Mikhail Naganov76956002020-10-30 09:40:21 -0700161 UuidUtils::uuidFromHal(*pEffectUuid, &hidlUuid);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800162 Result retval = Result::NOT_INITIALIZED;
Eric Laurentd7005292019-11-13 12:57:33 -0800163 Return<void> ret;
164#if MAJOR_VERSION >= 6
165 ret = mEffectsFactory->createEffect(
166 hidlUuid, sessionId, ioId, deviceId,
167 [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
168 retval = r;
169 if (retval == Result::OK) {
170 *effect = new EffectHalHidl(result, effectId);
171 }
172 });
173#else
174 if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
175 return INVALID_OPERATION;
176 }
177 ret = mEffectsFactory->createEffect(
Mikhail Naganovf558e022016-11-14 17:45:17 -0800178 hidlUuid, sessionId, ioId,
179 [&](Result r, const sp<IEffect>& result, uint64_t effectId) {
180 retval = r;
181 if (retval == Result::OK) {
182 *effect = new EffectHalHidl(result, effectId);
183 }
184 });
Eric Laurentd7005292019-11-13 12:57:33 -0800185#endif
Steven Morelande83be8a2017-01-06 11:06:33 -0800186 if (ret.isOk()) {
Mikhail Naganovf558e022016-11-14 17:45:17 -0800187 if (retval == Result::OK) return OK;
188 else if (retval == Result::INVALID_ARGUMENTS) return NAME_NOT_FOUND;
189 else return NO_INIT;
190 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800191 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800192}
193
194status_t EffectsFactoryHalHidl::dumpEffects(int fd) {
195 if (mEffectsFactory == 0) return NO_INIT;
196 native_handle_t* hidlHandle = native_handle_create(1, 0);
197 hidlHandle->data[0] = fd;
Kevin Rocarddf9b4202018-05-10 19:56:08 -0700198 Return<void> ret = mEffectsFactory->debug(hidlHandle, {} /* options */);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800199 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700200
201 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
202 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
203 // when the remote binder thread removes the last refcount to the fd blocks in the
204 // kernel for binder activity. We send a Binder ping() command to unblock the thread
205 // and complete the fd close / release.
206 //
207 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
208 // EffectsFactoryHalHidl::dumpEffects().
209
210 (void)mEffectsFactory->ping(); // synchronous Binder call
211
Steven Morelande83be8a2017-01-06 11:06:33 -0800212 return processReturn(__FUNCTION__, ret);
Mikhail Naganovf558e022016-11-14 17:45:17 -0800213}
214
Kevin Rocard7588ff42018-01-08 11:11:30 -0800215status_t EffectsFactoryHalHidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
216 return EffectBufferHalHidl::allocate(size, buffer);
217}
218
219status_t EffectsFactoryHalHidl::mirrorBuffer(void* external, size_t size,
220 sp<EffectBufferHalInterface>* buffer) {
221 return EffectBufferHalHidl::mirror(external, size, buffer);
222}
223
Mikhail Naganov595caa32018-12-13 11:08:28 -0800224} // namespace effect
Kevin Rocard00538f12019-06-25 14:26:29 -0700225
Mikhail Naganov288a3432022-03-25 00:29:56 +0000226// When a shared library is built from a static library, even explicit
227// exports from a static library are optimized out unless actually used by
228// the shared library. See EffectsFactoryHalHidlEntry.cpp.
229extern "C" void* createIEffectsFactoryImpl() {
Kevin Rocard00538f12019-06-25 14:26:29 -0700230 auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
Mikhail Naganov6718c392022-01-27 22:17:21 +0000231 return service ? new effect::EffectsFactoryHalHidl(service) : nullptr;
Kevin Rocard00538f12019-06-25 14:26:29 -0700232}
233
Mikhail Naganovf558e022016-11-14 17:45:17 -0800234} // namespace android