1 /*
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
18 #define LOG_TAG "CodecServiceRegistrant"
19
20 #include <android/api-level.h>
21 #include <android-base/logging.h>
22 #include <android-base/properties.h>
23 #include <android-base/stringprintf.h>
24
25 #include <C2Component.h>
26 #include <C2PlatformSupport.h>
27
28 #include <android/hidl/manager/1.2/IServiceManager.h>
29 #include <codec2/hidl/1.0/ComponentStore.h>
30 #include <codec2/hidl/1.1/ComponentStore.h>
31 #include <codec2/hidl/1.2/ComponentStore.h>
32 #include <codec2/hidl/1.2/Configurable.h>
33 #include <codec2/hidl/1.2/types.h>
34 #include <hidl/HidlSupport.h>
35 #include <hidl/HidlTransportSupport.h>
36
37 #include <android/binder_interface_utils.h>
38 #include <android/binder_manager.h>
39 #include <android/binder_process.h>
40 #include <codec2/aidl/ComponentStore.h>
41 #include <codec2/aidl/ParamTypes.h>
42
43 #include <media/CodecServiceRegistrant.h>
44
45 namespace /* unnamed */ {
46
47 using ::android::hardware::hidl_vec;
48 using ::android::hardware::hidl_string;
49 using ::android::hardware::Return;
50 using ::android::sp;
51 using ::ndk::ScopedAStatus;
52 namespace c2_hidl_V1_0 = ::android::hardware::media::c2::V1_0;
53 namespace c2_hidl = ::android::hardware::media::c2::V1_2;
54 namespace c2_aidl = ::aidl::android::hardware::media::c2;
55
56 constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
57
58 // Converter from IComponentStore to C2ComponentStore.
59 class H2C2ComponentStore : public C2ComponentStore {
60 protected:
61 using HidlComponentStore =
62 ::android::hardware::media::c2::V1_0::IComponentStore;
63 using HidlConfigurable =
64 ::android::hardware::media::c2::V1_0::IConfigurable;
65 sp<HidlComponentStore> mHidlStore;
66 sp<HidlConfigurable> mHidlConfigurable;
67
68 using AidlComponentStore =
69 ::aidl::android::hardware::media::c2::IComponentStore;
70 using AidlConfigurable =
71 ::aidl::android::hardware::media::c2::IConfigurable;
72 std::shared_ptr<AidlComponentStore> mAidlStore;
73 std::shared_ptr<AidlConfigurable> mAidlConfigurable;
74 public:
H2C2ComponentStore(nullptr_t)75 explicit H2C2ComponentStore(nullptr_t) {
76 }
77
H2C2ComponentStore(sp<HidlComponentStore> const & store)78 explicit H2C2ComponentStore(sp<HidlComponentStore> const& store)
79 : mHidlStore{store},
__anon3c75bd310202() 80 mHidlConfigurable{[store]() -> sp<HidlConfigurable>{
81 if (!store) {
82 return nullptr;
83 }
84 Return<sp<HidlConfigurable>> transResult =
85 store->getConfigurable();
86 return transResult.isOk() ?
87 static_cast<sp<HidlConfigurable>>(transResult) :
88 nullptr;
89 }()} {
90 if (!mHidlConfigurable) {
91 LOG(ERROR) << "Preferred store is corrupted.";
92 }
93 }
94
H2C2ComponentStore(std::shared_ptr<AidlComponentStore> const & store)95 explicit H2C2ComponentStore(std::shared_ptr<AidlComponentStore> const& store)
96 : mAidlStore{store},
__anon3c75bd310302() 97 mAidlConfigurable{[store]() -> std::shared_ptr<AidlConfigurable>{
98 if (!store) {
99 return nullptr;
100 }
101 std::shared_ptr<AidlConfigurable> configurable;
102 ScopedAStatus status = store->getConfigurable(&configurable);
103 if (!status.isOk()) {
104 return nullptr;
105 }
106 return configurable;
107 }()} {
108 if (!mAidlConfigurable) {
109 LOG(ERROR) << "Preferred store is corrupted.";
110 }
111 }
112
113 virtual ~H2C2ComponentStore() override = default;
114
config_sm(std::vector<C2Param * > const & params,std::vector<std::unique_ptr<C2SettingResult>> * const failures)115 c2_status_t config_sm(
116 std::vector<C2Param*> const ¶ms,
117 std::vector<std::unique_ptr<C2SettingResult>>* const failures
118 ) override {
119 if (mAidlStore) {
120 return config_sm_aidl(params, failures);
121 } else if (mHidlStore) {
122 return config_sm_hidl(params, failures);
123 } else {
124 return C2_OMITTED;
125 }
126 }
127
config_sm_aidl(std::vector<C2Param * > const & params,std::vector<std::unique_ptr<C2SettingResult>> * const failures)128 c2_status_t config_sm_aidl(
129 std::vector<C2Param*> const ¶ms,
130 std::vector<std::unique_ptr<C2SettingResult>>* const failures
131 ) {
132 c2_aidl::Params aidlParams;
133 if (!c2_aidl::utils::CreateParamsBlob(&aidlParams, params)) {
134 LOG(ERROR) << "config -- bad input.";
135 return C2_TRANSACTION_FAILED;
136 }
137 c2_status_t status = C2_OK;
138 c2_aidl::IConfigurable::ConfigResult configResult;
139 ScopedAStatus transResult = mAidlConfigurable->config(
140 aidlParams, true, &configResult);
141 if (!transResult.isOk()) {
142 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
143 status = c2_status_t(transResult.getServiceSpecificError());
144 if (status != C2_BAD_INDEX) {
145 LOG(DEBUG) << "config -- call failed: "
146 << status << ".";
147 }
148 } else {
149 LOG(ERROR) << "config -- transaction failed.";
150 return C2_TRANSACTION_FAILED;
151 }
152 }
153 status = static_cast<c2_status_t>(configResult.status.status);
154 if (status != C2_BAD_INDEX) {
155 LOG(DEBUG) << "config -- call failed: "
156 << status << ".";
157 }
158 size_t i = failures->size();
159 failures->resize(i + configResult.failures.size());
160 for (const c2_aidl::SettingResult& sf : configResult.failures) {
161 if (!c2_aidl::utils::FromAidl(&(*failures)[i++], sf)) {
162 LOG(ERROR) << "config -- "
163 << "invalid SettingResult returned.";
164 status = C2_CORRUPTED;
165 }
166 }
167 if (!c2_aidl::utils::UpdateParamsFromBlob(params, configResult.params)) {
168 LOG(ERROR) << "config -- "
169 << "failed to parse returned params.";
170 status = C2_CORRUPTED;
171 }
172 return status;
173 };
174
config_sm_hidl(std::vector<C2Param * > const & params,std::vector<std::unique_ptr<C2SettingResult>> * const failures)175 c2_status_t config_sm_hidl(
176 std::vector<C2Param*> const ¶ms,
177 std::vector<std::unique_ptr<C2SettingResult>>* const failures
178 ) {
179 c2_hidl::Params hidlParams;
180 if (!c2_hidl::utils::createParamsBlob(&hidlParams, params)) {
181 LOG(ERROR) << "config -- bad input.";
182 return C2_TRANSACTION_FAILED;
183 }
184 c2_status_t status{};
185 Return<void> transResult = mHidlConfigurable->config(
186 hidlParams,
187 true,
188 [&status, ¶ms, failures](
189 c2_hidl::Status s,
190 const hidl_vec<c2_hidl::SettingResult> f,
191 const c2_hidl::Params& o) {
192 status = static_cast<c2_status_t>(s);
193 if (status != C2_OK && status != C2_BAD_INDEX) {
194 LOG(DEBUG) << "config -- call failed: "
195 << status << ".";
196 }
197 size_t i = failures->size();
198 failures->resize(i + f.size());
199 for (const c2_hidl::SettingResult& sf : f) {
200 if (!c2_hidl::utils::objcpy(&(*failures)[i++], sf)) {
201 LOG(ERROR) << "config -- "
202 << "invalid SettingResult returned.";
203 return;
204 }
205 }
206 if (!c2_hidl::utils::updateParamsFromBlob(params, o)) {
207 LOG(ERROR) << "config -- "
208 << "failed to parse returned params.";
209 status = C2_CORRUPTED;
210 }
211 });
212 if (!transResult.isOk()) {
213 LOG(ERROR) << "config -- transaction failed.";
214 return C2_TRANSACTION_FAILED;
215 }
216 return status;
217 };
218
copyBuffer(std::shared_ptr<C2GraphicBuffer>,std::shared_ptr<C2GraphicBuffer>)219 c2_status_t copyBuffer(
220 std::shared_ptr<C2GraphicBuffer>,
221 std::shared_ptr<C2GraphicBuffer>) override {
222 LOG(ERROR) << "copyBuffer -- not supported.";
223 return C2_OMITTED;
224 }
225
createComponent(C2String,std::shared_ptr<C2Component> * const component)226 c2_status_t createComponent(
227 C2String, std::shared_ptr<C2Component> *const component) override {
228 component->reset();
229 LOG(ERROR) << "createComponent -- not supported.";
230 return C2_OMITTED;
231 }
232
createInterface(C2String,std::shared_ptr<C2ComponentInterface> * const interface)233 c2_status_t createInterface(
234 C2String, std::shared_ptr<C2ComponentInterface> *const interface) override {
235 interface->reset();
236 LOG(ERROR) << "createInterface -- not supported.";
237 return C2_OMITTED;
238 }
239
query_sm(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const heapParams) const240 c2_status_t query_sm(
241 const std::vector<C2Param *> &stackParams,
242 const std::vector<C2Param::Index> &heapParamIndices,
243 std::vector<std::unique_ptr<C2Param>> *const heapParams) const override {
244 if (mAidlStore) {
245 return query_sm_aidl(stackParams, heapParamIndices, heapParams);
246 } else if (mHidlStore) {
247 return query_sm_hidl(stackParams, heapParamIndices, heapParams);
248 } else {
249 return C2_OMITTED;
250 }
251 }
252
UpdateQueryResult(const std::vector<C2Param * > & paramPointers,size_t numStackIndices,const std::vector<C2Param * > & stackParams,std::vector<std::unique_ptr<C2Param>> * const heapParams)253 static c2_status_t UpdateQueryResult(
254 const std::vector<C2Param *> ¶mPointers,
255 size_t numStackIndices,
256 const std::vector<C2Param *> &stackParams,
257 std::vector<std::unique_ptr<C2Param>> *const heapParams) {
258 c2_status_t status = C2_OK;
259 size_t i = 0;
260 for (auto it = paramPointers.begin(); it != paramPointers.end(); ) {
261 C2Param* paramPointer = *it;
262 if (numStackIndices > 0) {
263 --numStackIndices;
264 if (!paramPointer) {
265 LOG(WARNING) << "query -- null stack param.";
266 ++it;
267 continue;
268 }
269 for (; i < stackParams.size() && !stackParams[i]; ) {
270 ++i;
271 }
272 if (i >= stackParams.size()) {
273 LOG(ERROR) << "query -- unexpected error.";
274 status = C2_CORRUPTED;
275 break;
276 }
277 if (stackParams[i]->index() != paramPointer->index()) {
278 LOG(WARNING) << "query -- param skipped: "
279 "index = "
280 << stackParams[i]->index() << ".";
281 stackParams[i++]->invalidate();
282 continue;
283 }
284 if (!stackParams[i++]->updateFrom(*paramPointer)) {
285 LOG(WARNING) << "query -- param update failed: "
286 "index = "
287 << paramPointer->index() << ".";
288 }
289 } else {
290 if (!paramPointer) {
291 LOG(WARNING) << "query -- null heap param.";
292 ++it;
293 continue;
294 }
295 if (!heapParams) {
296 LOG(WARNING) << "query -- "
297 "unexpected extra stack param.";
298 } else {
299 heapParams->emplace_back(
300 C2Param::Copy(*paramPointer));
301 }
302 }
303 ++it;
304 }
305 return status;
306 }
307
query_sm_aidl(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const heapParams) const308 c2_status_t query_sm_aidl(
309 const std::vector<C2Param *> &stackParams,
310 const std::vector<C2Param::Index> &heapParamIndices,
311 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
312 std::vector<int32_t> indices;
313 size_t numIndices = 0;
314 for (C2Param* const& stackParam : stackParams) {
315 if (!stackParam) {
316 LOG(WARNING) << "query -- null stack param encountered.";
317 continue;
318 }
319 indices[numIndices++] = stackParam->index();
320 }
321 size_t numStackIndices = numIndices;
322 for (const C2Param::Index& index : heapParamIndices) {
323 indices[numIndices++] = static_cast<uint32_t>(index);
324 }
325 indices.resize(numIndices);
326 if (heapParams) {
327 heapParams->reserve(heapParams->size() + numIndices);
328 }
329 c2_status_t status = C2_OK;
330 c2_aidl::IConfigurable::QueryResult aidlResult;
331 ScopedAStatus transResult = mAidlConfigurable->query(indices, true, &aidlResult);
332 if (!transResult.isOk()) {
333 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
334 status = c2_status_t(transResult.getServiceSpecificError());
335 LOG(DEBUG) << "query -- call failed: " << status << ".";
336 return status;
337 } else {
338 LOG(ERROR) << "query -- transaction failed.";
339 return C2_TRANSACTION_FAILED;
340 }
341 }
342 status = static_cast<c2_status_t>(aidlResult.status.status);
343 if (status != C2_OK) {
344 LOG(DEBUG) << "query -- call failed: " << status << ".";
345 }
346 std::vector<C2Param*> paramPointers;
347 if (!c2_aidl::utils::ParseParamsBlob(¶mPointers, aidlResult.params)) {
348 LOG(ERROR) << "query -- error while parsing params.";
349 return C2_CORRUPTED;
350 }
351 return UpdateQueryResult(paramPointers, numStackIndices, stackParams, heapParams);
352 }
353
query_sm_hidl(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const heapParams) const354 c2_status_t query_sm_hidl(
355 const std::vector<C2Param *> &stackParams,
356 const std::vector<C2Param::Index> &heapParamIndices,
357 std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
358 hidl_vec<c2_hidl::ParamIndex> indices(
359 stackParams.size() + heapParamIndices.size());
360 size_t numIndices = 0;
361 for (C2Param* const& stackParam : stackParams) {
362 if (!stackParam) {
363 LOG(WARNING) << "query -- null stack param encountered.";
364 continue;
365 }
366 indices[numIndices++] = static_cast<c2_hidl::ParamIndex>(stackParam->index());
367 }
368 size_t numStackIndices = numIndices;
369 for (const C2Param::Index& index : heapParamIndices) {
370 indices[numIndices++] =
371 static_cast<c2_hidl::ParamIndex>(static_cast<uint32_t>(index));
372 }
373 indices.resize(numIndices);
374 if (heapParams) {
375 heapParams->reserve(heapParams->size() + numIndices);
376 }
377 c2_status_t status;
378 Return<void> transResult = mHidlConfigurable->query(
379 indices,
380 true,
381 [&status, &numStackIndices, &stackParams, heapParams](
382 c2_hidl::Status s, const c2_hidl::Params& p) {
383 status = static_cast<c2_status_t>(s);
384 if (status != C2_OK && status != C2_BAD_INDEX) {
385 LOG(DEBUG) << "query -- call failed: "
386 << status << ".";
387 return;
388 }
389 std::vector<C2Param*> paramPointers;
390 if (!c2_hidl::utils::parseParamsBlob(¶mPointers, p)) {
391 LOG(ERROR) << "query -- error while parsing params.";
392 status = C2_CORRUPTED;
393 return;
394 }
395 status = UpdateQueryResult(
396 paramPointers, numStackIndices, stackParams, heapParams);
397 });
398 if (!transResult.isOk()) {
399 LOG(ERROR) << "query -- transaction failed.";
400 return C2_TRANSACTION_FAILED;
401 }
402 return status;
403 }
404
querySupportedParams_nb(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const405 c2_status_t querySupportedParams_nb(
406 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override {
407 if (mAidlStore) {
408 return querySupportedParams_nb_aidl(params);
409 } else if (mHidlStore) {
410 return querySupportedParams_nb_hidl(params);
411 } else {
412 return C2_OMITTED;
413 }
414 }
415
querySupportedParams_nb_aidl(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const416 c2_status_t querySupportedParams_nb_aidl(
417 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
418 c2_status_t status = C2_OK;
419 std::vector<c2_aidl::ParamDescriptor> aidlParams;
420 ScopedAStatus transResult = mAidlConfigurable->querySupportedParams(
421 std::numeric_limits<uint32_t>::min(),
422 std::numeric_limits<uint32_t>::max(),
423 &aidlParams);
424 if (!transResult.isOk()) {
425 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
426 status = c2_status_t(transResult.getServiceSpecificError());
427 LOG(DEBUG) << "querySupportedParams -- call failed: "
428 << status << ".";
429 return status;
430 } else {
431 LOG(ERROR) << "querySupportedParams -- transaction failed.";
432 return C2_TRANSACTION_FAILED;
433 }
434 }
435
436 size_t i = params->size();
437 params->resize(i + aidlParams.size());
438 for (const c2_aidl::ParamDescriptor& sp : aidlParams) {
439 if (!c2_aidl::utils::FromAidl(&(*params)[i++], sp)) {
440 LOG(ERROR) << "querySupportedParams -- "
441 << "invalid returned ParamDescriptor.";
442 break;
443 }
444 }
445 return status;
446 }
447
querySupportedParams_nb_hidl(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const448 c2_status_t querySupportedParams_nb_hidl(
449 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
450 c2_status_t status;
451 Return<void> transResult = mHidlConfigurable->querySupportedParams(
452 std::numeric_limits<uint32_t>::min(),
453 std::numeric_limits<uint32_t>::max(),
454 [&status, params](
455 c2_hidl::Status s,
456 const hidl_vec<c2_hidl::ParamDescriptor>& p) {
457 status = static_cast<c2_status_t>(s);
458 if (status != C2_OK) {
459 LOG(DEBUG) << "querySupportedParams -- call failed: "
460 << status << ".";
461 return;
462 }
463 size_t i = params->size();
464 params->resize(i + p.size());
465 for (const c2_hidl::ParamDescriptor& sp : p) {
466 if (!c2_hidl::utils::objcpy(&(*params)[i++], sp)) {
467 LOG(ERROR) << "querySupportedParams -- "
468 << "invalid returned ParamDescriptor.";
469 return;
470 }
471 }
472 });
473 if (!transResult.isOk()) {
474 LOG(ERROR) << "querySupportedParams -- transaction failed.";
475 return C2_TRANSACTION_FAILED;
476 }
477 return status;
478 }
479
querySupportedValues_sm(std::vector<C2FieldSupportedValuesQuery> & fields) const480 c2_status_t querySupportedValues_sm(
481 std::vector<C2FieldSupportedValuesQuery> &fields) const override {
482 if (mAidlStore) {
483 return querySupportedValues_sm_aidl(fields);
484 } else if (mHidlStore) {
485 return querySupportedValues_sm_hidl(fields);
486 } else {
487 return C2_OMITTED;
488 }
489 }
490
querySupportedValues_sm_aidl(std::vector<C2FieldSupportedValuesQuery> & fields) const491 c2_status_t querySupportedValues_sm_aidl(
492 std::vector<C2FieldSupportedValuesQuery> &fields) const {
493 std::vector<c2_aidl::FieldSupportedValuesQuery> aidlFields(fields.size());
494 for (size_t i = 0; i < fields.size(); ++i) {
495 if (!c2_aidl::utils::ToAidl(&aidlFields[i], fields[i])) {
496 LOG(ERROR) << "querySupportedValues -- bad input";
497 return C2_TRANSACTION_FAILED;
498 }
499 }
500
501 c2_status_t status = C2_OK;
502 c2_aidl::IConfigurable::QuerySupportedValuesResult queryResult;
503 ScopedAStatus transResult = mAidlConfigurable->querySupportedValues(
504 aidlFields, true, &queryResult);
505 if (!transResult.isOk()) {
506 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
507 status = c2_status_t(transResult.getServiceSpecificError());
508 LOG(DEBUG) << "querySupportedValues -- call failed: "
509 << status << ".";
510 return status;
511 } else {
512 LOG(ERROR) << "querySupportedValues -- transaction failed.";
513 return C2_TRANSACTION_FAILED;
514 }
515 }
516 status = static_cast<c2_status_t>(queryResult.status.status);
517 if (status != C2_OK) {
518 LOG(DEBUG) << "querySupportedValues -- call failed: "
519 << status << ".";
520 }
521 if (queryResult.values.size() != fields.size()) {
522 LOG(ERROR) << "querySupportedValues -- "
523 "input and output lists "
524 "have different sizes.";
525 return C2_CORRUPTED;
526 }
527 for (size_t i = 0; i < fields.size(); ++i) {
528 if (!c2_aidl::utils::FromAidl(&fields[i], aidlFields[i], queryResult.values[i])) {
529 LOG(ERROR) << "querySupportedValues -- "
530 "invalid returned value.";
531 return C2_CORRUPTED;
532 }
533 }
534 return status;
535 }
536
querySupportedValues_sm_hidl(std::vector<C2FieldSupportedValuesQuery> & fields) const537 c2_status_t querySupportedValues_sm_hidl(
538 std::vector<C2FieldSupportedValuesQuery> &fields) const {
539 hidl_vec<c2_hidl::FieldSupportedValuesQuery> inFields(fields.size());
540 for (size_t i = 0; i < fields.size(); ++i) {
541 if (!c2_hidl::utils::objcpy(&inFields[i], fields[i])) {
542 LOG(ERROR) << "querySupportedValues -- bad input";
543 return C2_TRANSACTION_FAILED;
544 }
545 }
546
547 c2_status_t status;
548 Return<void> transResult = mHidlConfigurable->querySupportedValues(
549 inFields,
550 true,
551 [&status, &inFields, &fields](
552 c2_hidl::Status s,
553 const hidl_vec<c2_hidl::FieldSupportedValuesQueryResult>& r) {
554 status = static_cast<c2_status_t>(s);
555 if (status != C2_OK) {
556 LOG(DEBUG) << "querySupportedValues -- call failed: "
557 << status << ".";
558 return;
559 }
560 if (r.size() != fields.size()) {
561 LOG(ERROR) << "querySupportedValues -- "
562 "input and output lists "
563 "have different sizes.";
564 status = C2_CORRUPTED;
565 return;
566 }
567 for (size_t i = 0; i < fields.size(); ++i) {
568 if (!c2_hidl::utils::objcpy(&fields[i], inFields[i], r[i])) {
569 LOG(ERROR) << "querySupportedValues -- "
570 "invalid returned value.";
571 status = C2_CORRUPTED;
572 return;
573 }
574 }
575 });
576 if (!transResult.isOk()) {
577 LOG(ERROR) << "querySupportedValues -- transaction failed.";
578 return C2_TRANSACTION_FAILED;
579 }
580 return status;
581 }
582
getName() const583 C2String getName() const override {
584 C2String outName = "(unknown)";
585 if (mAidlStore) {
586 ScopedAStatus transResult = mAidlConfigurable->getName(&outName);
587 if (!transResult.isOk()) {
588 LOG(ERROR) << "getName -- transaction failed.";
589 }
590 } else if (mHidlStore) {
591 Return<void> transResult = mHidlConfigurable->getName(
592 [&outName](const hidl_string& name) {
593 outName = name.c_str();
594 });
595 if (!transResult.isOk()) {
596 LOG(ERROR) << "getName -- transaction failed.";
597 }
598 }
599 return outName;
600 }
601
getParamReflector() const602 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
603 struct SimpleParamReflector : public C2ParamReflector {
604 std::unique_ptr<C2StructDescriptor> describe(
605 C2Param::CoreIndex coreIndex) const override {
606 if (mAidlBase) {
607 return describe_aidl(coreIndex);
608 } else if (mHidlBase) {
609 return describe_hidl(coreIndex);
610 } else {
611 return nullptr;
612 }
613 }
614
615 std::unique_ptr<C2StructDescriptor> describe_aidl(
616 C2Param::CoreIndex coreIndex) const {
617 std::vector<int32_t> indices(1);
618 indices[0] = coreIndex.coreIndex();
619 std::unique_ptr<C2StructDescriptor> descriptor;
620 std::vector<c2_aidl::StructDescriptor> aidlDescs;
621 ScopedAStatus transResult = mAidlBase->getStructDescriptors(
622 indices, &aidlDescs);
623 if (!transResult.isOk()) {
624 c2_status_t status = C2_TRANSACTION_FAILED;
625 if (transResult.getExceptionCode() == EX_SERVICE_SPECIFIC) {
626 status = c2_status_t(transResult.getServiceSpecificError());
627 LOG(DEBUG) << "SimpleParamReflector -- "
628 "getStructDescriptors() failed: "
629 << status << ".";
630 return nullptr;
631 }
632 }
633 if (aidlDescs.size() != 1) {
634 LOG(DEBUG) << "SimpleParamReflector -- "
635 "getStructDescriptors() "
636 "returned vector of size "
637 << aidlDescs.size() << ". "
638 "It should be 1.";
639 return nullptr;
640 }
641 if (!c2_aidl::utils::FromAidl(&descriptor, aidlDescs[0])) {
642 LOG(DEBUG) << "SimpleParamReflector -- "
643 "getStructDescriptors() returned "
644 "corrupted data.";
645 return nullptr;
646 }
647 return descriptor;
648 }
649
650 std::unique_ptr<C2StructDescriptor> describe_hidl(
651 C2Param::CoreIndex coreIndex) const {
652 hidl_vec<c2_hidl::ParamIndex> indices(1);
653 indices[0] = static_cast<c2_hidl::ParamIndex>(coreIndex.coreIndex());
654 std::unique_ptr<C2StructDescriptor> descriptor;
655 Return<void> transResult = mHidlBase->getStructDescriptors(
656 indices,
657 [&descriptor](
658 c2_hidl::Status s,
659 const hidl_vec<c2_hidl::StructDescriptor>& sd) {
660 c2_status_t status = static_cast<c2_status_t>(s);
661 if (status != C2_OK) {
662 LOG(DEBUG) << "SimpleParamReflector -- "
663 "getStructDescriptors() failed: "
664 << status << ".";
665 descriptor.reset();
666 return;
667 }
668 if (sd.size() != 1) {
669 LOG(DEBUG) << "SimpleParamReflector -- "
670 "getStructDescriptors() "
671 "returned vector of size "
672 << sd.size() << ". "
673 "It should be 1.";
674 descriptor.reset();
675 return;
676 }
677 if (!c2_hidl::utils::objcpy(&descriptor, sd[0])) {
678 LOG(DEBUG) << "SimpleParamReflector -- "
679 "getStructDescriptors() returned "
680 "corrupted data.";
681 descriptor.reset();
682 return;
683 }
684 });
685 return descriptor;
686 }
687
688 explicit SimpleParamReflector(const sp<HidlComponentStore> &base)
689 : mHidlBase(base) { }
690
691 explicit SimpleParamReflector(const std::shared_ptr<AidlComponentStore> &base)
692 : mAidlBase(base) { }
693
694 std::shared_ptr<AidlComponentStore> mAidlBase;
695 sp<HidlComponentStore> mHidlBase;
696 };
697
698 if (mAidlStore) {
699 return std::make_shared<SimpleParamReflector>(mAidlStore);
700 } else if (mHidlStore) {
701 return std::make_shared<SimpleParamReflector>(mHidlStore);
702 } else {
703 return nullptr;
704 }
705 }
706
707 virtual std::vector<std::shared_ptr<const C2Component::Traits>>
listComponents()708 listComponents() override {
709 LOG(ERROR) << "listComponents -- not supported.";
710 return {};
711 }
712 };
713
ionPropertiesDefined()714 bool ionPropertiesDefined() {
715 using namespace ::android::base;
716 std::string heapMask =
717 GetProperty("ro.com.android.media.swcodec.ion.heapmask", "undefined");
718 std::string flags =
719 GetProperty("ro.com.android.media.swcodec.ion.flags", "undefined");
720 std::string align =
721 GetProperty("ro.com.android.media.swcodec.ion.align", "undefined");
722 if (heapMask != "undefined" ||
723 flags != "undefined" ||
724 align != "undefined") {
725 LOG(INFO)
726 << "Some system properties for mediaswcodec ION usage are set: "
727 << "heapmask = " << heapMask << ", "
728 << "flags = " << flags << ", "
729 << "align = " << align << ". "
730 << "Preferred Codec2 store is defaulted to \"software\".";
731 return true;
732 }
733 return false;
734 }
735
736 } // unnamed namespace
737
getDeclaredHidlSwcodec(const std::shared_ptr<C2ComponentStore> & store)738 static android::sp<c2_hidl_V1_0::IComponentStore> getDeclaredHidlSwcodec(
739 const std::shared_ptr<C2ComponentStore>& store) {
740 using ::android::hidl::manager::V1_2::IServiceManager;
741 using namespace ::android::hardware::media::c2;
742
743 int platformVersion = android_get_device_api_level();
744 // STOPSHIP: Remove code name checking once platform version bumps up to 35.
745 std::string codeName = android::base::GetProperty("ro.build.version.codename", "");
746
747 if (codeName == "VanillaIceCream") {
748 platformVersion = __ANDROID_API_V__;
749 }
750 IServiceManager::Transport transport =
751 android::hardware::defaultServiceManager1_2()->getTransport(
752 V1_2::IComponentStore::descriptor, "software");
753 if (transport == IServiceManager::Transport::HWBINDER) {
754 if (platformVersion < __ANDROID_API_S__) {
755 LOG(ERROR) << "We don't expect V1.2::IComponentStore to be declared on this device";
756 }
757 return ::android::sp<V1_2::utils::ComponentStore>::make(store);
758 }
759 transport = android::hardware::defaultServiceManager1_2()->getTransport(
760 V1_1::IComponentStore::descriptor, "software");
761 if (transport == IServiceManager::Transport::HWBINDER) {
762 if (platformVersion != __ANDROID_API_R__) {
763 LOG(ERROR) << "We don't expect V1.1::IComponentStore to be declared on this device";
764 }
765 return ::android::sp<V1_1::utils::ComponentStore>::make(store);
766 }
767 transport = android::hardware::defaultServiceManager1_2()->getTransport(
768 V1_0::IComponentStore::descriptor, "software");
769 if (transport == IServiceManager::Transport::HWBINDER) {
770 if (platformVersion != __ANDROID_API_Q__) {
771 LOG(ERROR) << "We don't expect V1.0::IComponentStore to be declared on this device";
772 }
773 return ::android::sp<V1_0::utils::ComponentStore>::make(store);
774 }
775 return nullptr;
776 }
777
RegisterCodecServices()778 extern "C" void RegisterCodecServices() {
779 const bool aidlSelected = c2_aidl::utils::IsSelected();
780 constexpr int kThreadCount = 64;
781 ABinderProcess_setThreadPoolMaxThreadCount(kThreadCount);
782 ABinderProcess_startThreadPool();
783 ::android::hardware::configureRpcThreadpool(kThreadCount, false);
784
785 LOG(INFO) << "Creating software Codec2 service...";
786 std::shared_ptr<C2ComponentStore> store =
787 android::GetCodec2PlatformComponentStore();
788 if (!store) {
789 LOG(ERROR) << "Failed to create Codec2 service.";
790 return;
791 }
792
793 using namespace ::android::hardware::media::c2;
794
795 if (!ionPropertiesDefined()) {
796 using IComponentStore =
797 ::android::hardware::media::c2::V1_0::IComponentStore;
798 std::string const preferredStoreName = "default";
799 if (aidlSelected) {
800 std::shared_ptr<c2_aidl::IComponentStore> preferredStore;
801 if (__builtin_available(android __ANDROID_API_S__, *)) {
802 std::string instanceName = ::android::base::StringPrintf(
803 "%s/%s", c2_aidl::IComponentStore::descriptor, preferredStoreName.c_str());
804 if (AServiceManager_isDeclared(instanceName.c_str())) {
805 preferredStore = c2_aidl::IComponentStore::fromBinder(::ndk::SpAIBinder(
806 AServiceManager_waitForService(instanceName.c_str())));
807 }
808 }
809 if (preferredStore) {
810 ::android::SetPreferredCodec2ComponentStore(
811 std::make_shared<H2C2ComponentStore>(preferredStore));
812 LOG(INFO) <<
813 "Preferred Codec2 AIDL store is set to \"" <<
814 preferredStoreName << "\".";
815 } else {
816 LOG(INFO) <<
817 "Preferred Codec2 AIDL store is defaulted to \"software\".";
818 }
819 } else {
820 sp<IComponentStore> preferredStore =
821 IComponentStore::getService(preferredStoreName.c_str());
822 if (preferredStore) {
823 ::android::SetPreferredCodec2ComponentStore(
824 std::make_shared<H2C2ComponentStore>(preferredStore));
825 LOG(INFO) <<
826 "Preferred Codec2 HIDL store is set to \"" <<
827 preferredStoreName << "\".";
828 } else {
829 LOG(INFO) <<
830 "Preferred Codec2 HIDL store is defaulted to \"software\".";
831 }
832 }
833 }
834
835 bool registered = false;
836 const std::string aidlServiceName =
837 std::string(c2_aidl::IComponentStore::descriptor) + "/software";
838 if (__builtin_available(android __ANDROID_API_S__, *)) {
839 if (AServiceManager_isDeclared(aidlServiceName.c_str())) {
840 std::shared_ptr<c2_aidl::IComponentStore> aidlStore;
841 if (aidlSelected) {
842 aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(store);
843 } else {
844 aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(
845 std::make_shared<H2C2ComponentStore>(nullptr));
846 }
847 binder_exception_t ex = AServiceManager_addService(
848 aidlStore->asBinder().get(), aidlServiceName.c_str());
849 if (ex == EX_NONE) {
850 registered = true;
851 } else {
852 LOG(WARNING) << "Cannot register software Codec2 AIDL service. Exception: " << ex;
853 }
854 }
855 }
856
857 android::sp<V1_0::IComponentStore> hidlStore = getDeclaredHidlSwcodec(store);
858 // If the software component store isn't declared in the manifest, we don't
859 // need to create the service and register it.
860 if (hidlStore) {
861 if (registered && aidlSelected) {
862 LOG(INFO) << "Both HIDL and AIDL software codecs are declared in the vintf "
863 << "manifest, but AIDL was selected. "
864 << "Creating a null HIDL service so it's not accidentally "
865 << "used. The AIDL software codec is already registered.";
866 hidlStore = ::android::sp<V1_2::utils::ComponentStore>::make(
867 std::make_shared<H2C2ComponentStore>(nullptr));
868 }
869 if (hidlStore->registerAsService("software") == android::OK) {
870 registered = true;
871 } else {
872 LOG(ERROR) << "Cannot register software Codec2 " << hidlStore->descriptor
873 << " service.";
874 }
875 } else {
876 LOG(INFO) << "The HIDL software Codec2 service is deprecated"
877 " so it is not being registered with hwservicemanager.";
878 }
879
880 if (registered) {
881 LOG(INFO) << "Software Codec2 service created and registered.";
882 }
883
884 ABinderProcess_joinThreadPool();
885 ::android::hardware::joinRpcThreadpool();
886 }
887
888