xref: /aosp_15_r20/frameworks/av/media/codec2/sfplugin/ReflectedParamUpdater.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ReflectedParamUpdater"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <iostream>
22*ec779b8eSAndroid Build Coastguard Worker #include <set>
23*ec779b8eSAndroid Build Coastguard Worker #include <sstream>
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker #include <C2Debug.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <C2ParamInternal.h>
27*ec779b8eSAndroid Build Coastguard Worker 
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker #include "ReflectedParamUpdater.h"
34*ec779b8eSAndroid Build Coastguard Worker 
35*ec779b8eSAndroid Build Coastguard Worker namespace android {
36*ec779b8eSAndroid Build Coastguard Worker 
debugString(size_t indent_) const37*ec779b8eSAndroid Build Coastguard Worker std::string ReflectedParamUpdater::Dict::debugString(size_t indent_) const {
38*ec779b8eSAndroid Build Coastguard Worker     std::string indent(indent_, ' ');
39*ec779b8eSAndroid Build Coastguard Worker     std::stringstream s;
40*ec779b8eSAndroid Build Coastguard Worker     s << "Dict {" << std::endl;
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker     for (const auto &it : *this) {
43*ec779b8eSAndroid Build Coastguard Worker         s << indent << "  ";
44*ec779b8eSAndroid Build Coastguard Worker 
45*ec779b8eSAndroid Build Coastguard Worker         C2Value c2Value;
46*ec779b8eSAndroid Build Coastguard Worker         int32_t int32Value;
47*ec779b8eSAndroid Build Coastguard Worker         uint32_t uint32Value;
48*ec779b8eSAndroid Build Coastguard Worker         int64_t int64Value;
49*ec779b8eSAndroid Build Coastguard Worker         uint64_t uint64Value;
50*ec779b8eSAndroid Build Coastguard Worker         float floatValue;
51*ec779b8eSAndroid Build Coastguard Worker         sp<ABuffer> bufValue;
52*ec779b8eSAndroid Build Coastguard Worker         AString strValue;
53*ec779b8eSAndroid Build Coastguard Worker         if (it.second.find(&c2Value)) {
54*ec779b8eSAndroid Build Coastguard Worker             switch (c2Value.type()) {
55*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::INT32:
56*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get(&int32Value);
57*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::i32 " << it.first << " = " << int32Value;
58*ec779b8eSAndroid Build Coastguard Worker                     break;
59*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::UINT32:
60*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get(&uint32Value);
61*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::u32 " << it.first << " = " << uint32Value;
62*ec779b8eSAndroid Build Coastguard Worker                     break;
63*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::CNTR32:
64*ec779b8eSAndroid Build Coastguard Worker                     // dump counter value as unsigned
65*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get((c2_cntr32_t*)&uint32Value);
66*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::c32 " << it.first << " = " << uint32Value;
67*ec779b8eSAndroid Build Coastguard Worker                     break;
68*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::INT64:
69*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get(&int64Value);
70*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::i64 " << it.first << " = " << int64Value;
71*ec779b8eSAndroid Build Coastguard Worker                     break;
72*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::UINT64:
73*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get(&uint64Value);
74*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::u64 " << it.first << " = " << uint64Value;
75*ec779b8eSAndroid Build Coastguard Worker                     break;
76*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::CNTR64:
77*ec779b8eSAndroid Build Coastguard Worker                     // dump counter value as unsigned
78*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get((c2_cntr64_t*)&uint64Value);
79*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::c64 " << it.first << " = " << uint64Value;
80*ec779b8eSAndroid Build Coastguard Worker                     break;
81*ec779b8eSAndroid Build Coastguard Worker                 case C2Value::FLOAT:
82*ec779b8eSAndroid Build Coastguard Worker                     (void)c2Value.get(&floatValue);
83*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::float " << it.first << " = " << floatValue;
84*ec779b8eSAndroid Build Coastguard Worker                     break;
85*ec779b8eSAndroid Build Coastguard Worker                 default:
86*ec779b8eSAndroid Build Coastguard Worker                     // dump unsupported values for debugging, these should not be used
87*ec779b8eSAndroid Build Coastguard Worker                     s << "c2::unsupported " << it.first;
88*ec779b8eSAndroid Build Coastguard Worker             }
89*ec779b8eSAndroid Build Coastguard Worker         } else if (it.second.find(&int32Value)) {
90*ec779b8eSAndroid Build Coastguard Worker             s << "int32_t " << it.first << " = " << int32Value;
91*ec779b8eSAndroid Build Coastguard Worker         } else if (it.second.find(&int64Value)) {
92*ec779b8eSAndroid Build Coastguard Worker             s << "int64_t " << it.first << " = " << int64Value;
93*ec779b8eSAndroid Build Coastguard Worker         } else if (it.second.find(&strValue)) {
94*ec779b8eSAndroid Build Coastguard Worker             s << "string " << it.first << " = \"" << strValue.c_str() << "\"";
95*ec779b8eSAndroid Build Coastguard Worker         } else if (it.second.find(&bufValue)) {
96*ec779b8eSAndroid Build Coastguard Worker             s << "Buffer " << it.first << " = ";
97*ec779b8eSAndroid Build Coastguard Worker             if (bufValue != nullptr && bufValue->data() != nullptr && bufValue->size() <= 64) {
98*ec779b8eSAndroid Build Coastguard Worker                 s << "{" << std::endl;
99*ec779b8eSAndroid Build Coastguard Worker                 AString tmp;
100*ec779b8eSAndroid Build Coastguard Worker                 hexdump(bufValue->data(), bufValue->size(), indent_ + 4, &tmp);
101*ec779b8eSAndroid Build Coastguard Worker                 s << tmp.c_str() << indent << "  }";
102*ec779b8eSAndroid Build Coastguard Worker             } else {
103*ec779b8eSAndroid Build Coastguard Worker                 s << (void*)bufValue.get();
104*ec779b8eSAndroid Build Coastguard Worker             }
105*ec779b8eSAndroid Build Coastguard Worker         } else {
106*ec779b8eSAndroid Build Coastguard Worker             // dump unsupported values for debugging, this should never happen.
107*ec779b8eSAndroid Build Coastguard Worker             s << "unsupported " << it.first;
108*ec779b8eSAndroid Build Coastguard Worker         }
109*ec779b8eSAndroid Build Coastguard Worker         s << std::endl;
110*ec779b8eSAndroid Build Coastguard Worker     }
111*ec779b8eSAndroid Build Coastguard Worker     s << indent << "}";
112*ec779b8eSAndroid Build Coastguard Worker 
113*ec779b8eSAndroid Build Coastguard Worker     return s.str();
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker 
addParamDesc(const std::shared_ptr<C2ParamReflector> & reflector,const std::vector<std::shared_ptr<C2ParamDescriptor>> & paramDescs)116*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::addParamDesc(
117*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<C2ParamReflector> &reflector,
118*ec779b8eSAndroid Build Coastguard Worker         const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs) {
119*ec779b8eSAndroid Build Coastguard Worker     for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
120*ec779b8eSAndroid Build Coastguard Worker         std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
121*ec779b8eSAndroid Build Coastguard Worker                 desc->index().coreIndex());
122*ec779b8eSAndroid Build Coastguard Worker         if (structDesc == nullptr) {
123*ec779b8eSAndroid Build Coastguard Worker             ALOGD("Could not describe %s", desc->name().c_str());
124*ec779b8eSAndroid Build Coastguard Worker             continue;
125*ec779b8eSAndroid Build Coastguard Worker         }
126*ec779b8eSAndroid Build Coastguard Worker         addParamDesc(desc, *structDesc, reflector, true /* markVendor */);
127*ec779b8eSAndroid Build Coastguard Worker     }
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker 
addParamStructDesc(std::shared_ptr<C2ParamDescriptor> desc,C2String path,size_t offset,const C2StructDescriptor & structDesc,const std::shared_ptr<C2ParamReflector> & reflector)130*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::addParamStructDesc(
131*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<C2ParamDescriptor> desc,
132*ec779b8eSAndroid Build Coastguard Worker         C2String path,
133*ec779b8eSAndroid Build Coastguard Worker         size_t offset,
134*ec779b8eSAndroid Build Coastguard Worker         const C2StructDescriptor &structDesc,
135*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<C2ParamReflector> &reflector) {
136*ec779b8eSAndroid Build Coastguard Worker     for (auto it = structDesc.begin(); it != structDesc.end(); ++it) {
137*ec779b8eSAndroid Build Coastguard Worker         C2String fieldName = path + "." + it->name();
138*ec779b8eSAndroid Build Coastguard Worker         if (it->type() & C2FieldDescriptor::STRUCT_FLAG) {
139*ec779b8eSAndroid Build Coastguard Worker             if (reflector == nullptr || it->extent() != 1) {
140*ec779b8eSAndroid Build Coastguard Worker                 ALOGD("ignored struct field %s", fieldName.c_str());
141*ec779b8eSAndroid Build Coastguard Worker                 continue;
142*ec779b8eSAndroid Build Coastguard Worker             }
143*ec779b8eSAndroid Build Coastguard Worker             std::unique_ptr<C2StructDescriptor> structDesc_ = reflector->describe(
144*ec779b8eSAndroid Build Coastguard Worker                     C2Param::CoreIndex(it->type()).coreIndex());
145*ec779b8eSAndroid Build Coastguard Worker             if (structDesc_ == nullptr) {
146*ec779b8eSAndroid Build Coastguard Worker                 ALOGD("Could not describe structure of %s", fieldName.c_str());
147*ec779b8eSAndroid Build Coastguard Worker                 continue;
148*ec779b8eSAndroid Build Coastguard Worker             }
149*ec779b8eSAndroid Build Coastguard Worker             addParamStructDesc(desc, fieldName, offset + _C2ParamInspector::GetOffset(*it),
150*ec779b8eSAndroid Build Coastguard Worker                                *structDesc_, reflector);
151*ec779b8eSAndroid Build Coastguard Worker             continue;
152*ec779b8eSAndroid Build Coastguard Worker         }
153*ec779b8eSAndroid Build Coastguard Worker 
154*ec779b8eSAndroid Build Coastguard Worker         // verify extent and type
155*ec779b8eSAndroid Build Coastguard Worker         switch (it->type()) {
156*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::INT32:
157*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::UINT32:
158*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::CNTR32:
159*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::INT64:
160*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::UINT64:
161*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::CNTR64:
162*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::FLOAT:
163*ec779b8eSAndroid Build Coastguard Worker                 if (it->extent() != 1) {
164*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("extent() != 1 for single value type: %s", fieldName.c_str());
165*ec779b8eSAndroid Build Coastguard Worker                     continue;
166*ec779b8eSAndroid Build Coastguard Worker                 }
167*ec779b8eSAndroid Build Coastguard Worker                 break;
168*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::STRING:
169*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::BLOB:
170*ec779b8eSAndroid Build Coastguard Worker                 break;
171*ec779b8eSAndroid Build Coastguard Worker 
172*ec779b8eSAndroid Build Coastguard Worker             default:
173*ec779b8eSAndroid Build Coastguard Worker                 ALOGD("Unrecognized type: %s", fieldName.c_str());
174*ec779b8eSAndroid Build Coastguard Worker                 continue;
175*ec779b8eSAndroid Build Coastguard Worker         }
176*ec779b8eSAndroid Build Coastguard Worker 
177*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s registered", fieldName.c_str());
178*ec779b8eSAndroid Build Coastguard Worker         // TODO: get the proper size by iterating through the fields.
179*ec779b8eSAndroid Build Coastguard Worker         // only insert fields the very first time
180*ec779b8eSAndroid Build Coastguard Worker         mMap.emplace(fieldName, FieldDesc {
181*ec779b8eSAndroid Build Coastguard Worker             desc,
182*ec779b8eSAndroid Build Coastguard Worker             std::make_unique<C2FieldDescriptor>(
183*ec779b8eSAndroid Build Coastguard Worker                     it->type(), it->extent(), it->name(),
184*ec779b8eSAndroid Build Coastguard Worker                     _C2ParamInspector::GetOffset(*it),
185*ec779b8eSAndroid Build Coastguard Worker                     _C2ParamInspector::GetSize(*it)),
186*ec779b8eSAndroid Build Coastguard Worker             offset,
187*ec779b8eSAndroid Build Coastguard Worker         });
188*ec779b8eSAndroid Build Coastguard Worker     }
189*ec779b8eSAndroid Build Coastguard Worker }
190*ec779b8eSAndroid Build Coastguard Worker 
addParamDesc(std::shared_ptr<C2ParamDescriptor> desc,const C2StructDescriptor & structDesc,const std::shared_ptr<C2ParamReflector> & reflector,bool markVendor)191*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::addParamDesc(
192*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<C2ParamDescriptor> desc, const C2StructDescriptor &structDesc,
193*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<C2ParamReflector> &reflector, bool markVendor) {
194*ec779b8eSAndroid Build Coastguard Worker     C2String paramName = desc->name();
195*ec779b8eSAndroid Build Coastguard Worker 
196*ec779b8eSAndroid Build Coastguard Worker     // Do not reflect requested parameters
197*ec779b8eSAndroid Build Coastguard Worker     // TODO: split these once aliases are introduced into '.actual' and '.requested' and alias
198*ec779b8eSAndroid Build Coastguard Worker     // the name to '.actual'.
199*ec779b8eSAndroid Build Coastguard Worker     if (desc->index() & C2Param::CoreIndex::IS_REQUEST_FLAG) {
200*ec779b8eSAndroid Build Coastguard Worker         return;
201*ec779b8eSAndroid Build Coastguard Worker     }
202*ec779b8eSAndroid Build Coastguard Worker 
203*ec779b8eSAndroid Build Coastguard Worker     // prefix vendor parameters
204*ec779b8eSAndroid Build Coastguard Worker     if (desc->index().isVendor() && markVendor) {
205*ec779b8eSAndroid Build Coastguard Worker         paramName = "vendor." + paramName;
206*ec779b8eSAndroid Build Coastguard Worker     }
207*ec779b8eSAndroid Build Coastguard Worker     mParamNames.emplace(desc->index(), paramName);
208*ec779b8eSAndroid Build Coastguard Worker 
209*ec779b8eSAndroid Build Coastguard Worker     // also allow setting whole parameters in a binary fashion via ByteBuffer
210*ec779b8eSAndroid Build Coastguard Worker     // this is opt-in for now
211*ec779b8eSAndroid Build Coastguard Worker     auto it = mWholeParams.find(paramName);
212*ec779b8eSAndroid Build Coastguard Worker     if (it != mWholeParams.end() && it->second.coreIndex() == desc->index().coreIndex()) {
213*ec779b8eSAndroid Build Coastguard Worker         mMap.emplace(paramName, FieldDesc{ desc, nullptr, 0 /* offset */ });
214*ec779b8eSAndroid Build Coastguard Worker         // don't add fields of whole parameters.
215*ec779b8eSAndroid Build Coastguard Worker         return;
216*ec779b8eSAndroid Build Coastguard Worker     }
217*ec779b8eSAndroid Build Coastguard Worker 
218*ec779b8eSAndroid Build Coastguard Worker     addParamStructDesc(desc, paramName, 0 /* offset */, structDesc, reflector);
219*ec779b8eSAndroid Build Coastguard Worker }
220*ec779b8eSAndroid Build Coastguard Worker 
supportWholeParam(std::string name,C2Param::CoreIndex index)221*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::supportWholeParam(std::string name, C2Param::CoreIndex index) {
222*ec779b8eSAndroid Build Coastguard Worker     mWholeParams.emplace(name, index);
223*ec779b8eSAndroid Build Coastguard Worker }
224*ec779b8eSAndroid Build Coastguard Worker 
getParamName(C2Param::Index index) const225*ec779b8eSAndroid Build Coastguard Worker std::string ReflectedParamUpdater::getParamName(C2Param::Index index) const {
226*ec779b8eSAndroid Build Coastguard Worker     auto it = mParamNames.find(index);
227*ec779b8eSAndroid Build Coastguard Worker     if (it != mParamNames.end()) {
228*ec779b8eSAndroid Build Coastguard Worker         return it->second;
229*ec779b8eSAndroid Build Coastguard Worker     }
230*ec779b8eSAndroid Build Coastguard Worker 
231*ec779b8eSAndroid Build Coastguard Worker     std::stringstream ret;
232*ec779b8eSAndroid Build Coastguard Worker     ret << "<unknown " << index << ">";
233*ec779b8eSAndroid Build Coastguard Worker     return ret.str();
234*ec779b8eSAndroid Build Coastguard Worker }
235*ec779b8eSAndroid Build Coastguard Worker 
getParamIndicesFromMessage(const Dict & params,std::vector<C2Param::Index> * vec) const236*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::getParamIndicesFromMessage(
237*ec779b8eSAndroid Build Coastguard Worker         const Dict &params,
238*ec779b8eSAndroid Build Coastguard Worker         std::vector<C2Param::Index> *vec /* nonnull */) const {
239*ec779b8eSAndroid Build Coastguard Worker     CHECK(vec != nullptr);
240*ec779b8eSAndroid Build Coastguard Worker     vec->clear();
241*ec779b8eSAndroid Build Coastguard Worker     std::set<C2Param::Index> indices;
242*ec779b8eSAndroid Build Coastguard Worker     parseMessageAndDoWork(
243*ec779b8eSAndroid Build Coastguard Worker             params,
244*ec779b8eSAndroid Build Coastguard Worker             [&indices](const std::string &, const FieldDesc &desc, const void *, size_t) {
245*ec779b8eSAndroid Build Coastguard Worker                 indices.insert(desc.paramDesc->index());
246*ec779b8eSAndroid Build Coastguard Worker             });
247*ec779b8eSAndroid Build Coastguard Worker     for (const C2Param::Index &index : indices) {
248*ec779b8eSAndroid Build Coastguard Worker         vec->push_back(index);
249*ec779b8eSAndroid Build Coastguard Worker     }
250*ec779b8eSAndroid Build Coastguard Worker }
251*ec779b8eSAndroid Build Coastguard Worker 
getParamIndicesForKeys(const std::vector<std::string> & keys,std::vector<C2Param::Index> * vec) const252*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::getParamIndicesForKeys(
253*ec779b8eSAndroid Build Coastguard Worker         const std::vector<std::string> &keys,
254*ec779b8eSAndroid Build Coastguard Worker         std::vector<C2Param::Index> *vec /* nonnull */) const {
255*ec779b8eSAndroid Build Coastguard Worker     CHECK(vec != nullptr);
256*ec779b8eSAndroid Build Coastguard Worker     vec->clear();
257*ec779b8eSAndroid Build Coastguard Worker     std::set<C2Param::Index> indices;
258*ec779b8eSAndroid Build Coastguard Worker 
259*ec779b8eSAndroid Build Coastguard Worker     std::set<std::string> keyMap(keys.begin(), keys.end());
260*ec779b8eSAndroid Build Coastguard Worker 
261*ec779b8eSAndroid Build Coastguard Worker     ALOGV("in getParamIndicesForKeys with %zu keys and map of %zu entries",
262*ec779b8eSAndroid Build Coastguard Worker             keyMap.size(), mMap.size());
263*ec779b8eSAndroid Build Coastguard Worker     for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
264*ec779b8eSAndroid Build Coastguard Worker         const std::string &name = kv.first;
265*ec779b8eSAndroid Build Coastguard Worker         const FieldDesc &desc = kv.second;
266*ec779b8eSAndroid Build Coastguard Worker         ALOGV("count of %s is %zu", name.c_str(), keyMap.count(name));
267*ec779b8eSAndroid Build Coastguard Worker         if (keyMap.count(name) > 0) {
268*ec779b8eSAndroid Build Coastguard Worker             indices.insert(desc.paramDesc->index());
269*ec779b8eSAndroid Build Coastguard Worker         }
270*ec779b8eSAndroid Build Coastguard Worker     }
271*ec779b8eSAndroid Build Coastguard Worker 
272*ec779b8eSAndroid Build Coastguard Worker     for (const C2Param::Index &index : indices) {
273*ec779b8eSAndroid Build Coastguard Worker         vec->push_back(index);
274*ec779b8eSAndroid Build Coastguard Worker     }
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker 
getKeysForParamIndex(const C2Param::Index & index,std::vector<std::string> * keys) const277*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::getKeysForParamIndex(
278*ec779b8eSAndroid Build Coastguard Worker         const C2Param::Index &index,
279*ec779b8eSAndroid Build Coastguard Worker         std::vector<std::string> *keys /* nonnull */) const {
280*ec779b8eSAndroid Build Coastguard Worker     CHECK(keys != nullptr);
281*ec779b8eSAndroid Build Coastguard Worker     keys->clear();
282*ec779b8eSAndroid Build Coastguard Worker     for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
283*ec779b8eSAndroid Build Coastguard Worker         const std::string &name = kv.first;
284*ec779b8eSAndroid Build Coastguard Worker         const FieldDesc &desc = kv.second;
285*ec779b8eSAndroid Build Coastguard Worker         if (desc.paramDesc->index() == index) {
286*ec779b8eSAndroid Build Coastguard Worker             keys->push_back(name);
287*ec779b8eSAndroid Build Coastguard Worker         }
288*ec779b8eSAndroid Build Coastguard Worker     }
289*ec779b8eSAndroid Build Coastguard Worker }
290*ec779b8eSAndroid Build Coastguard Worker 
getTypeForKey(const std::string & key) const291*ec779b8eSAndroid Build Coastguard Worker C2FieldDescriptor::type_t ReflectedParamUpdater::getTypeForKey(
292*ec779b8eSAndroid Build Coastguard Worker         const std::string &key) const {
293*ec779b8eSAndroid Build Coastguard Worker     auto it = mMap.find(key);
294*ec779b8eSAndroid Build Coastguard Worker     if (it == mMap.end()) {
295*ec779b8eSAndroid Build Coastguard Worker         return C2FieldDescriptor::type_t(~0);
296*ec779b8eSAndroid Build Coastguard Worker     }
297*ec779b8eSAndroid Build Coastguard Worker 
298*ec779b8eSAndroid Build Coastguard Worker     if (it->second.fieldDesc) {
299*ec779b8eSAndroid Build Coastguard Worker         return it->second.fieldDesc->type();
300*ec779b8eSAndroid Build Coastguard Worker     }
301*ec779b8eSAndroid Build Coastguard Worker     // whole param is exposed as a blob
302*ec779b8eSAndroid Build Coastguard Worker     return C2FieldDescriptor::BLOB;
303*ec779b8eSAndroid Build Coastguard Worker }
304*ec779b8eSAndroid Build Coastguard Worker 
updateParamsFromMessage(const Dict & params,std::vector<std::unique_ptr<C2Param>> * vec) const305*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::updateParamsFromMessage(
306*ec779b8eSAndroid Build Coastguard Worker         const Dict &params,
307*ec779b8eSAndroid Build Coastguard Worker         std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const {
308*ec779b8eSAndroid Build Coastguard Worker     CHECK(vec != nullptr);
309*ec779b8eSAndroid Build Coastguard Worker 
310*ec779b8eSAndroid Build Coastguard Worker     std::map<C2Param::Index, std::unique_ptr<C2Param>*> paramsMap;
311*ec779b8eSAndroid Build Coastguard Worker     for (std::unique_ptr<C2Param> &param : *vec) {
312*ec779b8eSAndroid Build Coastguard Worker         if (param && *param) {
313*ec779b8eSAndroid Build Coastguard Worker             paramsMap[param->index()] = &param;
314*ec779b8eSAndroid Build Coastguard Worker         }
315*ec779b8eSAndroid Build Coastguard Worker     }
316*ec779b8eSAndroid Build Coastguard Worker 
317*ec779b8eSAndroid Build Coastguard Worker     parseMessageAndDoWork(
318*ec779b8eSAndroid Build Coastguard Worker             params,
319*ec779b8eSAndroid Build Coastguard Worker             [&paramsMap](const std::string &name, const FieldDesc &desc, const void *ptr, size_t size) {
320*ec779b8eSAndroid Build Coastguard Worker                 std::unique_ptr<C2Param> *param = nullptr;
321*ec779b8eSAndroid Build Coastguard Worker                 auto paramIt = paramsMap.find(desc.paramDesc->index());
322*ec779b8eSAndroid Build Coastguard Worker                 if (paramIt == paramsMap.end()) {
323*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("%s found, but param #%d isn't present to update",
324*ec779b8eSAndroid Build Coastguard Worker                             name.c_str(), (int32_t)desc.paramDesc->index());
325*ec779b8eSAndroid Build Coastguard Worker                     return;
326*ec779b8eSAndroid Build Coastguard Worker                 }
327*ec779b8eSAndroid Build Coastguard Worker                 param = paramIt->second;
328*ec779b8eSAndroid Build Coastguard Worker 
329*ec779b8eSAndroid Build Coastguard Worker                 struct _C2Param : public C2Param {
330*ec779b8eSAndroid Build Coastguard Worker                     using C2Param::C2Param;
331*ec779b8eSAndroid Build Coastguard Worker                     _C2Param(uint32_t size, uint32_t index) : C2Param(size, index) { }
332*ec779b8eSAndroid Build Coastguard Worker                 };
333*ec779b8eSAndroid Build Coastguard Worker 
334*ec779b8eSAndroid Build Coastguard Worker                 // we will handle whole param updates as part of a flexible param update using
335*ec779b8eSAndroid Build Coastguard Worker                 // a zero offset.
336*ec779b8eSAndroid Build Coastguard Worker                 size_t offset = 0;
337*ec779b8eSAndroid Build Coastguard Worker                 size_t minOffset = 0;
338*ec779b8eSAndroid Build Coastguard Worker 
339*ec779b8eSAndroid Build Coastguard Worker                 // if this descriptor has a field, use the offset and size and ensure that offset
340*ec779b8eSAndroid Build Coastguard Worker                 // is not part of the header
341*ec779b8eSAndroid Build Coastguard Worker                 if (desc.fieldDesc) {
342*ec779b8eSAndroid Build Coastguard Worker                     minOffset = sizeof(C2Param);
343*ec779b8eSAndroid Build Coastguard Worker                     offset = sizeof(C2Param) + desc.offset
344*ec779b8eSAndroid Build Coastguard Worker                             + _C2ParamInspector::GetOffset(*desc.fieldDesc);
345*ec779b8eSAndroid Build Coastguard Worker                 }
346*ec779b8eSAndroid Build Coastguard Worker 
347*ec779b8eSAndroid Build Coastguard Worker                 // reallocate or trim flexible param (or whole param) as necessary
348*ec779b8eSAndroid Build Coastguard Worker                 if (!desc.fieldDesc /* whole param */ || desc.fieldDesc->extent() == 0) {
349*ec779b8eSAndroid Build Coastguard Worker                     // reallocate param if more space is needed
350*ec779b8eSAndroid Build Coastguard Worker                     if (param->get()->size() < offset + size) {
351*ec779b8eSAndroid Build Coastguard Worker                         if (size > INT32_MAX - offset || offset < minOffset) {
352*ec779b8eSAndroid Build Coastguard Worker                             // size too long or offset too early - abandon
353*ec779b8eSAndroid Build Coastguard Worker                             return;
354*ec779b8eSAndroid Build Coastguard Worker                         }
355*ec779b8eSAndroid Build Coastguard Worker                         C2Param *newParam = (C2Param *)::operator new(offset + size);
356*ec779b8eSAndroid Build Coastguard Worker                         new (newParam) _C2Param(offset + size, param->get()->index());
357*ec779b8eSAndroid Build Coastguard Worker                         if (offset > sizeof(C2Param)) {
358*ec779b8eSAndroid Build Coastguard Worker                             memcpy(newParam + 1, param->get() + 1, offset - sizeof(C2Param));
359*ec779b8eSAndroid Build Coastguard Worker                         }
360*ec779b8eSAndroid Build Coastguard Worker                         param->reset(newParam);
361*ec779b8eSAndroid Build Coastguard Worker                     } else if (param->get()->size() > offset + size) {
362*ec779b8eSAndroid Build Coastguard Worker                         // trim parameter size
363*ec779b8eSAndroid Build Coastguard Worker                         _C2ParamInspector::TrimParam(param->get(), offset + size);
364*ec779b8eSAndroid Build Coastguard Worker                     }
365*ec779b8eSAndroid Build Coastguard Worker                 } else if (desc.fieldDesc->type() == C2FieldDescriptor::BLOB) {
366*ec779b8eSAndroid Build Coastguard Worker                     // zero fill blobs if updating with smaller blob
367*ec779b8eSAndroid Build Coastguard Worker                     if (desc.fieldDesc->extent() > size) {
368*ec779b8eSAndroid Build Coastguard Worker                         memset((uint8_t *)(param->get()) + offset + size, 0,
369*ec779b8eSAndroid Build Coastguard Worker                                desc.fieldDesc->extent() - size);
370*ec779b8eSAndroid Build Coastguard Worker                     }
371*ec779b8eSAndroid Build Coastguard Worker                 }
372*ec779b8eSAndroid Build Coastguard Worker 
373*ec779b8eSAndroid Build Coastguard Worker                 memcpy((uint8_t *)(param->get()) + offset, ptr, size);
374*ec779b8eSAndroid Build Coastguard Worker             });
375*ec779b8eSAndroid Build Coastguard Worker }
376*ec779b8eSAndroid Build Coastguard Worker 
parseMessageAndDoWork(const Dict & params,std::function<void (const std::string &,const FieldDesc &,const void *,size_t)> work) const377*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::parseMessageAndDoWork(
378*ec779b8eSAndroid Build Coastguard Worker         const Dict &params,
379*ec779b8eSAndroid Build Coastguard Worker         std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const {
380*ec779b8eSAndroid Build Coastguard Worker     for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
381*ec779b8eSAndroid Build Coastguard Worker         const std::string &name = kv.first;
382*ec779b8eSAndroid Build Coastguard Worker         const FieldDesc &desc = kv.second;
383*ec779b8eSAndroid Build Coastguard Worker         auto param = params.find(name);
384*ec779b8eSAndroid Build Coastguard Worker         if (param == params.end()) {
385*ec779b8eSAndroid Build Coastguard Worker             continue;
386*ec779b8eSAndroid Build Coastguard Worker         }
387*ec779b8eSAndroid Build Coastguard Worker 
388*ec779b8eSAndroid Build Coastguard Worker         // handle whole parameters
389*ec779b8eSAndroid Build Coastguard Worker         if (!desc.fieldDesc) {
390*ec779b8eSAndroid Build Coastguard Worker             sp<ABuffer> tmp;
391*ec779b8eSAndroid Build Coastguard Worker             if (param->second.find(&tmp) && tmp != nullptr) {
392*ec779b8eSAndroid Build Coastguard Worker                 C2Param *tmpAsParam = C2Param::From(tmp->data(), tmp->size());
393*ec779b8eSAndroid Build Coastguard Worker                 if (tmpAsParam && tmpAsParam->type().type() == desc.paramDesc->index().type()) {
394*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, tmp->data(), tmp->size());
395*ec779b8eSAndroid Build Coastguard Worker                 } else {
396*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("Param blob does not match param for '%s' (%p, %x vs %x)",
397*ec779b8eSAndroid Build Coastguard Worker                             name.c_str(), tmpAsParam, tmpAsParam ? tmpAsParam->type().type() : 0xDEADu,
398*ec779b8eSAndroid Build Coastguard Worker                             desc.paramDesc->index().type());
399*ec779b8eSAndroid Build Coastguard Worker                 }
400*ec779b8eSAndroid Build Coastguard Worker             }
401*ec779b8eSAndroid Build Coastguard Worker             continue;
402*ec779b8eSAndroid Build Coastguard Worker         }
403*ec779b8eSAndroid Build Coastguard Worker 
404*ec779b8eSAndroid Build Coastguard Worker         int32_t int32Value;
405*ec779b8eSAndroid Build Coastguard Worker         int64_t int64Value;
406*ec779b8eSAndroid Build Coastguard Worker         C2Value c2Value;
407*ec779b8eSAndroid Build Coastguard Worker 
408*ec779b8eSAndroid Build Coastguard Worker         C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
409*ec779b8eSAndroid Build Coastguard Worker         size_t fieldExtent = desc.fieldDesc->extent();
410*ec779b8eSAndroid Build Coastguard Worker         switch (fieldType) {
411*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::INT32:
412*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get(&int32Value))
413*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int32Value)) {
414*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int32Value, sizeof(int32Value));
415*ec779b8eSAndroid Build Coastguard Worker                 }
416*ec779b8eSAndroid Build Coastguard Worker                 break;
417*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::UINT32:
418*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get((uint32_t*)&int32Value))
419*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int32Value)) {
420*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int32Value, sizeof(int32Value));
421*ec779b8eSAndroid Build Coastguard Worker                 }
422*ec779b8eSAndroid Build Coastguard Worker                 break;
423*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::CNTR32:
424*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get((c2_cntr32_t*)&int32Value))
425*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int32Value)) {
426*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int32Value, sizeof(int32Value));
427*ec779b8eSAndroid Build Coastguard Worker                 }
428*ec779b8eSAndroid Build Coastguard Worker                 break;
429*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::INT64:
430*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get(&int64Value))
431*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int64Value)) {
432*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int64Value, sizeof(int64Value));
433*ec779b8eSAndroid Build Coastguard Worker                 }
434*ec779b8eSAndroid Build Coastguard Worker                 break;
435*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::UINT64:
436*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get((uint64_t*)&int64Value))
437*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int64Value)) {
438*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int64Value, sizeof(int64Value));
439*ec779b8eSAndroid Build Coastguard Worker                 }
440*ec779b8eSAndroid Build Coastguard Worker                 break;
441*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::CNTR64:
442*ec779b8eSAndroid Build Coastguard Worker                 if ((param->second.find(&c2Value) && c2Value.get((c2_cntr64_t*)&int64Value))
443*ec779b8eSAndroid Build Coastguard Worker                         || param->second.find(&int64Value)) {
444*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &int64Value, sizeof(int64Value));
445*ec779b8eSAndroid Build Coastguard Worker                 }
446*ec779b8eSAndroid Build Coastguard Worker                 break;
447*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::FLOAT: {
448*ec779b8eSAndroid Build Coastguard Worker                 float tmp;
449*ec779b8eSAndroid Build Coastguard Worker                 if (param->second.find(&c2Value) && c2Value.get(&tmp)) {
450*ec779b8eSAndroid Build Coastguard Worker                     work(name, desc, &tmp, sizeof(tmp));
451*ec779b8eSAndroid Build Coastguard Worker                 }
452*ec779b8eSAndroid Build Coastguard Worker                 break;
453*ec779b8eSAndroid Build Coastguard Worker             }
454*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::STRING: {
455*ec779b8eSAndroid Build Coastguard Worker                 AString tmp;
456*ec779b8eSAndroid Build Coastguard Worker                 if (!param->second.find(&tmp)) {
457*ec779b8eSAndroid Build Coastguard Worker                     break;
458*ec779b8eSAndroid Build Coastguard Worker                 }
459*ec779b8eSAndroid Build Coastguard Worker                 if (fieldExtent > 0 && tmp.size() >= fieldExtent) {
460*ec779b8eSAndroid Build Coastguard Worker                     AString truncated(tmp, 0, fieldExtent - 1);
461*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("String value too long to fit: original \"%s\" truncated to \"%s\"",
462*ec779b8eSAndroid Build Coastguard Worker                             tmp.c_str(), truncated.c_str());
463*ec779b8eSAndroid Build Coastguard Worker                     tmp = truncated;
464*ec779b8eSAndroid Build Coastguard Worker                 }
465*ec779b8eSAndroid Build Coastguard Worker                 work(name, desc, tmp.c_str(), tmp.size() + 1);
466*ec779b8eSAndroid Build Coastguard Worker                 break;
467*ec779b8eSAndroid Build Coastguard Worker             }
468*ec779b8eSAndroid Build Coastguard Worker 
469*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::BLOB: {
470*ec779b8eSAndroid Build Coastguard Worker                 sp<ABuffer> tmp;
471*ec779b8eSAndroid Build Coastguard Worker                 if (!param->second.find(&tmp) || tmp == nullptr) {
472*ec779b8eSAndroid Build Coastguard Worker                     break;
473*ec779b8eSAndroid Build Coastguard Worker                 }
474*ec779b8eSAndroid Build Coastguard Worker 
475*ec779b8eSAndroid Build Coastguard Worker                 if (fieldExtent > 0 && tmp->size() > fieldExtent) {
476*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("Blob value too long to fit. Truncating.");
477*ec779b8eSAndroid Build Coastguard Worker                     tmp->setRange(tmp->offset(), fieldExtent);
478*ec779b8eSAndroid Build Coastguard Worker                 }
479*ec779b8eSAndroid Build Coastguard Worker                 work(name, desc, tmp->data(), tmp->size());
480*ec779b8eSAndroid Build Coastguard Worker                 break;
481*ec779b8eSAndroid Build Coastguard Worker             }
482*ec779b8eSAndroid Build Coastguard Worker 
483*ec779b8eSAndroid Build Coastguard Worker             default:
484*ec779b8eSAndroid Build Coastguard Worker                 ALOGD("Unsupported data type for %s", name.c_str());
485*ec779b8eSAndroid Build Coastguard Worker                 break;
486*ec779b8eSAndroid Build Coastguard Worker         }
487*ec779b8eSAndroid Build Coastguard Worker     }
488*ec779b8eSAndroid Build Coastguard Worker }
489*ec779b8eSAndroid Build Coastguard Worker 
490*ec779b8eSAndroid Build Coastguard Worker ReflectedParamUpdater::Dict
getParams(const std::vector<std::unique_ptr<C2Param>> & params_) const491*ec779b8eSAndroid Build Coastguard Worker ReflectedParamUpdater::getParams(const std::vector<std::unique_ptr<C2Param>> &params_) const {
492*ec779b8eSAndroid Build Coastguard Worker     std::vector<C2Param*> params;
493*ec779b8eSAndroid Build Coastguard Worker     params.resize(params_.size());
494*ec779b8eSAndroid Build Coastguard Worker     std::transform(params_.begin(), params_.end(), params.begin(),
495*ec779b8eSAndroid Build Coastguard Worker                    [](const std::unique_ptr<C2Param>& p) -> C2Param* { return p.get(); });
496*ec779b8eSAndroid Build Coastguard Worker     return getParams(params);
497*ec779b8eSAndroid Build Coastguard Worker }
498*ec779b8eSAndroid Build Coastguard Worker 
499*ec779b8eSAndroid Build Coastguard Worker ReflectedParamUpdater::Dict
getParams(const std::vector<C2Param * > & params) const500*ec779b8eSAndroid Build Coastguard Worker ReflectedParamUpdater::getParams(const std::vector<C2Param*> &params) const {
501*ec779b8eSAndroid Build Coastguard Worker     Dict ret;
502*ec779b8eSAndroid Build Coastguard Worker 
503*ec779b8eSAndroid Build Coastguard Worker     // convert vector to map
504*ec779b8eSAndroid Build Coastguard Worker     std::map<C2Param::Index, C2Param *> paramsMap;
505*ec779b8eSAndroid Build Coastguard Worker     for (C2Param *param : params) {
506*ec779b8eSAndroid Build Coastguard Worker         if (param != nullptr && *param) {
507*ec779b8eSAndroid Build Coastguard Worker             paramsMap[param->index()] = param;
508*ec779b8eSAndroid Build Coastguard Worker         }
509*ec779b8eSAndroid Build Coastguard Worker     }
510*ec779b8eSAndroid Build Coastguard Worker 
511*ec779b8eSAndroid Build Coastguard Worker     for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
512*ec779b8eSAndroid Build Coastguard Worker         const std::string &name = kv.first;
513*ec779b8eSAndroid Build Coastguard Worker         const FieldDesc &desc = kv.second;
514*ec779b8eSAndroid Build Coastguard Worker         if (paramsMap.count(desc.paramDesc->index()) == 0) {
515*ec779b8eSAndroid Build Coastguard Worker             continue;
516*ec779b8eSAndroid Build Coastguard Worker         }
517*ec779b8eSAndroid Build Coastguard Worker         C2Param *param = paramsMap[desc.paramDesc->index()];
518*ec779b8eSAndroid Build Coastguard Worker         Value value;
519*ec779b8eSAndroid Build Coastguard Worker 
520*ec779b8eSAndroid Build Coastguard Worker         // handle whole params first
521*ec779b8eSAndroid Build Coastguard Worker         if (!desc.fieldDesc) {
522*ec779b8eSAndroid Build Coastguard Worker             sp<ABuffer> buf = ABuffer::CreateAsCopy(param, param->size());
523*ec779b8eSAndroid Build Coastguard Worker             value.set(buf);
524*ec779b8eSAndroid Build Coastguard Worker             ret.emplace(name, value);
525*ec779b8eSAndroid Build Coastguard Worker             continue;
526*ec779b8eSAndroid Build Coastguard Worker         }
527*ec779b8eSAndroid Build Coastguard Worker 
528*ec779b8eSAndroid Build Coastguard Worker         size_t offset = sizeof(C2Param) + desc.offset
529*ec779b8eSAndroid Build Coastguard Worker                 + _C2ParamInspector::GetOffset(*desc.fieldDesc);
530*ec779b8eSAndroid Build Coastguard Worker         uint8_t *data = (uint8_t *)param + offset;
531*ec779b8eSAndroid Build Coastguard Worker         C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
532*ec779b8eSAndroid Build Coastguard Worker         switch (fieldType) {
533*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::STRING: {
534*ec779b8eSAndroid Build Coastguard Worker                 size_t length = desc.fieldDesc->extent();
535*ec779b8eSAndroid Build Coastguard Worker                 if (length == 0) {
536*ec779b8eSAndroid Build Coastguard Worker                     length = param->size() - offset;
537*ec779b8eSAndroid Build Coastguard Worker                 }
538*ec779b8eSAndroid Build Coastguard Worker 
539*ec779b8eSAndroid Build Coastguard Worker                 if (param->size() < length || param->size() - length < offset) {
540*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("param too small for string: length %zu size %zu offset %zu",
541*ec779b8eSAndroid Build Coastguard Worker                             length, param->size(), offset);
542*ec779b8eSAndroid Build Coastguard Worker                     break;
543*ec779b8eSAndroid Build Coastguard Worker                 }
544*ec779b8eSAndroid Build Coastguard Worker                 value.set(AString((char *)data, strnlen((char *)data, length)));
545*ec779b8eSAndroid Build Coastguard Worker                 break;
546*ec779b8eSAndroid Build Coastguard Worker             }
547*ec779b8eSAndroid Build Coastguard Worker 
548*ec779b8eSAndroid Build Coastguard Worker             case C2FieldDescriptor::BLOB: {
549*ec779b8eSAndroid Build Coastguard Worker                 size_t length = desc.fieldDesc->extent();
550*ec779b8eSAndroid Build Coastguard Worker                 if (length == 0) {
551*ec779b8eSAndroid Build Coastguard Worker                     length = param->size() - offset;
552*ec779b8eSAndroid Build Coastguard Worker                 }
553*ec779b8eSAndroid Build Coastguard Worker 
554*ec779b8eSAndroid Build Coastguard Worker                 if (param->size() < length || param->size() - length < offset) {
555*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("param too small for blob: length %zu size %zu offset %zu",
556*ec779b8eSAndroid Build Coastguard Worker                             length, param->size(), offset);
557*ec779b8eSAndroid Build Coastguard Worker                     break;
558*ec779b8eSAndroid Build Coastguard Worker                 }
559*ec779b8eSAndroid Build Coastguard Worker 
560*ec779b8eSAndroid Build Coastguard Worker                 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, length);
561*ec779b8eSAndroid Build Coastguard Worker                 value.set(buf);
562*ec779b8eSAndroid Build Coastguard Worker                 break;
563*ec779b8eSAndroid Build Coastguard Worker             }
564*ec779b8eSAndroid Build Coastguard Worker 
565*ec779b8eSAndroid Build Coastguard Worker             default: {
566*ec779b8eSAndroid Build Coastguard Worker                 size_t valueSize = C2Value::SizeFor((C2Value::type_t)fieldType);
567*ec779b8eSAndroid Build Coastguard Worker                 if (param->size() < valueSize || param->size() - valueSize < offset) {
568*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("param too small for c2value: size %zu offset %zu",
569*ec779b8eSAndroid Build Coastguard Worker                             param->size(), offset);
570*ec779b8eSAndroid Build Coastguard Worker                     break;
571*ec779b8eSAndroid Build Coastguard Worker                 }
572*ec779b8eSAndroid Build Coastguard Worker 
573*ec779b8eSAndroid Build Coastguard Worker                 C2Value c2Value;
574*ec779b8eSAndroid Build Coastguard Worker                 switch (fieldType) {
575*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::INT32:  c2Value = *((int32_t *)data); break;
576*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::UINT32: c2Value = *((uint32_t *)data); break;
577*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::CNTR32: c2Value = *((c2_cntr32_t *)data); break;
578*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::INT64:  c2Value = *((int64_t *)data); break;
579*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::UINT64: c2Value = *((uint64_t *)data); break;
580*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::CNTR64: c2Value = *((c2_cntr64_t *)data); break;
581*ec779b8eSAndroid Build Coastguard Worker                     case C2FieldDescriptor::FLOAT:  c2Value = *((float *)data); break;
582*ec779b8eSAndroid Build Coastguard Worker                     default:
583*ec779b8eSAndroid Build Coastguard Worker                         ALOGD("Unsupported data type for %s", name.c_str());
584*ec779b8eSAndroid Build Coastguard Worker                         continue;
585*ec779b8eSAndroid Build Coastguard Worker                 }
586*ec779b8eSAndroid Build Coastguard Worker                 value.set(c2Value);
587*ec779b8eSAndroid Build Coastguard Worker             }
588*ec779b8eSAndroid Build Coastguard Worker         }
589*ec779b8eSAndroid Build Coastguard Worker         ret.emplace(name, value);
590*ec779b8eSAndroid Build Coastguard Worker     }
591*ec779b8eSAndroid Build Coastguard Worker     return ret;
592*ec779b8eSAndroid Build Coastguard Worker }
593*ec779b8eSAndroid Build Coastguard Worker 
clear()594*ec779b8eSAndroid Build Coastguard Worker void ReflectedParamUpdater::clear() {
595*ec779b8eSAndroid Build Coastguard Worker     mMap.clear();
596*ec779b8eSAndroid Build Coastguard Worker }
597*ec779b8eSAndroid Build Coastguard Worker 
598*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
599