blob: 65d537bfeb50631ed455b648677c4fe833a96648 [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 Kim138db0d2023-11-02 16:02:01 -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 Kim138db0d2023-11-02 16:02:01 -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 Kim138db0d2023-11-02 16:02:01 -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 Kim138db0d2023-11-02 16:02:01 -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 Kim138db0d2023-11-02 16:02:01 -070059 using HidlComponentStore =
Dongwon Kang2d91d3f2019-12-09 13:53:34 -080060 ::android::hardware::media::c2::V1_0::IComponentStore;
Wonsik Kim138db0d2023-11-02 16:02:01 -070061 using HidlConfigurable =
Dongwon Kang2d91d3f2019-12-09 13:53:34 -080062 ::android::hardware::media::c2::V1_0::IConfigurable;
Wonsik Kim138db0d2023-11-02 16:02:01 -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 Kim138db0d2023-11-02 16:02:01 -070073 explicit H2C2ComponentStore(nullptr_t) {
74 }
75
76 explicit H2C2ComponentStore(sp<HidlComponentStore> const& store)
77 : mHidlStore{store},
78 mHidlConfigurable{[store]() -> sp<HidlConfigurable>{
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080079 if (!store) {
80 return nullptr;
81 }
Wonsik Kim138db0d2023-11-02 16:02:01 -070082 Return<sp<HidlConfigurable>> transResult =
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080083 store->getConfigurable();
84 return transResult.isOk() ?
Wonsik Kim138db0d2023-11-02 16:02:01 -070085 static_cast<sp<HidlConfigurable>>(transResult) :
Pawin Vongmasa6c09c002019-12-16 04:25:41 -080086 nullptr;
87 }()} {
Wonsik Kim138db0d2023-11-02 16:02:01 -070088 if (!mHidlConfigurable) {
89 LOG(ERROR) << "Preferred store is corrupted.";
90 }
91 }
92
93 explicit H2C2ComponentStore(std::shared_ptr<AidlComponentStore> const& store)
94 : mAidlStore{store},
95 mAidlConfigurable{[store]() -> std::shared_ptr<AidlConfigurable>{
96 if (!store) {
97 return nullptr;
98 }
99 std::shared_ptr<AidlConfigurable> configurable;
100 ScopedAStatus status = store->getConfigurable(&configurable);
101 if (!status.isOk()) {
102 return nullptr;
103 }
104 return configurable;
105 }()} {
106 if (!mAidlConfigurable) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800107 LOG(ERROR) << "Preferred store is corrupted.";
108 }
109 }
110
111 virtual ~H2C2ComponentStore() override = default;
112
Wonsik Kim138db0d2023-11-02 16:02:01 -0700113 c2_status_t config_sm(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800114 std::vector<C2Param*> const &params,
115 std::vector<std::unique_ptr<C2SettingResult>>* const failures
116 ) override {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700117 if (mAidlStore) {
118 return config_sm_aidl(params, failures);
119 } else if (mHidlStore) {
120 return config_sm_hidl(params, failures);
121 } else {
122 return C2_OMITTED;
123 }
124 }
125
126 c2_status_t config_sm_aidl(
127 std::vector<C2Param*> const &params,
128 std::vector<std::unique_ptr<C2SettingResult>>* const failures
129 ) {
130 c2_aidl::Params aidlParams;
131 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
132 LOG(ERROR) << "config -- bad input.";
133 return C2_TRANSACTION_FAILED;
134 }
135 c2_status_t status = C2_OK;
136 c2_aidl::IConfigurable::ConfigResult configResult;
137 ScopedAStatus transResult = mAidlConfigurable->config(
138 aidlParams, true, &configResult);
139 if (!transResult.isOk()) {
140 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
141 status = c2_status_t(transResult.getServiceSpecificError());
142 if (status != C2_BAD_INDEX) {
143 LOG(DEBUG) << "config -- call failed: "
144 << status << ".";
145 }
146 } else {
147 LOG(ERROR) << "config -- transaction failed.";
148 return C2_TRANSACTION_FAILED;
149 }
150 }
151 size_t i = failures->size();
152 failures->resize(i + configResult.failures.size());
153 for (const c2_aidl::SettingResult& sf : configResult.failures) {
154 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
155 LOG(ERROR) << "config -- "
156 << "invalid SettingResult returned.";
157 status = C2_CORRUPTED;
158 }
159 }
160 if (!c2_aidl::utils::UpdateParamsFromBlob(params, configResult.params)) {
161 LOG(ERROR) << "config -- "
162 << "failed to parse returned params.";
163 status = C2_CORRUPTED;
164 }
165 return status;
166 };
167
168 c2_status_t config_sm_hidl(
169 std::vector<C2Param*> const &params,
170 std::vector<std::unique_ptr<C2SettingResult>>* const failures
171 ) {
172 c2_hidl::Params hidlParams;
173 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800174 LOG(ERROR) << "config -- bad input.";
175 return C2_TRANSACTION_FAILED;
176 }
177 c2_status_t status{};
Wonsik Kim138db0d2023-11-02 16:02:01 -0700178 Return<void> transResult = mHidlConfigurable->config(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800179 hidlParams,
180 true,
181 [&status, &params, failures](
Wonsik Kim138db0d2023-11-02 16:02:01 -0700182 c2_hidl::Status s,
183 const hidl_vec<c2_hidl::SettingResult> f,
184 const c2_hidl::Params& o) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800185 status = static_cast<c2_status_t>(s);
186 if (status != C2_OK && status != C2_BAD_INDEX) {
187 LOG(DEBUG) << "config -- call failed: "
188 << status << ".";
189 }
190 size_t i = failures->size();
191 failures->resize(i + f.size());
Wonsik Kim138db0d2023-11-02 16:02:01 -0700192 for (const c2_hidl::SettingResult& sf : f) {
193 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800194 LOG(ERROR) << "config -- "
195 << "invalid SettingResult returned.";
196 return;
197 }
198 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700199 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800200 LOG(ERROR) << "config -- "
201 << "failed to parse returned params.";
202 status = C2_CORRUPTED;
203 }
204 });
205 if (!transResult.isOk()) {
206 LOG(ERROR) << "config -- transaction failed.";
207 return C2_TRANSACTION_FAILED;
208 }
209 return status;
210 };
211
Wonsik Kim138db0d2023-11-02 16:02:01 -0700212 c2_status_t copyBuffer(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800213 std::shared_ptr<C2GraphicBuffer>,
214 std::shared_ptr<C2GraphicBuffer>) override {
215 LOG(ERROR) << "copyBuffer -- not supported.";
216 return C2_OMITTED;
217 }
218
Wonsik Kim138db0d2023-11-02 16:02:01 -0700219 c2_status_t createComponent(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800220 C2String, std::shared_ptr<C2Component> *const component) override {
221 component->reset();
222 LOG(ERROR) << "createComponent -- not supported.";
223 return C2_OMITTED;
224 }
225
Wonsik Kim138db0d2023-11-02 16:02:01 -0700226 c2_status_t createInterface(
227 C2String, std::shared_ptr<C2ComponentInterface> *const interface) override {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800228 interface->reset();
229 LOG(ERROR) << "createInterface -- not supported.";
230 return C2_OMITTED;
231 }
232
Wonsik Kim138db0d2023-11-02 16:02:01 -0700233 c2_status_t query_sm(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800234 const std::vector<C2Param *> &stackParams,
235 const std::vector<C2Param::Index> &heapParamIndices,
Wonsik Kim138db0d2023-11-02 16:02:01 -0700236 std::vector<std::unique_ptr<C2Param>> *const heapParams) const override {
237 if (mAidlStore) {
238 return query_sm_aidl(stackParams, heapParamIndices, heapParams);
239 } else if (mHidlStore) {
240 return query_sm_hidl(stackParams, heapParamIndices, heapParams);
241 } else {
242 return C2_OMITTED;
243 }
244 }
245
246 static c2_status_t UpdateQueryResult(
247 const std::vector<C2Param *> &paramPointers,
248 size_t numStackIndices,
249 const std::vector<C2Param *> &stackParams,
250 std::vector<std::unique_ptr<C2Param>> *const heapParams) {
251 c2_status_t status = C2_OK;
252 size_t i = 0;
253 for (auto it = paramPointers.begin(); it != paramPointers.end(); ) {
254 C2Param* paramPointer = *it;
255 if (numStackIndices > 0) {
256 --numStackIndices;
257 if (!paramPointer) {
258 LOG(WARNING) << "query -- null stack param.";
259 ++it;
260 continue;
261 }
262 for (; i < stackParams.size() && !stackParams[i]; ) {
263 ++i;
264 }
265 if (i >= stackParams.size()) {
266 LOG(ERROR) << "query -- unexpected error.";
267 status = C2_CORRUPTED;
268 break;
269 }
270 if (stackParams[i]->index() != paramPointer->index()) {
271 LOG(WARNING) << "query -- param skipped: "
272 "index = "
273 << stackParams[i]->index() << ".";
274 stackParams[i++]->invalidate();
275 continue;
276 }
277 if (!stackParams[i++]->updateFrom(*paramPointer)) {
278 LOG(WARNING) << "query -- param update failed: "
279 "index = "
280 << paramPointer->index() << ".";
281 }
282 } else {
283 if (!paramPointer) {
284 LOG(WARNING) << "query -- null heap param.";
285 ++it;
286 continue;
287 }
288 if (!heapParams) {
289 LOG(WARNING) << "query -- "
290 "unexpected extra stack param.";
291 } else {
292 heapParams->emplace_back(
293 C2Param::Copy(*paramPointer));
294 }
295 }
296 ++it;
297 }
298 return status;
299 }
300
301 c2_status_t query_sm_aidl(
302 const std::vector<C2Param *> &stackParams,
303 const std::vector<C2Param::Index> &heapParamIndices,
304 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
305 std::vector<int32_t> indices;
306 size_t numIndices = 0;
307 for (C2Param* const& stackParam : stackParams) {
308 if (!stackParam) {
309 LOG(WARNING) << "query -- null stack param encountered.";
310 continue;
311 }
312 indices[numIndices++] = stackParam->index();
313 }
314 size_t numStackIndices = numIndices;
315 for (const C2Param::Index& index : heapParamIndices) {
316 indices[numIndices++] = static_cast<uint32_t>(index);
317 }
318 indices.resize(numIndices);
319 if (heapParams) {
320 heapParams->reserve(heapParams->size() + numIndices);
321 }
322 c2_status_t status = C2_OK;
323 c2_aidl::Params aidlParams;
324 ScopedAStatus transResult = mAidlConfigurable->query(indices, true, &aidlParams);
325 if (!transResult.isOk()) {
326 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
327 status = c2_status_t(transResult.getServiceSpecificError());
328 LOG(DEBUG) << "query -- call failed: " << status << ".";
329 return status;
330 } else {
331 LOG(ERROR) << "query -- transaction failed.";
332 return C2_TRANSACTION_FAILED;
333 }
334 }
335 std::vector<C2Param*> paramPointers;
336 if (!c2_aidl::utils::ParseParamsBlob(&paramPointers, aidlParams)) {
337 LOG(ERROR) << "query -- error while parsing params.";
338 return C2_CORRUPTED;
339 }
340 return UpdateQueryResult(paramPointers, numStackIndices, stackParams, heapParams);
341 }
342
343 c2_status_t query_sm_hidl(
344 const std::vector<C2Param *> &stackParams,
345 const std::vector<C2Param::Index> &heapParamIndices,
346 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
347 hidl_vec<c2_hidl::ParamIndex> indices(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800348 stackParams.size() + heapParamIndices.size());
349 size_t numIndices = 0;
350 for (C2Param* const& stackParam : stackParams) {
351 if (!stackParam) {
352 LOG(WARNING) << "query -- null stack param encountered.";
353 continue;
354 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700355 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800356 }
357 size_t numStackIndices = numIndices;
358 for (const C2Param::Index& index : heapParamIndices) {
359 indices[numIndices++] =
Wonsik Kim138db0d2023-11-02 16:02:01 -0700360 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800361 }
362 indices.resize(numIndices);
363 if (heapParams) {
364 heapParams->reserve(heapParams->size() + numIndices);
365 }
366 c2_status_t status;
Wonsik Kim138db0d2023-11-02 16:02:01 -0700367 Return<void> transResult = mHidlConfigurable->query(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800368 indices,
369 true,
370 [&status, &numStackIndices, &stackParams, heapParams](
Wonsik Kim138db0d2023-11-02 16:02:01 -0700371 c2_hidl::Status s, const c2_hidl::Params& p) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800372 status = static_cast<c2_status_t>(s);
373 if (status != C2_OK && status != C2_BAD_INDEX) {
374 LOG(DEBUG) << "query -- call failed: "
375 << status << ".";
376 return;
377 }
378 std::vector<C2Param*> paramPointers;
Wonsik Kim138db0d2023-11-02 16:02:01 -0700379 if (!c2_hidl::utils::parseParamsBlob(&paramPointers, p)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800380 LOG(ERROR) << "query -- error while parsing params.";
381 status = C2_CORRUPTED;
382 return;
383 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700384 status = UpdateQueryResult(
385 paramPointers, numStackIndices, stackParams, heapParams);
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800386 });
387 if (!transResult.isOk()) {
388 LOG(ERROR) << "query -- transaction failed.";
389 return C2_TRANSACTION_FAILED;
390 }
391 return status;
392 }
393
Wonsik Kim138db0d2023-11-02 16:02:01 -0700394 c2_status_t querySupportedParams_nb(
395 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override {
396 if (mAidlStore) {
397 return querySupportedParams_nb_aidl(params);
398 } else if (mHidlStore) {
399 return querySupportedParams_nb_hidl(params);
400 } else {
401 return C2_OMITTED;
402 }
403 }
404
405 c2_status_t querySupportedParams_nb_aidl(
406 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
407 c2_status_t status = C2_OK;
408 std::vector<c2_aidl::ParamDescriptor> aidlParams;
409 ScopedAStatus transResult = mAidlConfigurable->querySupportedParams(
410 std::numeric_limits<uint32_t>::min(),
411 std::numeric_limits<uint32_t>::max(),
412 &aidlParams);
413 if (!transResult.isOk()) {
414 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
415 status = c2_status_t(transResult.getServiceSpecificError());
416 LOG(DEBUG) << "querySupportedParams -- call failed: "
417 << status << ".";
418 return status;
419 } else {
420 LOG(ERROR) << "querySupportedParams -- transaction failed.";
421 return C2_TRANSACTION_FAILED;
422 }
423 }
424
425 size_t i = params->size();
426 params->resize(i + aidlParams.size());
427 for (const c2_aidl::ParamDescriptor& sp : aidlParams) {
428 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
429 LOG(ERROR) << "querySupportedParams -- "
430 << "invalid returned ParamDescriptor.";
431 break;
432 }
433 }
434 return status;
435 }
436
437 c2_status_t querySupportedParams_nb_hidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800438 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
439 c2_status_t status;
Wonsik Kim138db0d2023-11-02 16:02:01 -0700440 Return<void> transResult = mHidlConfigurable->querySupportedParams(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800441 std::numeric_limits<uint32_t>::min(),
442 std::numeric_limits<uint32_t>::max(),
443 [&status, params](
Wonsik Kim138db0d2023-11-02 16:02:01 -0700444 c2_hidl::Status s,
445 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800446 status = static_cast<c2_status_t>(s);
447 if (status != C2_OK) {
448 LOG(DEBUG) << "querySupportedParams -- call failed: "
449 << status << ".";
450 return;
451 }
452 size_t i = params->size();
453 params->resize(i + p.size());
Wonsik Kim138db0d2023-11-02 16:02:01 -0700454 for (const c2_hidl::ParamDescriptor& sp : p) {
455 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800456 LOG(ERROR) << "querySupportedParams -- "
457 << "invalid returned ParamDescriptor.";
458 return;
459 }
460 }
461 });
462 if (!transResult.isOk()) {
463 LOG(ERROR) << "querySupportedParams -- transaction failed.";
464 return C2_TRANSACTION_FAILED;
465 }
466 return status;
467 }
468
Wonsik Kim138db0d2023-11-02 16:02:01 -0700469 c2_status_t querySupportedValues_sm(
470 std::vector<C2FieldSupportedValuesQuery> &fields) const override {
471 if (mAidlStore) {
472 return querySupportedValues_sm_aidl(fields);
473 } else if (mHidlStore) {
474 return querySupportedValues_sm_hidl(fields);
475 } else {
476 return C2_OMITTED;
477 }
478 }
479
480 c2_status_t querySupportedValues_sm_aidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800481 std::vector<C2FieldSupportedValuesQuery> &fields) const {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700482 std::vector<c2_aidl::FieldSupportedValuesQuery> aidlFields(fields.size());
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800483 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700484 if (!c2_aidl::utils::ToAidl(&aidlFields[i], fields[i])) {
485 LOG(ERROR) << "querySupportedValues -- bad input";
486 return C2_TRANSACTION_FAILED;
487 }
488 }
489
490 c2_status_t status = C2_OK;
491 std::vector<c2_aidl::FieldSupportedValuesQueryResult> queryResults;
492 ScopedAStatus transResult = mAidlConfigurable->querySupportedValues(
493 aidlFields, true, &queryResults);
494 if (!transResult.isOk()) {
495 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
496 status = c2_status_t(transResult.getServiceSpecificError());
497 LOG(DEBUG) << "querySupportedValues -- call failed: "
498 << status << ".";
499 return status;
500 } else {
501 LOG(ERROR) << "querySupportedValues -- transaction failed.";
502 return C2_TRANSACTION_FAILED;
503 }
504 }
505 if (queryResults.size() != fields.size()) {
506 LOG(ERROR) << "querySupportedValues -- "
507 "input and output lists "
508 "have different sizes.";
509 return C2_CORRUPTED;
510 }
511 for (size_t i = 0; i < fields.size(); ++i) {
512 if (!c2_aidl::utils::FromAidl(&fields[i], aidlFields[i], queryResults[i])) {
513 LOG(ERROR) << "querySupportedValues -- "
514 "invalid returned value.";
515 return C2_CORRUPTED;
516 }
517 }
518 return status;
519 }
520
521 c2_status_t querySupportedValues_sm_hidl(
522 std::vector<C2FieldSupportedValuesQuery> &fields) const {
523 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
524 for (size_t i = 0; i < fields.size(); ++i) {
525 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800526 LOG(ERROR) << "querySupportedValues -- bad input";
527 return C2_TRANSACTION_FAILED;
528 }
529 }
530
531 c2_status_t status;
Wonsik Kim138db0d2023-11-02 16:02:01 -0700532 Return<void> transResult = mHidlConfigurable->querySupportedValues(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800533 inFields,
534 true,
535 [&status, &inFields, &fields](
Wonsik Kim138db0d2023-11-02 16:02:01 -0700536 c2_hidl::Status s,
537 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800538 status = static_cast<c2_status_t>(s);
539 if (status != C2_OK) {
540 LOG(DEBUG) << "querySupportedValues -- call failed: "
541 << status << ".";
542 return;
543 }
544 if (r.size() != fields.size()) {
545 LOG(ERROR) << "querySupportedValues -- "
546 "input and output lists "
547 "have different sizes.";
548 status = C2_CORRUPTED;
549 return;
550 }
551 for (size_t i = 0; i < fields.size(); ++i) {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700552 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800553 LOG(ERROR) << "querySupportedValues -- "
554 "invalid returned value.";
555 status = C2_CORRUPTED;
556 return;
557 }
558 }
559 });
560 if (!transResult.isOk()) {
561 LOG(ERROR) << "querySupportedValues -- transaction failed.";
562 return C2_TRANSACTION_FAILED;
563 }
564 return status;
565 }
566
Wonsik Kim138db0d2023-11-02 16:02:01 -0700567 C2String getName() const override {
568 C2String outName = "(unknown)";
569 if (mAidlStore) {
570 ScopedAStatus transResult = mAidlConfigurable->getName(&outName);
571 if (!transResult.isOk()) {
572 LOG(ERROR) << "getName -- transaction failed.";
573 }
574 } else if (mHidlStore) {
575 Return<void> transResult = mHidlConfigurable->getName(
576 [&outName](const hidl_string& name) {
577 outName = name.c_str();
578 });
579 if (!transResult.isOk()) {
580 LOG(ERROR) << "getName -- transaction failed.";
581 }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800582 }
583 return outName;
584 }
585
Wonsik Kim138db0d2023-11-02 16:02:01 -0700586 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800587 struct SimpleParamReflector : public C2ParamReflector {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700588 std::unique_ptr<C2StructDescriptor> describe(
589 C2Param::CoreIndex coreIndex) const override {
590 if (mAidlBase) {
591 return describe_aidl(coreIndex);
592 } else if (mHidlBase) {
593 return describe_hidl(coreIndex);
594 } else {
595 return nullptr;
596 }
597 }
598
599 std::unique_ptr<C2StructDescriptor> describe_aidl(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800600 C2Param::CoreIndex coreIndex) const {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700601 std::vector<int32_t> indices(1);
602 indices[0] = coreIndex.coreIndex();
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800603 std::unique_ptr<C2StructDescriptor> descriptor;
Wonsik Kim138db0d2023-11-02 16:02:01 -0700604 std::vector<c2_aidl::StructDescriptor> aidlDescs;
605 ScopedAStatus transResult = mAidlBase->getStructDescriptors(
606 indices, &aidlDescs);
607 if (!transResult.isOk()) {
608 c2_status_t status = C2_TRANSACTION_FAILED;
609 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
610 status = c2_status_t(transResult.getServiceSpecificError());
611 LOG(DEBUG) << "SimpleParamReflector -- "
612 "getStructDescriptors() failed: "
613 << status << ".";
614 return nullptr;
615 }
616 }
617 if (aidlDescs.size() != 1) {
618 LOG(DEBUG) << "SimpleParamReflector -- "
619 "getStructDescriptors() "
620 "returned vector of size "
621 << aidlDescs.size() << ". "
622 "It should be 1.";
623 return nullptr;
624 }
625 if (!c2_aidl::utils::FromAidl(&descriptor, aidlDescs[0])) {
626 LOG(DEBUG) << "SimpleParamReflector -- "
627 "getStructDescriptors() returned "
628 "corrupted data.";
629 return nullptr;
630 }
631 return descriptor;
632 }
633
634 std::unique_ptr<C2StructDescriptor> describe_hidl(
635 C2Param::CoreIndex coreIndex) const {
636 hidl_vec<c2_hidl::ParamIndex> indices(1);
637 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
638 std::unique_ptr<C2StructDescriptor> descriptor;
639 Return<void> transResult = mHidlBase->getStructDescriptors(
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800640 indices,
641 [&descriptor](
Wonsik Kim138db0d2023-11-02 16:02:01 -0700642 c2_hidl::Status s,
643 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800644 c2_status_t status = static_cast<c2_status_t>(s);
645 if (status != C2_OK) {
646 LOG(DEBUG) << "SimpleParamReflector -- "
647 "getStructDescriptors() failed: "
648 << status << ".";
649 descriptor.reset();
650 return;
651 }
652 if (sd.size() != 1) {
653 LOG(DEBUG) << "SimpleParamReflector -- "
654 "getStructDescriptors() "
655 "returned vector of size "
656 << sd.size() << ". "
657 "It should be 1.";
658 descriptor.reset();
659 return;
660 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700661 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800662 LOG(DEBUG) << "SimpleParamReflector -- "
663 "getStructDescriptors() returned "
664 "corrupted data.";
665 descriptor.reset();
666 return;
667 }
668 });
669 return descriptor;
670 }
671
Wonsik Kim138db0d2023-11-02 16:02:01 -0700672 explicit SimpleParamReflector(const sp<HidlComponentStore> &base)
673 : mHidlBase(base) { }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800674
Wonsik Kim138db0d2023-11-02 16:02:01 -0700675 explicit SimpleParamReflector(const std::shared_ptr<AidlComponentStore> &base)
676 : mAidlBase(base) { }
677
678 std::shared_ptr<AidlComponentStore> mAidlBase;
679 sp<HidlComponentStore> mHidlBase;
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800680 };
681
Wonsik Kim138db0d2023-11-02 16:02:01 -0700682 if (mAidlStore) {
683 return std::make_shared<SimpleParamReflector>(mAidlStore);
684 } else if (mHidlStore) {
685 return std::make_shared<SimpleParamReflector>(mHidlStore);
686 } else {
687 return nullptr;
688 }
Pawin Vongmasa6c09c002019-12-16 04:25:41 -0800689 }
690
691 virtual std::vector<std::shared_ptr<const C2Component::Traits>>
692 listComponents() override {
693 LOG(ERROR) << "listComponents -- not supported.";
694 return {};
695 }
696};
697
698bool ionPropertiesDefined() {
699 using namespace ::android::base;
700 std::string heapMask =
701 GetProperty("ro.com.android.media.swcodec.ion.heapmask", "undefined");
702 std::string flags =
703 GetProperty("ro.com.android.media.swcodec.ion.flags", "undefined");
704 std::string align =
705 GetProperty("ro.com.android.media.swcodec.ion.align", "undefined");
706 if (heapMask != "undefined" ||
707 flags != "undefined" ||
708 align != "undefined") {
709 LOG(INFO)
710 << "Some system properties for mediaswcodec ION usage are set: "
711 << "heapmask = " << heapMask << ", "
712 << "flags = " << flags << ", "
713 << "align = " << align << ". "
714 << "Preferred Codec2 store is defaulted to \"software\".";
715 return true;
716 }
717 return false;
718}
719
720} // unnamed namespace
721
Pawin Vongmasa36653902018-11-15 00:10:25 -0800722extern "C" void RegisterCodecServices() {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700723 const bool aidlSelected = c2_aidl::utils::IsSelected();
724 constexpr int kThreadCount = 64;
725 ABinderProcess_setThreadPoolMaxThreadCount(kThreadCount);
726 ABinderProcess_startThreadPool();
727 ::android::hardware::configureRpcThreadpool(kThreadCount, false);
728
Pawin Vongmasae55ed3f2018-11-28 03:39:57 -0800729 LOG(INFO) << "Creating software Codec2 service...";
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800730 std::shared_ptr<C2ComponentStore> store =
731 android::GetCodec2PlatformComponentStore();
732 if (!store) {
733 LOG(ERROR) << "Failed to create Codec2 service.";
734 return;
735 }
736
737 using namespace ::android::hardware::media::c2;
738
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700739 int platformVersion = android_get_device_api_level();
Wonsik Kim60f836d2023-11-15 14:08:43 -0800740 // STOPSHIP: Remove code name checking once platform version bumps up to 35.
741 std::string codeName =
742 android::base::GetProperty("ro.build.version.codename", "");
743 if (codeName == "VanillaIceCream") {
744 platformVersion = __ANDROID_API_V__;
745 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800746
Wonsik Kim138db0d2023-11-02 16:02:01 -0700747 android::sp<V1_0::IComponentStore> hidlStore;
748 std::shared_ptr<c2_aidl::IComponentStore> aidlStore;
749 const char *hidlVer = "(unknown)";
750 if (aidlSelected) {
751 aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(store);
752 } else if (platformVersion >= __ANDROID_API_S__) {
753 hidlStore = ::android::sp<V1_2::utils::ComponentStore>::make(store);
754 hidlVer = "1.2";
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700755 } else if (platformVersion == __ANDROID_API_R__) {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700756 hidlStore = ::android::sp<V1_1::utils::ComponentStore>::make(store);
757 hidlVer = "1.1";
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700758 } else if (platformVersion == __ANDROID_API_Q__) {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700759 hidlStore = ::android::sp<V1_0::utils::ComponentStore>::make(store);
760 hidlVer = "1.0";
Wonsik Kimbe1e4642021-11-03 18:26:22 -0700761 } else { // platformVersion < __ANDROID_API_Q__
762 LOG(ERROR) << "The platform version " << platformVersion <<
763 " is not supported.";
764 return;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800765 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800766 if (!ionPropertiesDefined()) {
767 using IComponentStore =
768 ::android::hardware::media::c2::V1_0::IComponentStore;
769 std::string const preferredStoreName = "default";
Wonsik Kim138db0d2023-11-02 16:02:01 -0700770 if (aidlSelected) {
771 std::shared_ptr<c2_aidl::IComponentStore> preferredStore;
772 if (__builtin_available(android __ANDROID_API_S__, *)) {
773 std::string instanceName = ::android::base::StringPrintf(
774 "%s/%s", c2_aidl::IComponentStore::descriptor, preferredStoreName.c_str());
775 if (AServiceManager_isDeclared(instanceName.c_str())) {
776 preferredStore = c2_aidl::IComponentStore::fromBinder(::ndk::SpAIBinder(
777 AServiceManager_waitForService(instanceName.c_str())));
778 }
779 }
780 if (preferredStore) {
781 ::android::SetPreferredCodec2ComponentStore(
782 std::make_shared<H2C2ComponentStore>(preferredStore));
783 LOG(INFO) <<
784 "Preferred Codec2 AIDL store is set to \"" <<
785 preferredStoreName << "\".";
786 } else {
787 LOG(INFO) <<
788 "Preferred Codec2 AIDL store is defaulted to \"software\".";
789 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800790 } else {
Wonsik Kim138db0d2023-11-02 16:02:01 -0700791 sp<IComponentStore> preferredStore =
792 IComponentStore::getService(preferredStoreName.c_str());
793 if (preferredStore) {
794 ::android::SetPreferredCodec2ComponentStore(
795 std::make_shared<H2C2ComponentStore>(preferredStore));
796 LOG(INFO) <<
797 "Preferred Codec2 HIDL store is set to \"" <<
798 preferredStoreName << "\".";
799 } else {
800 LOG(INFO) <<
801 "Preferred Codec2 HIDL store is defaulted to \"software\".";
802 }
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800803 }
804 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700805
Wonsik Kim60f836d2023-11-15 14:08:43 -0800806 if (platformVersion >= __ANDROID_API_V__) {
807 if (!aidlStore) {
808 aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(
809 std::make_shared<H2C2ComponentStore>(nullptr));
810 }
811 const std::string serviceName =
812 std::string(c2_aidl::IComponentStore::descriptor) + "/software";
813 binder_exception_t ex = AServiceManager_addService(
814 aidlStore->asBinder().get(), serviceName.c_str());
815 if (ex != EX_NONE) {
816 LOG(ERROR) << "Cannot register software Codec2 AIDL service.";
817 return;
818 }
Wonsik Kim138db0d2023-11-02 16:02:01 -0700819 }
820
821 if (!hidlStore) {
822 hidlStore = ::android::sp<V1_0::utils::ComponentStore>::make(
823 std::make_shared<H2C2ComponentStore>(nullptr));
824 hidlVer = "1.0";
825 }
826 if (hidlStore->registerAsService("software") != android::OK) {
827 LOG(ERROR) << "Cannot register software Codec2 v" << hidlVer << " service.";
828 return;
829 }
830
Dongwon Kang2d91d3f2019-12-09 13:53:34 -0800831 LOG(INFO) << "Software Codec2 service created and registered.";
Wonsik Kim138db0d2023-11-02 16:02:01 -0700832
833 ABinderProcess_joinThreadPool();
834 ::android::hardware::joinRpcThreadpool();
Pawin Vongmasa36653902018-11-15 00:10:25 -0800835}
836