blob: b65ad48e31111902dd845c933f819c3d081d696b [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright 2018 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_NDEBUG 0
Pawin Vongmasae55ed3f2018-11-28 03:39:57 -080018#define LOG_TAG "CodecServiceRegistrant"
19
Wonsik Kimbe1e4642021-11-03 18:26:22 -070020#include <android/api-level.h>
Pawin Vongmasae55ed3f2018-11-28 03:39:57 -080021#include <android-base/logging.h>
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080022#include <android-base/properties.h>
Wonsik Kim65febd22023-09-20 16:26:02 -070023#include <android-base/stringprintf.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080024
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080025#include <C2Component.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080026#include <C2PlatformSupport.h>
Wonsik Kim65febd22023-09-20 16:26:02 -070027
Dongwon Kang2d91d3f2019-12-09 13:53:34 -080028#include <codec2/hidl/1.0/ComponentStore.h>
Pawin Vongmasabf69de92019-10-29 06:21:27 -070029#include <codec2/hidl/1.1/ComponentStore.h>
Sungtak Lee8577dab2021-03-12 02:25:50 -080030#include <codec2/hidl/1.2/ComponentStore.h>
31#include <codec2/hidl/1.2/Configurable.h>
32#include <codec2/hidl/1.2/types.h>
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080033#include <hidl/HidlSupport.h>
Wonsik Kim65febd22023-09-20 16:26:02 -070034#include <hidl/HidlTransportSupport.h>
35
36#include <android/binder_interface_utils.h>
37#include <android/binder_manager.h>
38#include <android/binder_process.h>
39#include <codec2/aidl/ComponentStore.h>
40#include <codec2/aidl/ParamTypes.h>
41
Pawin Vongmasa36653902018-11-15 00:10:25 -080042#include <media/CodecServiceRegistrant.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080043
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080044namespace /* unnamed */ {
45
46using ::android::hardware::hidl_vec;
47using ::android::hardware::hidl_string;
48using ::android::hardware::Return;
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080049using ::android::sp;
Wonsik Kim65febd22023-09-20 16:26:02 -070050using ::ndk::ScopedAStatus;
51namespace c2_hidl = ::android::hardware::media::c2::V1_2;
52namespace c2_aidl = ::aidl::android::hardware::media::c2;
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080053
54constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
55
56// Converter from IComponentStore to C2ComponentStore.
57class H2C2ComponentStore : public C2ComponentStore {
58protected:
Wonsik Kim65febd22023-09-20 16:26:02 -070059 using HidlComponentStore =
Dongwon Kang2d91d3f2019-12-09 13:53:34 -080060 ::android::hardware::media::c2::V1_0::IComponentStore;
Wonsik Kim65febd22023-09-20 16:26:02 -070061 using HidlConfigurable =
Dongwon Kang2d91d3f2019-12-09 13:53:34 -080062 ::android::hardware::media::c2::V1_0::IConfigurable;
Wonsik Kim65febd22023-09-20 16:26:02 -070063 sp<HidlComponentStore> mHidlStore;
64 sp<HidlConfigurable> mHidlConfigurable;
65
66 using AidlComponentStore =
67 ::aidl::android::hardware::media::c2::IComponentStore;
68 using AidlConfigurable =
69 ::aidl::android::hardware::media::c2::IConfigurable;
70 std::shared_ptr<AidlComponentStore> mAidlStore;
71 std::shared_ptr<AidlConfigurable> mAidlConfigurable;
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080072public:
Wonsik Kim65febd22023-09-20 16:26:02 -070073 explicit H2C2ComponentStore(sp<HidlComponentStore> const& store)
74 : mHidlStore{store},
75 mHidlConfigurable{[store]() -> sp<HidlConfigurable>{
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080076 if (!store) {
77 return nullptr;
78 }
Wonsik Kim65febd22023-09-20 16:26:02 -070079 Return<sp<HidlConfigurable>> transResult =
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080080 store->getConfigurable();
81 return transResult.isOk() ?
Wonsik Kim65febd22023-09-20 16:26:02 -070082 static_cast<sp<HidlConfigurable>>(transResult) :
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080083 nullptr;
84 }()} {
Wonsik Kim65febd22023-09-20 16:26:02 -070085 if (!mHidlConfigurable) {
86 LOG(ERROR) << "Preferred store is corrupted.";
87 }
88 }
89
90 explicit H2C2ComponentStore(std::shared_ptr<AidlComponentStore> const& store)
91 : mAidlStore{store},
92 mAidlConfigurable{[store]() -> std::shared_ptr<AidlConfigurable>{
93 if (!store) {
94 return nullptr;
95 }
96 std::shared_ptr<AidlConfigurable> configurable;
97 ScopedAStatus status = store->getConfigurable(&configurable);
98 if (!status.isOk()) {
99 return nullptr;
100 }
101 return configurable;
102 }()} {
103 if (!mAidlConfigurable) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800104 LOG(ERROR) << "Preferred store is corrupted.";
105 }
106 }
107
108 virtual ~H2C2ComponentStore() override = default;
109
Wonsik Kim65febd22023-09-20 16:26:02 -0700110 c2_status_t config_sm(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800111 std::vector<C2Param*> const &params,
112 std::vector<std::unique_ptr<C2SettingResult>>* const failures
113 ) override {
Wonsik Kim65febd22023-09-20 16:26:02 -0700114 if (mAidlStore) {
115 return config_sm_aidl(params, failures);
116 } else if (mHidlStore) {
117 return config_sm_hidl(params, failures);
118 } else {
119 return C2_OMITTED;
120 }
121 }
122
123 c2_status_t config_sm_aidl(
124 std::vector<C2Param*> const &params,
125 std::vector<std::unique_ptr<C2SettingResult>>* const failures
126 ) {
127 c2_aidl::Params aidlParams;
128 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
129 LOG(ERROR) << "config -- bad input.";
130 return C2_TRANSACTION_FAILED;
131 }
132 c2_status_t status = C2_OK;
133 c2_aidl::IConfigurable::ConfigResult configResult;
134 ScopedAStatus transResult = mAidlConfigurable->config(
135 aidlParams, true, &configResult);
136 if (!transResult.isOk()) {
137 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
138 status = c2_status_t(transResult.getServiceSpecificError());
139 if (status != C2_BAD_INDEX) {
140 LOG(DEBUG) << "config -- call failed: "
141 << status << ".";
142 }
143 } else {
144 LOG(ERROR) << "config -- transaction failed.";
145 return C2_TRANSACTION_FAILED;
146 }
147 }
148 size_t i = failures->size();
149 failures->resize(i + configResult.failures.size());
150 for (const c2_aidl::SettingResult& sf : configResult.failures) {
151 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
152 LOG(ERROR) << "config -- "
153 << "invalid SettingResult returned.";
154 status = C2_CORRUPTED;
155 }
156 }
157 if (!c2_aidl::utils::UpdateParamsFromBlob(params, configResult.params)) {
158 LOG(ERROR) << "config -- "
159 << "failed to parse returned params.";
160 status = C2_CORRUPTED;
161 }
162 return status;
163 };
164
165 c2_status_t config_sm_hidl(
166 std::vector<C2Param*> const &params,
167 std::vector<std::unique_ptr<C2SettingResult>>* const failures
168 ) {
169 c2_hidl::Params hidlParams;
170 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800171 LOG(ERROR) << "config -- bad input.";
172 return C2_TRANSACTION_FAILED;
173 }
174 c2_status_t status{};
Wonsik Kim65febd22023-09-20 16:26:02 -0700175 Return<void> transResult = mHidlConfigurable->config(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800176 hidlParams,
177 true,
178 [&status, &params, failures](
Wonsik Kim65febd22023-09-20 16:26:02 -0700179 c2_hidl::Status s,
180 const hidl_vec<c2_hidl::SettingResult> f,
181 const c2_hidl::Params& o) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800182 status = static_cast<c2_status_t>(s);
183 if (status != C2_OK && status != C2_BAD_INDEX) {
184 LOG(DEBUG) << "config -- call failed: "
185 << status << ".";
186 }
187 size_t i = failures->size();
188 failures->resize(i + f.size());
Wonsik Kim65febd22023-09-20 16:26:02 -0700189 for (const c2_hidl::SettingResult& sf : f) {
190 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800191 LOG(ERROR) << "config -- "
192 << "invalid SettingResult returned.";
193 return;
194 }
195 }
Wonsik Kim65febd22023-09-20 16:26:02 -0700196 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800197 LOG(ERROR) << "config -- "
198 << "failed to parse returned params.";
199 status = C2_CORRUPTED;
200 }
201 });
202 if (!transResult.isOk()) {
203 LOG(ERROR) << "config -- transaction failed.";
204 return C2_TRANSACTION_FAILED;
205 }
206 return status;
207 };
208
Wonsik Kim65febd22023-09-20 16:26:02 -0700209 c2_status_t copyBuffer(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800210 std::shared_ptr<C2GraphicBuffer>,
211 std::shared_ptr<C2GraphicBuffer>) override {
212 LOG(ERROR) << "copyBuffer -- not supported.";
213 return C2_OMITTED;
214 }
215
Wonsik Kim65febd22023-09-20 16:26:02 -0700216 c2_status_t createComponent(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800217 C2String, std::shared_ptr<C2Component> *const component) override {
218 component->reset();
219 LOG(ERROR) << "createComponent -- not supported.";
220 return C2_OMITTED;
221 }
222
Wonsik Kim65febd22023-09-20 16:26:02 -0700223 c2_status_t createInterface(
224 C2String, std::shared_ptr<C2ComponentInterface> *const interface) override {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800225 interface->reset();
226 LOG(ERROR) << "createInterface -- not supported.";
227 return C2_OMITTED;
228 }
229
Wonsik Kim65febd22023-09-20 16:26:02 -0700230 c2_status_t query_sm(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800231 const std::vector<C2Param *> &stackParams,
232 const std::vector<C2Param::Index> &heapParamIndices,
Wonsik Kim65febd22023-09-20 16:26:02 -0700233 std::vector<std::unique_ptr<C2Param>> *const heapParams) const override {
234 if (mAidlStore) {
235 return query_sm_aidl(stackParams, heapParamIndices, heapParams);
236 } else if (mHidlStore) {
237 return query_sm_hidl(stackParams, heapParamIndices, heapParams);
238 } else {
239 return C2_OMITTED;
240 }
241 }
242
243 static c2_status_t UpdateQueryResult(
244 const std::vector<C2Param *> &paramPointers,
245 size_t numStackIndices,
246 const std::vector<C2Param *> &stackParams,
247 std::vector<std::unique_ptr<C2Param>> *const heapParams) {
248 c2_status_t status = C2_OK;
249 size_t i = 0;
250 for (auto it = paramPointers.begin(); it != paramPointers.end(); ) {
251 C2Param* paramPointer = *it;
252 if (numStackIndices > 0) {
253 --numStackIndices;
254 if (!paramPointer) {
255 LOG(WARNING) << "query -- null stack param.";
256 ++it;
257 continue;
258 }
259 for (; i < stackParams.size() && !stackParams[i]; ) {
260 ++i;
261 }
262 if (i >= stackParams.size()) {
263 LOG(ERROR) << "query -- unexpected error.";
264 status = C2_CORRUPTED;
265 break;
266 }
267 if (stackParams[i]->index() != paramPointer->index()) {
268 LOG(WARNING) << "query -- param skipped: "
269 "index = "
270 << stackParams[i]->index() << ".";
271 stackParams[i++]->invalidate();
272 continue;
273 }
274 if (!stackParams[i++]->updateFrom(*paramPointer)) {
275 LOG(WARNING) << "query -- param update failed: "
276 "index = "
277 << paramPointer->index() << ".";
278 }
279 } else {
280 if (!paramPointer) {
281 LOG(WARNING) << "query -- null heap param.";
282 ++it;
283 continue;
284 }
285 if (!heapParams) {
286 LOG(WARNING) << "query -- "
287 "unexpected extra stack param.";
288 } else {
289 heapParams->emplace_back(
290 C2Param::Copy(*paramPointer));
291 }
292 }
293 ++it;
294 }
295 return status;
296 }
297
298 c2_status_t query_sm_aidl(
299 const std::vector<C2Param *> &stackParams,
300 const std::vector<C2Param::Index> &heapParamIndices,
301 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
302 std::vector<int32_t> indices;
303 size_t numIndices = 0;
304 for (C2Param* const& stackParam : stackParams) {
305 if (!stackParam) {
306 LOG(WARNING) << "query -- null stack param encountered.";
307 continue;
308 }
309 indices[numIndices++] = stackParam->index();
310 }
311 size_t numStackIndices = numIndices;
312 for (const C2Param::Index& index : heapParamIndices) {
313 indices[numIndices++] = static_cast<uint32_t>(index);
314 }
315 indices.resize(numIndices);
316 if (heapParams) {
317 heapParams->reserve(heapParams->size() + numIndices);
318 }
319 c2_status_t status = C2_OK;
320 c2_aidl::Params aidlParams;
321 ScopedAStatus transResult = mAidlConfigurable->query(indices, true, &aidlParams);
322 if (!transResult.isOk()) {
323 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
324 status = c2_status_t(transResult.getServiceSpecificError());
325 LOG(DEBUG) << "query -- call failed: " << status << ".";
326 return status;
327 } else {
328 LOG(ERROR) << "query -- transaction failed.";
329 return C2_TRANSACTION_FAILED;
330 }
331 }
332 std::vector<C2Param*> paramPointers;
333 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, aidlParams)) {
334 LOG(ERROR) << "query -- error while parsing params.";
335 return C2_CORRUPTED;
336 }
337 return UpdateQueryResult(paramPointers, numStackIndices, stackParams, heapParams);
338 }
339
340 c2_status_t query_sm_hidl(
341 const std::vector<C2Param *> &stackParams,
342 const std::vector<C2Param::Index> &heapParamIndices,
343 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
344 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800345 stackParams.size() + heapParamIndices.size());
346 size_t numIndices = 0;
347 for (C2Param* const& stackParam : stackParams) {
348 if (!stackParam) {
349 LOG(WARNING) << "query -- null stack param encountered.";
350 continue;
351 }
Wonsik Kim65febd22023-09-20 16:26:02 -0700352 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800353 }
354 size_t numStackIndices = numIndices;
355 for (const C2Param::Index& index : heapParamIndices) {
356 indices[numIndices++] =
Wonsik Kim65febd22023-09-20 16:26:02 -0700357 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800358 }
359 indices.resize(numIndices);
360 if (heapParams) {
361 heapParams->reserve(heapParams->size() + numIndices);
362 }
363 c2_status_t status;
Wonsik Kim65febd22023-09-20 16:26:02 -0700364 Return<void> transResult = mHidlConfigurable->query(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800365 indices,
366 true,
367 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kim65febd22023-09-20 16:26:02 -0700368 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800369 status = static_cast<c2_status_t>(s);
370 if (status != C2_OK && status != C2_BAD_INDEX) {
371 LOG(DEBUG) << "query -- call failed: "
372 << status << ".";
373 return;
374 }
375 std::vector<C2Param*> paramPointers;
Wonsik Kim65febd22023-09-20 16:26:02 -0700376 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800377 LOG(ERROR) << "query -- error while parsing params.";
378 status = C2_CORRUPTED;
379 return;
380 }
Wonsik Kim65febd22023-09-20 16:26:02 -0700381 status = UpdateQueryResult(
382 paramPointers, numStackIndices, stackParams, heapParams);
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800383 });
384 if (!transResult.isOk()) {
385 LOG(ERROR) << "query -- transaction failed.";
386 return C2_TRANSACTION_FAILED;
387 }
388 return status;
389 }
390
Wonsik Kim65febd22023-09-20 16:26:02 -0700391 c2_status_t querySupportedParams_nb(
392 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override {
393 if (mAidlStore) {
394 return querySupportedParams_nb_aidl(params);
395 } else if (mHidlStore) {
396 return querySupportedParams_nb_hidl(params);
397 } else {
398 return C2_OMITTED;
399 }
400 }
401
402 c2_status_t querySupportedParams_nb_aidl(
403 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
404 c2_status_t status = C2_OK;
405 std::vector<c2_aidl::ParamDescriptor> aidlParams;
406 ScopedAStatus transResult = mAidlConfigurable->querySupportedParams(
407 std::numeric_limits<uint32_t>::min(),
408 std::numeric_limits<uint32_t>::max(),
409 &aidlParams);
410 if (!transResult.isOk()) {
411 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
412 status = c2_status_t(transResult.getServiceSpecificError());
413 LOG(DEBUG) << "querySupportedParams -- call failed: "
414 << status << ".";
415 return status;
416 } else {
417 LOG(ERROR) << "querySupportedParams -- transaction failed.";
418 return C2_TRANSACTION_FAILED;
419 }
420 }
421
422 size_t i = params->size();
423 params->resize(i + aidlParams.size());
424 for (const c2_aidl::ParamDescriptor& sp : aidlParams) {
425 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
426 LOG(ERROR) << "querySupportedParams -- "
427 << "invalid returned ParamDescriptor.";
428 break;
429 }
430 }
431 return status;
432 }
433
434 c2_status_t querySupportedParams_nb_hidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800435 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
436 c2_status_t status;
Wonsik Kim65febd22023-09-20 16:26:02 -0700437 Return<void> transResult = mHidlConfigurable->querySupportedParams(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800438 std::numeric_limits<uint32_t>::min(),
439 std::numeric_limits<uint32_t>::max(),
440 [&status, params](
Wonsik Kim65febd22023-09-20 16:26:02 -0700441 c2_hidl::Status s,
442 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800443 status = static_cast<c2_status_t>(s);
444 if (status != C2_OK) {
445 LOG(DEBUG) << "querySupportedParams -- call failed: "
446 << status << ".";
447 return;
448 }
449 size_t i = params->size();
450 params->resize(i + p.size());
Wonsik Kim65febd22023-09-20 16:26:02 -0700451 for (const c2_hidl::ParamDescriptor& sp : p) {
452 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800453 LOG(ERROR) << "querySupportedParams -- "
454 << "invalid returned ParamDescriptor.";
455 return;
456 }
457 }
458 });
459 if (!transResult.isOk()) {
460 LOG(ERROR) << "querySupportedParams -- transaction failed.";
461 return C2_TRANSACTION_FAILED;
462 }
463 return status;
464 }
465
Wonsik Kim65febd22023-09-20 16:26:02 -0700466 c2_status_t querySupportedValues_sm(
467 std::vector<C2FieldSupportedValuesQuery> &fields) const override {
468 if (mAidlStore) {
469 return querySupportedValues_sm_aidl(fields);
470 } else if (mHidlStore) {
471 return querySupportedValues_sm_hidl(fields);
472 } else {
473 return C2_OMITTED;
474 }
475 }
476
477 c2_status_t querySupportedValues_sm_aidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800478 std::vector<C2FieldSupportedValuesQuery> &fields) const {
Wonsik Kim65febd22023-09-20 16:26:02 -0700479 std::vector<c2_aidl::FieldSupportedValuesQuery> aidlFields(fields.size());
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800480 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kim65febd22023-09-20 16:26:02 -0700481 if (!c2_aidl::utils::ToAidl(&aidlFields[i], fields[i])) {
482 LOG(ERROR) << "querySupportedValues -- bad input";
483 return C2_TRANSACTION_FAILED;
484 }
485 }
486
487 c2_status_t status = C2_OK;
488 std::vector<c2_aidl::FieldSupportedValuesQueryResult> queryResults;
489 ScopedAStatus transResult = mAidlConfigurable->querySupportedValues(
490 aidlFields, true, &queryResults);
491 if (!transResult.isOk()) {
492 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
493 status = c2_status_t(transResult.getServiceSpecificError());
494 LOG(DEBUG) << "querySupportedValues -- call failed: "
495 << status << ".";
496 return status;
497 } else {
498 LOG(ERROR) << "querySupportedValues -- transaction failed.";
499 return C2_TRANSACTION_FAILED;
500 }
501 }
502 if (queryResults.size() != fields.size()) {
503 LOG(ERROR) << "querySupportedValues -- "
504 "input and output lists "
505 "have different sizes.";
506 return C2_CORRUPTED;
507 }
508 for (size_t i = 0; i < fields.size(); ++i) {
509 if (!c2_aidl::utils::FromAidl(&fields[i], aidlFields[i], queryResults[i])) {
510 LOG(ERROR) << "querySupportedValues -- "
511 "invalid returned value.";
512 return C2_CORRUPTED;
513 }
514 }
515 return status;
516 }
517
518 c2_status_t querySupportedValues_sm_hidl(
519 std::vector<C2FieldSupportedValuesQuery> &fields) const {
520 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
521 for (size_t i = 0; i < fields.size(); ++i) {
522 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800523 LOG(ERROR) << "querySupportedValues -- bad input";
524 return C2_TRANSACTION_FAILED;
525 }
526 }
527
528 c2_status_t status;
Wonsik Kim65febd22023-09-20 16:26:02 -0700529 Return<void> transResult = mHidlConfigurable->querySupportedValues(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800530 inFields,
531 true,
532 [&status, &inFields, &fields](
Wonsik Kim65febd22023-09-20 16:26:02 -0700533 c2_hidl::Status s,
534 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800535 status = static_cast<c2_status_t>(s);
536 if (status != C2_OK) {
537 LOG(DEBUG) << "querySupportedValues -- call failed: "
538 << status << ".";
539 return;
540 }
541 if (r.size() != fields.size()) {
542 LOG(ERROR) << "querySupportedValues -- "
543 "input and output lists "
544 "have different sizes.";
545 status = C2_CORRUPTED;
546 return;
547 }
548 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kim65febd22023-09-20 16:26:02 -0700549 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800550 LOG(ERROR) << "querySupportedValues -- "
551 "invalid returned value.";
552 status = C2_CORRUPTED;
553 return;
554 }
555 }
556 });
557 if (!transResult.isOk()) {
558 LOG(ERROR) << "querySupportedValues -- transaction failed.";
559 return C2_TRANSACTION_FAILED;
560 }
561 return status;
562 }
563
Wonsik Kim65febd22023-09-20 16:26:02 -0700564 C2String getName() const override {
565 C2String outName = "(unknown)";
566 if (mAidlStore) {
567 ScopedAStatus transResult = mAidlConfigurable->getName(&outName);
568 if (!transResult.isOk()) {
569 LOG(ERROR) << "getName -- transaction failed.";
570 }
571 } else if (mHidlStore) {
572 Return<void> transResult = mHidlConfigurable->getName(
573 [&outName](const hidl_string& name) {
574 outName = name.c_str();
575 });
576 if (!transResult.isOk()) {
577 LOG(ERROR) << "getName -- transaction failed.";
578 }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800579 }
580 return outName;
581 }
582
583 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const
584 override {
585 struct SimpleParamReflector : public C2ParamReflector {
Wonsik Kim65febd22023-09-20 16:26:02 -0700586 std::unique_ptr<C2StructDescriptor> describe(
587 C2Param::CoreIndex coreIndex) const override {
588 if (mAidlBase) {
589 return describe_aidl(coreIndex);
590 } else if (mHidlBase) {
591 return describe_hidl(coreIndex);
592 } else {
593 return nullptr;
594 }
595 }
596
597 std::unique_ptr<C2StructDescriptor> describe_aidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800598 C2Param::CoreIndex coreIndex) const {
Wonsik Kim65febd22023-09-20 16:26:02 -0700599 std::vector<int32_t> indices(1);
600 indices[0] = coreIndex.coreIndex();
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800601 std::unique_ptr<C2StructDescriptor> descriptor;
Wonsik Kim65febd22023-09-20 16:26:02 -0700602 std::vector<c2_aidl::StructDescriptor> aidlDescs;
603 ScopedAStatus transResult = mAidlBase->getStructDescriptors(
604 indices, &aidlDescs);
605 if (!transResult.isOk()) {
606 c2_status_t status = C2_TRANSACTION_FAILED;
607 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
608 status = c2_status_t(transResult.getServiceSpecificError());
609 LOG(DEBUG) << "SimpleParamReflector -- "
610 "getStructDescriptors() failed: "
611 << status << ".";
612 return nullptr;
613 }
614 }
615 if (aidlDescs.size() != 1) {
616 LOG(DEBUG) << "SimpleParamReflector -- "
617 "getStructDescriptors() "
618 "returned vector of size "
619 << aidlDescs.size() << ". "
620 "It should be 1.";
621 return nullptr;
622 }
623 if (!c2_aidl::utils::FromAidl(&descriptor, aidlDescs[0])) {
624 LOG(DEBUG) << "SimpleParamReflector -- "
625 "getStructDescriptors() returned "
626 "corrupted data.";
627 return nullptr;
628 }
629 return descriptor;
630 }
631
632 std::unique_ptr<C2StructDescriptor> describe_hidl(
633 C2Param::CoreIndex coreIndex) const {
634 hidl_vec<c2_hidl::ParamIndex> indices(1);
635 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
636 std::unique_ptr<C2StructDescriptor> descriptor;
637 Return<void> transResult = mHidlBase->getStructDescriptors(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800638 indices,
639 [&descriptor](
Wonsik Kim65febd22023-09-20 16:26:02 -0700640 c2_hidl::Status s,
641 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800642 c2_status_t status = static_cast<c2_status_t>(s);
643 if (status != C2_OK) {
644 LOG(DEBUG) << "SimpleParamReflector -- "
645 "getStructDescriptors() failed: "
646 << status << ".";
647 descriptor.reset();
648 return;
649 }
650 if (sd.size() != 1) {
651 LOG(DEBUG) << "SimpleParamReflector -- "
652 "getStructDescriptors() "
653 "returned vector of size "
654 << sd.size() << ". "
655 "It should be 1.";
656 descriptor.reset();
657 return;
658 }
Wonsik Kim65febd22023-09-20 16:26:02 -0700659 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800660 LOG(DEBUG) << "SimpleParamReflector -- "
661 "getStructDescriptors() returned "
662 "corrupted data.";
663 descriptor.reset();
664 return;
665 }
666 });
667 return descriptor;
668 }
669
Wonsik Kim65febd22023-09-20 16:26:02 -0700670 explicit SimpleParamReflector(const sp<HidlComponentStore> &base)
671 : mHidlBase(base) { }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800672
Wonsik Kim65febd22023-09-20 16:26:02 -0700673 explicit SimpleParamReflector(const std::shared_ptr<AidlComponentStore> &base)
674 : mAidlBase(base) { }
675
676 std::shared_ptr<AidlComponentStore> mAidlBase;
677 sp<HidlComponentStore> mHidlBase;
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800678 };
679
Wonsik Kim65febd22023-09-20 16:26:02 -0700680 if (mAidlStore) {
681 return std::make_shared<SimpleParamReflector>(mAidlStore);
682 } else if (mHidlStore) {
683 return std::make_shared<SimpleParamReflector>(mHidlStore);
684 } else {
685 return nullptr;
686 }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800687 }
688
689 virtual std::vector<std::shared_ptr<const C2Component::Traits>>
690 listComponents() override {
691 LOG(ERROR) << "listComponents -- not supported.";
692 return {};
693 }
694};
695
696bool ionPropertiesDefined() {
697 using namespace ::android::base;
698 std::string heapMask =
699 GetProperty("ro.com.android.media.swcodec.ion.heapmask", "undefined");
700 std::string flags =
701 GetProperty("ro.com.android.media.swcodec.ion.flags", "undefined");
702 std::string align =
703 GetProperty("ro.com.android.media.swcodec.ion.align", "undefined");
704 if (heapMask != "undefined" ||
705 flags != "undefined" ||
706 align != "undefined") {
707 LOG(INFO)
708 << "Some system properties for mediaswcodec ION usage are set: "
709 << "heapmask = " << heapMask << ", "
710 << "flags = " << flags << ", "
711 << "align = " << align << ". "
712 << "Preferred Codec2 store is defaulted to \"software\".";
713 return true;
714 }
715 return false;
716}
717
718} // unnamed namespace
719
Pawin Vongmasa36653902018-11-15 00:10:25 -0800720extern "C" void RegisterCodecServices() {
Wonsik Kim65febd22023-09-20 16:26:02 -0700721 const bool aidlSelected = c2_aidl::utils::IsSelected();
722 constexpr int kThreadCount = 64;
723 if (aidlSelected) {
724 ABinderProcess_setThreadPoolMaxThreadCount(kThreadCount);
725 ABinderProcess_startThreadPool();
726 } else {
727 ::android::hardware::configureRpcThreadpool(kThreadCount, false);
728 }
729
Pawin Vongmasae55ed3f2018-11-28 03:39:57 -0800730 LOG(INFO) << "Creating software Codec2 service...";
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800731 std::shared_ptr<C2ComponentStore> store =
732 android::GetCodec2PlatformComponentStore();
733 if (!store) {
734 LOG(ERROR) << "Failed to create Codec2 service.";
735 return;
736 }
737
738 using namespace ::android::hardware::media::c2;
739
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700740 int platformVersion = android_get_device_api_level();
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800741
Wonsik Kim65febd22023-09-20 16:26:02 -0700742 std::shared_ptr<c2_aidl::IComponentStore> aidlStore;
743 if (aidlSelected) {
744 aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(store);
745 const std::string serviceName =
746 std::string(c2_aidl::IComponentStore::descriptor) + "/software";
747 binder_exception_t ex = AServiceManager_addService(
748 aidlStore->asBinder().get(), serviceName.c_str());
749 if (ex != EX_NONE) {
750 LOG(ERROR) << "Cannot register software Codec2 AIDL service.";
751 return;
752 }
753 } else if (platformVersion >= __ANDROID_API_S__) {
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700754 android::sp<V1_2::IComponentStore> storeV1_2 =
755 new V1_2::utils::ComponentStore(store);
756 if (storeV1_2->registerAsService("software") != android::OK) {
757 LOG(ERROR) << "Cannot register software Codec2 v1.2 service.";
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800758 return;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800759 }
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700760 } else if (platformVersion == __ANDROID_API_R__) {
761 android::sp<V1_1::IComponentStore> storeV1_1 =
762 new V1_1::utils::ComponentStore(store);
763 if (storeV1_1->registerAsService("software") != android::OK) {
764 LOG(ERROR) << "Cannot register software Codec2 v1.1 service.";
765 return;
766 }
767 } else if (platformVersion == __ANDROID_API_Q__) {
768 android::sp<V1_0::IComponentStore> storeV1_0 =
769 new V1_0::utils::ComponentStore(store);
770 if (storeV1_0->registerAsService("software") != android::OK) {
771 LOG(ERROR) << "Cannot register software Codec2 v1.0 service.";
772 return;
773 }
774 } else { // platformVersion < __ANDROID_API_Q__
775 LOG(ERROR) << "The platform version " << platformVersion <<
776 " is not supported.";
777 return;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800778 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800779 if (!ionPropertiesDefined()) {
780 using IComponentStore =
781 ::android::hardware::media::c2::V1_0::IComponentStore;
782 std::string const preferredStoreName = "default";
Wonsik Kim65febd22023-09-20 16:26:02 -0700783 if (aidlSelected) {
784 std::shared_ptr<c2_aidl::IComponentStore> preferredStore;
785 if (__builtin_available(android __ANDROID_API_S__, *)) {
786 std::string instanceName = ::android::base::StringPrintf(
787 "%s/%s", c2_aidl::IComponentStore::descriptor, preferredStoreName.c_str());
788 if (AServiceManager_isDeclared(instanceName.c_str())) {
789 preferredStore = c2_aidl::IComponentStore::fromBinder(::ndk::SpAIBinder(
790 AServiceManager_waitForService(instanceName.c_str())));
791 }
792 }
793 if (preferredStore) {
794 ::android::SetPreferredCodec2ComponentStore(
795 std::make_shared<H2C2ComponentStore>(preferredStore));
796 LOG(INFO) <<
797 "Preferred Codec2 AIDL store is set to \"" <<
798 preferredStoreName << "\".";
799 } else {
800 LOG(INFO) <<
801 "Preferred Codec2 AIDL store is defaulted to \"software\".";
802 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800803 } else {
Wonsik Kim65febd22023-09-20 16:26:02 -0700804 sp<IComponentStore> preferredStore =
805 IComponentStore::getService(preferredStoreName.c_str());
806 if (preferredStore) {
807 ::android::SetPreferredCodec2ComponentStore(
808 std::make_shared<H2C2ComponentStore>(preferredStore));
809 LOG(INFO) <<
810 "Preferred Codec2 HIDL store is set to \"" <<
811 preferredStoreName << "\".";
812 } else {
813 LOG(INFO) <<
814 "Preferred Codec2 HIDL store is defaulted to \"software\".";
815 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800816 }
817 }
818 LOG(INFO) << "Software Codec2 service created and registered.";
Wonsik Kim65febd22023-09-20 16:26:02 -0700819
820 if (aidlSelected) {
821 ABinderProcess_joinThreadPool();
822 } else {
823 ::android::hardware::joinRpcThreadpool();
824 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800825}
826