blob: 69437f52d0ddeed2162c19801fea15629cfb44f4 [file] [log] [blame]
Wonsik Kima9ee43d2024-11-22 23:45:42 +00001/*
2 * Copyright (C) 2024 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#include <mutex>
18
19#include <dlfcn.h>
20
21#include "log/log.h"
22
23#include <apex/ApexCodecs.h>
24
25// This file provides a lazy interface to libapexcodecs.so to address early boot dependencies.
26
27// Method pointers to libapexcodecs methods are held in an array which simplifies checking
28// all pointers are initialized.
29enum MethodIndex {
30 k_ApexCodec_Component_create,
31 k_ApexCodec_Component_destroy,
32 k_ApexCodec_Component_flush,
33 k_ApexCodec_Component_getConfigurable,
34 k_ApexCodec_Component_process,
35 k_ApexCodec_Component_start,
36 k_ApexCodec_Component_reset,
37 k_ApexCodec_Configurable_config,
38 k_ApexCodec_Configurable_query,
39 k_ApexCodec_Configurable_querySupportedParams,
40 k_ApexCodec_Configurable_querySupportedValues,
41 k_ApexCodec_GetComponentStore,
42 k_ApexCodec_ParamDescriptors_getDescriptor,
43 k_ApexCodec_ParamDescriptors_getIndices,
44 k_ApexCodec_ParamDescriptors_release,
45 k_ApexCodec_SettingResults_getResultAtIndex,
46 k_ApexCodec_SettingResults_release,
47 k_ApexCodec_SupportedValues_getTypeAndValues,
48 k_ApexCodec_SupportedValues_release,
49 k_ApexCodec_Traits_get,
50
51 // Marker for count of methods
52 k_MethodCount
53};
54
55// Table of methods pointers in libapexcodecs APIs.
56static void* g_Methods[k_MethodCount];
57
58static void* LoadLibapexcodecs(int dlopen_flags) {
59 return dlopen("libapexcodecs.so", dlopen_flags);
60}
61
62// Initialization and symbol binding.
63
64static void BindSymbol(void* handle, const char* name, enum MethodIndex index) {
65 void* symbol = dlsym(handle, name);
66 LOG_ALWAYS_FATAL_IF(symbol == nullptr, "Failed to find symbol '%s' in libapexcodecs.so: %s",
67 name, dlerror());
68 g_Methods[index] = symbol;
69}
70
71static void InitializeOnce() {
72 void* handle = LoadLibstatssocket(RTLD_NOW);
73 LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load libapexcodecs.so: %s", dlerror());
74
75#undef BIND_SYMBOL
76#define BIND_SYMBOL(name) BindSymbol(handle, #name, k_##name);
77 BIND_SYMBOL(ApexCodec_Component_create);
78 BIND_SYMBOL(ApexCodec_Component_destroy);
79 BIND_SYMBOL(ApexCodec_Component_flush);
80 BIND_SYMBOL(ApexCodec_Component_getConfigurable);
81 BIND_SYMBOL(ApexCodec_Component_process);
82 BIND_SYMBOL(ApexCodec_Component_start);
83 BIND_SYMBOL(ApexCodec_Component_reset);
84 BIND_SYMBOL(ApexCodec_Configurable_config);
85 BIND_SYMBOL(ApexCodec_Configurable_query);
86 BIND_SYMBOL(ApexCodec_Configurable_querySupportedParams);
87 BIND_SYMBOL(ApexCodec_Configurable_querySupportedValues);
88 BIND_SYMBOL(ApexCodec_GetComponentStore);
89 BIND_SYMBOL(ApexCodec_ParamDescriptors_getDescriptor);
90 BIND_SYMBOL(ApexCodec_ParamDescriptors_getIndices);
91 BIND_SYMBOL(ApexCodec_ParamDescriptors_release);
92 BIND_SYMBOL(ApexCodec_SettingResults_getResultAtIndex);
93 BIND_SYMBOL(ApexCodec_SettingResults_release);
94 BIND_SYMBOL(ApexCodec_SupportedValues_getTypeAndValues);
95 BIND_SYMBOL(ApexCodec_SupportedValues_release);
96 BIND_SYMBOL(ApexCodec_Traits_get);
97#undef BIND_SYMBOL
98
99 // Check every symbol is bound.
100 for (int i = 0; i < k_MethodCount; ++i) {
101 LOG_ALWAYS_FATAL_IF(g_Methods[i] == nullptr,
102 "Uninitialized method in libapexcodecs_lazy at index: %d", i);
103 }
104}
105
106static void EnsureInitialized() {
107 static std::once_flag initialize_flag;
108 std::call_once(initialize_flag, InitializeOnce);
109}
110
111#define INVOKE_METHOD(name, args...) \
112 do { \
113 EnsureInitialized(); \
114 void* method = g_Methods[k_##name]; \
115 return reinterpret_cast<decltype(&name)>(method)(args); \
116 } while (0)
117
118//
119// Forwarding for methods in ApexCodecs.h.
120//
121
122ApexCodec_ComponentStore *ApexCodec_GetComponentStore() {
123 INVOKE_METHOD(ApexCodec_GetComponentStore);
124}
125
126ApexCodec_ComponentTraits *ApexCodec_Traits_get(
127 ApexCodec_ComponentStore *store, size_t index) {
128 INVOKE_METHOD(ApexCodec_Traits_get, store, index);
129}
130
131ApexCodec_Status ApexCodec_Component_create(
132 ApexCodec_ComponentStore *store, const char *name, ApexCodec_Component **comp) {
133 INVOKE_METHOD(ApexCodec_Component_create, store, name, comp);
134}
135
136void ApexCodec_Component_destroy(ApexCodec_Component *comp) {
137 INVOKE_METHOD(ApexCodec_Component_destroy, comp);
138}
139
140ApexCodec_Status ApexCodec_Component_start(ApexCodec_Component *comp) {
141 INVOKE_METHOD(ApexCodec_Component_start, comp);
142}
143
144ApexCodec_Status ApexCodec_Component_flush(ApexCodec_Component *comp) {
145 INVOKE_METHOD(ApexCodec_Component_flush, comp);
146}
147
148ApexCodec_Status ApexCodec_Component_reset(ApexCodec_Component *comp) {
149 INVOKE_METHOD(ApexCodec_Component_reset, comp);
150}
151
152ApexCodec_Configurable *ApexCodec_Component_getConfigurable(
153 ApexCodec_Component *comp) {
154 INVOKE_METHOD(ApexCodec_Component_getConfigurable, comp);
155}
156
157ApexCodec_Status ApexCodec_SupportedValues_getTypeAndValues(
158 ApexCodec_SupportedValues *supportedValues,
159 ApexCodec_SupportedValuesType *type,
160 ApexCodec_SupportedValuesNumberType *numberType,
161 ApexCodec_Value **values,
162 uint32_t *numValues) {
163 INVOKE_METHOD(ApexCodec_SupportedValues_getTypeAndValues,
164 supportedValues, type, numberType, values, numValues);
165}
166
167void ApexCodec_SupportedValues_release(ApexCodec_SupportedValues *values) {
168 INVOKE_METHOD(ApexCodec_SupportedValues_release, values);
169}
170
171ApexCodec_Status ApexCodec_SettingResults_getResultAtIndex(
172 ApexCodec_SettingResults *results,
173 size_t index,
174 ApexCodec_SettingResultFailure *failure,
175 ApexCodec_ParamFieldValues *field,
176 ApexCodec_ParamFieldValues **conflicts,
177 size_t *numConflicts) {
178 INVOKE_METHOD(ApexCodec_SettingResults_getResultAtIndex,
179 results, index, failure, field, conflicts, numConflicts);
180}
181
182void ApexCodec_SettingResults_release(ApexCodec_SettingResults *results) {
183 INVOKE_METHOD(ApexCodec_SettingResults_release, results);
184}
185
186ApexCodec_Status ApexCodec_Component_process(
187 ApexCodec_Component *comp,
188 const ApexCodec_Buffer *input,
189 ApexCodec_Buffer *output,
190 size_t *consumed,
191 size_t *produced) {
192 INVOKE_METHOD(ApexCodec_Component_process, comp, input, output, consumed, produced);
193}
194
195ApexCodec_Status ApexCodec_Configurable_config(
196 ApexCodec_Configurable *comp,
197 ApexCodec_LinearBuffer *config,
198 ApexCodec_SettingResults **results) {
199 INVOKE_METHOD(ApexCodec_Configurable_config, comp, config, results);
200}
201
202ApexCodec_Status ApexCodec_Configurable_query(
203 ApexCodec_Configurable *comp,
204 uint32_t indices[],
205 size_t numIndices,
206 ApexCodec_LinearBuffer *config,
207 size_t *writtenOrRequested) {
208 INVOKE_METHOD(ApexCodec_Configurable_query,
209 comp, indices, numIndices, config, writtenOrRequested);
210}
211
212ApexCodec_Status ApexCodec_ParamDescriptors_getIndices(
213 ApexCodec_ParamDescriptors *descriptors,
214 uint32_t **indices,
215 size_t *numIndices) {
216 INVOKE_METHOD(ApexCodec_ParamDescriptors_getIndices, descriptors, indices, numIndices);
217}
218
219ApexCodec_Status ApexCodec_ParamDescriptors_getDescriptor(
220 ApexCodec_ParamDescriptors *descriptors,
221 uint32_t index,
222 ApexCodec_ParamAttribute *attr,
223 const char **name,
224 uint32_t **dependencies,
225 size_t *numDependencies) {
226 INVOKE_METHOD(ApexCodec_ParamDescriptors_getDescriptor,
227 descriptors, index, attr, name, dependencies, numDependencies);
228}
229
230ApexCodec_Status ApexCodec_ParamDescriptors_release(
231 ApexCodec_ParamDescriptors *descriptors) {
232 INVOKE_METHOD(ApexCodec_ParamDescriptors_release, descriptors);
233}
234
235ApexCodec_Status ApexCodec_Configurable_querySupportedParams(
236 ApexCodec_Configurable *comp,
237 ApexCodec_ParamDescriptors **descriptors) {
238 INVOKE_METHOD(ApexCodec_Configurable_querySupportedParams, comp, descriptors);
239}
240
241ApexCodec_Status ApexCodec_Configurable_querySupportedValues(
242 ApexCodec_Configurable *comp,
243 ApexCodec_SupportedValuesQuery *queries,
244 size_t numQueries) {
245 INVOKE_METHOD(ApexCodec_Configurable_querySupportedValues, comp, queries, numQueries);
246}