1 /*
2  * Copyright (C) 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 "Codec2-Configurable"
19 #include <log/log.h>
20 
21 #include <codec2/hidl/1.0/Configurable.h>
22 #include <codec2/hidl/1.0/ComponentStore.h>
23 #include <codec2/hidl/1.0/types.h>
24 #include <C2ParamInternal.h>
25 
26 namespace hardware {
27 namespace google {
28 namespace media {
29 namespace c2 {
30 namespace V1_0 {
31 namespace utils {
32 
33 using namespace ::android;
34 
CachedConfigurable(std::unique_ptr<ConfigurableC2Intf> && intf)35 CachedConfigurable::CachedConfigurable(
36         std::unique_ptr<ConfigurableC2Intf>&& intf) :
37     mIntf(std::move(intf)) {
38 }
39 
init(ComponentStore * store)40 c2_status_t CachedConfigurable::init(ComponentStore* store) {
41     // Retrieve supported parameters from store
42     c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
43     c2_status_t validate = store->validateSupportedParams(mSupportedParams);
44     return init == C2_OK ? C2_OK : validate;
45 }
46 
47 // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
getName(getName_cb _hidl_cb)48 Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) {
49     _hidl_cb(mIntf->getName());
50     return Void();
51 }
52 
query(const hidl_vec<uint32_t> & indices,bool mayBlock,query_cb _hidl_cb)53 Return<void> CachedConfigurable::query(
54         const hidl_vec<uint32_t>& indices,
55         bool mayBlock,
56         query_cb _hidl_cb) {
57     typedef C2Param::Index Index;
58     std::vector<Index> c2heapParamIndices(
59             (Index*)indices.data(),
60             (Index*)indices.data() + indices.size());
61     std::vector<std::unique_ptr<C2Param>> c2heapParams;
62     c2_status_t c2res = mIntf->query(
63             c2heapParamIndices,
64             mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
65             &c2heapParams);
66 
67     hidl_vec<uint8_t> params;
68     createParamsBlob(&params, c2heapParams);
69     _hidl_cb(static_cast<Status>(c2res), params);
70 
71     return Void();
72 }
73 
config(const hidl_vec<uint8_t> & inParams,bool mayBlock,config_cb _hidl_cb)74 Return<void> CachedConfigurable::config(
75         const hidl_vec<uint8_t>& inParams,
76         bool mayBlock,
77         config_cb _hidl_cb) {
78     // inParams is not writable, so create a copy as config modifies the parameters
79     hidl_vec<uint8_t> inParamsCopy = inParams;
80     std::vector<C2Param*> c2params;
81     if (parseParamsBlob(&c2params, inParamsCopy) != C2_OK) {
82         _hidl_cb(Status::CORRUPTED,
83                 hidl_vec<SettingResult>(),
84                 hidl_vec<uint8_t>());
85         return Void();
86     }
87     // TODO: check if blob was invalid
88     std::vector<std::unique_ptr<C2SettingResult>> c2failures;
89     c2_status_t c2res = mIntf->config(
90             c2params,
91             mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
92             &c2failures);
93     hidl_vec<SettingResult> failures(c2failures.size());
94     {
95         size_t ix = 0;
96         for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
97             if (c2result) {
98                 objcpy(&failures[ix++], *c2result);
99             }
100         }
101         failures.resize(ix);
102     }
103     hidl_vec<uint8_t> outParams;
104     createParamsBlob(&outParams, c2params);
105     _hidl_cb((Status)c2res, failures, outParams);
106     return Void();
107 }
108 
querySupportedParams(uint32_t start,uint32_t count,querySupportedParams_cb _hidl_cb)109 Return<void> CachedConfigurable::querySupportedParams(
110         uint32_t start,
111         uint32_t count,
112         querySupportedParams_cb _hidl_cb) {
113     C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range(
114             start, count);
115     hidl_vec<ParamDescriptor> params(request.size());
116     Status res = Status::OK;
117     size_t dstIx = 0;
118     for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
119         if (mSupportedParams[srcIx]) {
120             objcpy(&params[dstIx++], *mSupportedParams[srcIx]);
121         } else {
122             res = Status::BAD_INDEX;
123         }
124     }
125     params.resize(dstIx);
126     _hidl_cb(res, params);
127     return Void();
128 }
129 
querySupportedValues(const hidl_vec<FieldSupportedValuesQuery> & inFields,bool mayBlock,querySupportedValues_cb _hidl_cb)130 Return<void> CachedConfigurable::querySupportedValues(
131         const hidl_vec<FieldSupportedValuesQuery>& inFields,
132         bool mayBlock,
133         querySupportedValues_cb _hidl_cb) {
134     std::vector<C2FieldSupportedValuesQuery> c2fields;
135     {
136         // C2FieldSupportedValuesQuery objects are restricted in that some
137         // members are const.
138         // C2ParamField - required for its constructor - has no constructors
139         // from fields. Use C2ParamInspector.
140         for (const FieldSupportedValuesQuery &query : inFields) {
141             c2fields.emplace_back(_C2ParamInspector::CreateParamField(
142                     query.field.index,
143                     query.field.fieldId.offset,
144                     query.field.fieldId.size),
145                     query.type == FieldSupportedValuesQuery::Type::POSSIBLE ?
146                     C2FieldSupportedValuesQuery::POSSIBLE :
147                     C2FieldSupportedValuesQuery::CURRENT);
148         }
149     }
150     c2_status_t c2res = mIntf->querySupportedValues(
151             c2fields,
152             mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK);
153     hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size());
154     {
155         size_t ix = 0;
156         for (const C2FieldSupportedValuesQuery &result : c2fields) {
157             objcpy(&outFields[ix++], result);
158         }
159     }
160     _hidl_cb((Status)c2res, outFields);
161     return Void();
162 }
163 
164 }  // namespace utils
165 }  // namespace V1_0
166 }  // namespace c2
167 }  // namespace media
168 }  // namespace google
169 }  // namespace hardware
170