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 "Codec2-Configurable-Aidl"
19 #include <android-base/logging.h>
20
21 #include <android/binder_auto_utils.h>
22 #include <android-base/hex.h>
23 #include <codec2/aidl/Configurable.h>
24 #include <codec2/aidl/ParamTypes.h>
25
26 #include <C2ParamInternal.h>
27
28 namespace aidl {
29 namespace android {
30 namespace hardware {
31 namespace media {
32 namespace c2 {
33 namespace utils {
34
35 using ::ndk::ScopedAStatus;
36
CachedConfigurable(std::unique_ptr<ConfigurableC2Intf> && intf)37 CachedConfigurable::CachedConfigurable(
38 std::unique_ptr<ConfigurableC2Intf>&& intf)
39 : mIntf{std::move(intf)} {
40 }
41
init(const std::shared_ptr<ParameterCache> & cache)42 c2_status_t CachedConfigurable::init(
43 const std::shared_ptr<ParameterCache>& cache) {
44 // Retrieve supported parameters from store
45 c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
46 c2_status_t validate = cache->validate(mSupportedParams);
47 return init == C2_OK ? C2_OK : validate;
48 }
49
50 // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
51
getId(int32_t * id)52 ScopedAStatus CachedConfigurable::getId(int32_t* id) {
53 *id = mIntf->getId();
54 return ScopedAStatus::ok();
55 }
56
getName(std::string * name)57 ScopedAStatus CachedConfigurable::getName(std::string* name) {
58 *name = mIntf->getName();
59 return ScopedAStatus::ok();
60 }
61
query(const std::vector<int32_t> & indices,bool mayBlock,QueryResult * queryResult)62 ScopedAStatus CachedConfigurable::query(
63 const std::vector<int32_t>& indices,
64 bool mayBlock,
65 QueryResult *queryResult) {
66 typedef C2Param::Index Index;
67 std::vector<Index> c2heapParamIndices(
68 (Index*)indices.data(),
69 (Index*)indices.data() + indices.size());
70 std::vector<std::unique_ptr<C2Param>> c2heapParams;
71 c2_status_t c2res = mIntf->query(
72 c2heapParamIndices,
73 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
74 &c2heapParams);
75
76 if (!CreateParamsBlob(&(queryResult->params), c2heapParams)) {
77 LOG(WARNING) << "query -- invalid output params.";
78 }
79 queryResult->status.status = c2res;
80 return ScopedAStatus::ok();
81 }
82
config(const Params & params,bool mayBlock,ConfigResult * result)83 ScopedAStatus CachedConfigurable::config(
84 const Params& params,
85 bool mayBlock,
86 ConfigResult* result) {
87 // inParams is not writable, so create a copy as config modifies the parameters
88 std::vector<C2Param*> c2params;
89 if (!ParseParamsBlob(&c2params, params)) {
90 LOG(WARNING) << "config -- invalid input params.";
91 return ScopedAStatus::fromServiceSpecificError(C2_CORRUPTED);
92 }
93 // TODO: check if blob was invalid
94 std::vector<std::unique_ptr<C2SettingResult>> c2failures;
95 c2_status_t c2res = mIntf->config(
96 c2params,
97 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
98 &c2failures);
99 result->failures.resize(c2failures.size());
100 {
101 size_t ix = 0;
102 for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
103 if (c2result) {
104 if (ToAidl(&result->failures[ix], *c2result)) {
105 ++ix;
106 } else {
107 LOG(DEBUG) << "config -- invalid setting results.";
108 break;
109 }
110 }
111 }
112 result->failures.resize(ix);
113 }
114 if (!CreateParamsBlob(&result->params, c2params)) {
115 LOG(DEBUG) << "config -- invalid output params.";
116 }
117 result->status.status = c2res;
118 return ScopedAStatus::ok();
119 }
120
querySupportedParams(int32_t start,int32_t count,std::vector<ParamDescriptor> * paramDesc)121 ScopedAStatus CachedConfigurable::querySupportedParams(
122 int32_t start,
123 int32_t count,
124 std::vector<ParamDescriptor>* paramDesc) {
125 C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range(
126 start, count);
127 paramDesc->resize(request.size());
128 int32_t res = Status::OK;
129 size_t dstIx = 0;
130 for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
131 if (mSupportedParams[srcIx]) {
132 if (ToAidl(&(*paramDesc)[dstIx], *mSupportedParams[srcIx])) {
133 ++dstIx;
134 } else {
135 res = Status::CORRUPTED;
136 LOG(WARNING) << "querySupportedParams -- invalid output params.";
137 break;
138 }
139 }
140 }
141 paramDesc->resize(dstIx);
142 if (res == Status::OK) {
143 return ScopedAStatus::ok();
144 }
145 return ScopedAStatus::fromServiceSpecificError(res);
146 }
147
querySupportedValues(const std::vector<FieldSupportedValuesQuery> & fields,bool mayBlock,QuerySupportedValuesResult * queryValues)148 ScopedAStatus CachedConfigurable::querySupportedValues(
149 const std::vector<FieldSupportedValuesQuery>& fields,
150 bool mayBlock,
151 QuerySupportedValuesResult *queryValues) {
152 std::vector<C2FieldSupportedValuesQuery> c2fields;
153 {
154 // C2FieldSupportedValuesQuery objects are restricted in that some
155 // members are const.
156 // C2ParamField - required for its constructor - has no constructors
157 // from fields. Use C2ParamInspector.
158 for (const FieldSupportedValuesQuery &query : fields) {
159 c2fields.emplace_back(_C2ParamInspector::CreateParamField(
160 (uint32_t)query.field.index,
161 query.field.fieldId.offset,
162 query.field.fieldId.sizeBytes),
163 query.type == FieldSupportedValuesQuery::Type::POSSIBLE ?
164 C2FieldSupportedValuesQuery::POSSIBLE :
165 C2FieldSupportedValuesQuery::CURRENT);
166 }
167 }
168 c2_status_t c2res = mIntf->querySupportedValues(
169 c2fields,
170 mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK);
171 queryValues->values.resize(fields.size());
172 size_t dstIx = 0;
173 for (const C2FieldSupportedValuesQuery &res : c2fields) {
174 if (ToAidl(&(queryValues->values[dstIx]), res)) {
175 ++dstIx;
176 } else {
177 queryValues->values.resize(dstIx);
178 c2res = C2_CORRUPTED;
179 LOG(WARNING) << "querySupportedValues -- invalid output params.";
180 break;
181 }
182 }
183 queryValues->status.status = c2res;
184 return ScopedAStatus::ok();
185 }
186
187 } // namespace utils
188 } // namespace c2
189 } // namespace media
190 } // namespace hardware
191 } // namespace android
192 } // namespace aidl
193
194