• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params,
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 &params,
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 &params,
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, &params, 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 *> &paramPointers,
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(&paramPointers, 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(&paramPointers, 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