xref: /aosp_15_r20/frameworks/av/media/module/foundation/MetaDataBase.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2009 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 "MetaDataBase"
19*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <utils/KeyedVector.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <string.h>
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker #include <mutex>
27*ec779b8eSAndroid Build Coastguard Worker 
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MetaDataBase.h>
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
34*ec779b8eSAndroid Build Coastguard Worker #include <binder/Parcel.h>
35*ec779b8eSAndroid Build Coastguard Worker #endif
36*ec779b8eSAndroid Build Coastguard Worker 
37*ec779b8eSAndroid Build Coastguard Worker namespace android {
38*ec779b8eSAndroid Build Coastguard Worker 
39*ec779b8eSAndroid Build Coastguard Worker struct MetaDataBase::typed_data {
40*ec779b8eSAndroid Build Coastguard Worker     typed_data();
41*ec779b8eSAndroid Build Coastguard Worker     ~typed_data();
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker     typed_data(const MetaDataBase::typed_data &);
44*ec779b8eSAndroid Build Coastguard Worker     typed_data &operator=(const MetaDataBase::typed_data &);
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker     void clear();
47*ec779b8eSAndroid Build Coastguard Worker     void setData(uint32_t type, const void *data, size_t size);
48*ec779b8eSAndroid Build Coastguard Worker     void getData(uint32_t *type, const void **data, size_t *size) const;
49*ec779b8eSAndroid Build Coastguard Worker     // may include hexdump of binary data if verbose=true
50*ec779b8eSAndroid Build Coastguard Worker     String8 asString(bool verbose) const;
51*ec779b8eSAndroid Build Coastguard Worker 
52*ec779b8eSAndroid Build Coastguard Worker private:
53*ec779b8eSAndroid Build Coastguard Worker     uint32_t mType;
54*ec779b8eSAndroid Build Coastguard Worker     size_t mSize;
55*ec779b8eSAndroid Build Coastguard Worker 
56*ec779b8eSAndroid Build Coastguard Worker     union {
57*ec779b8eSAndroid Build Coastguard Worker         void *ext_data;
58*ec779b8eSAndroid Build Coastguard Worker         float reservoir;
59*ec779b8eSAndroid Build Coastguard Worker     } u;
60*ec779b8eSAndroid Build Coastguard Worker 
usesReservoirandroid::MetaDataBase::typed_data61*ec779b8eSAndroid Build Coastguard Worker     bool usesReservoir() const {
62*ec779b8eSAndroid Build Coastguard Worker         return mSize <= sizeof(u.reservoir);
63*ec779b8eSAndroid Build Coastguard Worker     }
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker     void *allocateStorage(size_t size);
66*ec779b8eSAndroid Build Coastguard Worker     void freeStorage();
67*ec779b8eSAndroid Build Coastguard Worker 
storageandroid::MetaDataBase::typed_data68*ec779b8eSAndroid Build Coastguard Worker     void *storage() {
69*ec779b8eSAndroid Build Coastguard Worker         return usesReservoir() ? &u.reservoir : u.ext_data;
70*ec779b8eSAndroid Build Coastguard Worker     }
71*ec779b8eSAndroid Build Coastguard Worker 
storageandroid::MetaDataBase::typed_data72*ec779b8eSAndroid Build Coastguard Worker     const void *storage() const {
73*ec779b8eSAndroid Build Coastguard Worker         return usesReservoir() ? &u.reservoir : u.ext_data;
74*ec779b8eSAndroid Build Coastguard Worker     }
75*ec779b8eSAndroid Build Coastguard Worker };
76*ec779b8eSAndroid Build Coastguard Worker 
77*ec779b8eSAndroid Build Coastguard Worker struct MetaDataBase::Rect {
78*ec779b8eSAndroid Build Coastguard Worker     int32_t mLeft, mTop, mRight, mBottom;
79*ec779b8eSAndroid Build Coastguard Worker };
80*ec779b8eSAndroid Build Coastguard Worker 
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker struct MetaDataBase::MetaDataInternal {
83*ec779b8eSAndroid Build Coastguard Worker     std::mutex mLock;
84*ec779b8eSAndroid Build Coastguard Worker     KeyedVector<uint32_t, MetaDataBase::typed_data> mItems;
85*ec779b8eSAndroid Build Coastguard Worker };
86*ec779b8eSAndroid Build Coastguard Worker 
87*ec779b8eSAndroid Build Coastguard Worker 
MetaDataBase()88*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::MetaDataBase()
89*ec779b8eSAndroid Build Coastguard Worker     : mInternalData(new MetaDataInternal()) {
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker 
MetaDataBase(const MetaDataBase & from)92*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::MetaDataBase(const MetaDataBase &from)
93*ec779b8eSAndroid Build Coastguard Worker     : mInternalData(new MetaDataInternal()) {
94*ec779b8eSAndroid Build Coastguard Worker     mInternalData->mItems = from.mInternalData->mItems;
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker 
operator =(const MetaDataBase & rhs)97*ec779b8eSAndroid Build Coastguard Worker MetaDataBase& MetaDataBase::operator = (const MetaDataBase &rhs) {
98*ec779b8eSAndroid Build Coastguard Worker     this->mInternalData->mItems = rhs.mInternalData->mItems;
99*ec779b8eSAndroid Build Coastguard Worker     return *this;
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker 
~MetaDataBase()102*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::~MetaDataBase() {
103*ec779b8eSAndroid Build Coastguard Worker     clear();
104*ec779b8eSAndroid Build Coastguard Worker     delete mInternalData;
105*ec779b8eSAndroid Build Coastguard Worker }
106*ec779b8eSAndroid Build Coastguard Worker 
clear()107*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::clear() {
108*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
109*ec779b8eSAndroid Build Coastguard Worker     mInternalData->mItems.clear();
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker 
remove(uint32_t key)112*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::remove(uint32_t key) {
113*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
114*ec779b8eSAndroid Build Coastguard Worker     ssize_t i = mInternalData->mItems.indexOfKey(key);
115*ec779b8eSAndroid Build Coastguard Worker 
116*ec779b8eSAndroid Build Coastguard Worker     if (i < 0) {
117*ec779b8eSAndroid Build Coastguard Worker         return false;
118*ec779b8eSAndroid Build Coastguard Worker     }
119*ec779b8eSAndroid Build Coastguard Worker 
120*ec779b8eSAndroid Build Coastguard Worker     mInternalData->mItems.removeItemsAt(i);
121*ec779b8eSAndroid Build Coastguard Worker 
122*ec779b8eSAndroid Build Coastguard Worker     return true;
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker 
setCString(uint32_t key,const char * value)125*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setCString(uint32_t key, const char *value) {
126*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
127*ec779b8eSAndroid Build Coastguard Worker }
128*ec779b8eSAndroid Build Coastguard Worker 
setInt32(uint32_t key,int32_t value)129*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setInt32(uint32_t key, int32_t value) {
130*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_INT32, &value, sizeof(value));
131*ec779b8eSAndroid Build Coastguard Worker }
132*ec779b8eSAndroid Build Coastguard Worker 
setInt64(uint32_t key,int64_t value)133*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setInt64(uint32_t key, int64_t value) {
134*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_INT64, &value, sizeof(value));
135*ec779b8eSAndroid Build Coastguard Worker }
136*ec779b8eSAndroid Build Coastguard Worker 
setFloat(uint32_t key,float value)137*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setFloat(uint32_t key, float value) {
138*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_FLOAT, &value, sizeof(value));
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker 
setPointer(uint32_t key,void * value)141*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setPointer(uint32_t key, void *value) {
142*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_POINTER, &value, sizeof(value));
143*ec779b8eSAndroid Build Coastguard Worker }
144*ec779b8eSAndroid Build Coastguard Worker 
setRect(uint32_t key,int32_t left,int32_t top,int32_t right,int32_t bottom)145*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setRect(
146*ec779b8eSAndroid Build Coastguard Worker         uint32_t key,
147*ec779b8eSAndroid Build Coastguard Worker         int32_t left, int32_t top,
148*ec779b8eSAndroid Build Coastguard Worker         int32_t right, int32_t bottom) {
149*ec779b8eSAndroid Build Coastguard Worker     Rect r;
150*ec779b8eSAndroid Build Coastguard Worker     r.mLeft = left;
151*ec779b8eSAndroid Build Coastguard Worker     r.mTop = top;
152*ec779b8eSAndroid Build Coastguard Worker     r.mRight = right;
153*ec779b8eSAndroid Build Coastguard Worker     r.mBottom = bottom;
154*ec779b8eSAndroid Build Coastguard Worker 
155*ec779b8eSAndroid Build Coastguard Worker     return setData(key, TYPE_RECT, &r, sizeof(r));
156*ec779b8eSAndroid Build Coastguard Worker }
157*ec779b8eSAndroid Build Coastguard Worker 
158*ec779b8eSAndroid Build Coastguard Worker /**
159*ec779b8eSAndroid Build Coastguard Worker  * Note that the returned pointer becomes invalid when additional metadata is set.
160*ec779b8eSAndroid Build Coastguard Worker  */
findCString(uint32_t key,const char ** value) const161*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findCString(uint32_t key, const char **value) const {
162*ec779b8eSAndroid Build Coastguard Worker     uint32_t type;
163*ec779b8eSAndroid Build Coastguard Worker     const void *data;
164*ec779b8eSAndroid Build Coastguard Worker     size_t size;
165*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
166*ec779b8eSAndroid Build Coastguard Worker         return false;
167*ec779b8eSAndroid Build Coastguard Worker     }
168*ec779b8eSAndroid Build Coastguard Worker 
169*ec779b8eSAndroid Build Coastguard Worker     *value = (const char *)data;
170*ec779b8eSAndroid Build Coastguard Worker 
171*ec779b8eSAndroid Build Coastguard Worker     return true;
172*ec779b8eSAndroid Build Coastguard Worker }
173*ec779b8eSAndroid Build Coastguard Worker 
findInt32(uint32_t key,int32_t * value) const174*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findInt32(uint32_t key, int32_t *value) const {
175*ec779b8eSAndroid Build Coastguard Worker     uint32_t type = 0;
176*ec779b8eSAndroid Build Coastguard Worker     const void *data;
177*ec779b8eSAndroid Build Coastguard Worker     size_t size;
178*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
179*ec779b8eSAndroid Build Coastguard Worker         return false;
180*ec779b8eSAndroid Build Coastguard Worker     }
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker     CHECK_EQ(size, sizeof(*value));
183*ec779b8eSAndroid Build Coastguard Worker 
184*ec779b8eSAndroid Build Coastguard Worker     *value = *(int32_t *)data;
185*ec779b8eSAndroid Build Coastguard Worker 
186*ec779b8eSAndroid Build Coastguard Worker     return true;
187*ec779b8eSAndroid Build Coastguard Worker }
188*ec779b8eSAndroid Build Coastguard Worker 
findInt64(uint32_t key,int64_t * value) const189*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findInt64(uint32_t key, int64_t *value) const {
190*ec779b8eSAndroid Build Coastguard Worker     uint32_t type = 0;
191*ec779b8eSAndroid Build Coastguard Worker     const void *data;
192*ec779b8eSAndroid Build Coastguard Worker     size_t size;
193*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_INT64) {
194*ec779b8eSAndroid Build Coastguard Worker         return false;
195*ec779b8eSAndroid Build Coastguard Worker     }
196*ec779b8eSAndroid Build Coastguard Worker 
197*ec779b8eSAndroid Build Coastguard Worker     CHECK_EQ(size, sizeof(*value));
198*ec779b8eSAndroid Build Coastguard Worker 
199*ec779b8eSAndroid Build Coastguard Worker     *value = *(int64_t *)data;
200*ec779b8eSAndroid Build Coastguard Worker 
201*ec779b8eSAndroid Build Coastguard Worker     return true;
202*ec779b8eSAndroid Build Coastguard Worker }
203*ec779b8eSAndroid Build Coastguard Worker 
findFloat(uint32_t key,float * value) const204*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findFloat(uint32_t key, float *value) const {
205*ec779b8eSAndroid Build Coastguard Worker     uint32_t type = 0;
206*ec779b8eSAndroid Build Coastguard Worker     const void *data;
207*ec779b8eSAndroid Build Coastguard Worker     size_t size;
208*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
209*ec779b8eSAndroid Build Coastguard Worker         return false;
210*ec779b8eSAndroid Build Coastguard Worker     }
211*ec779b8eSAndroid Build Coastguard Worker 
212*ec779b8eSAndroid Build Coastguard Worker     CHECK_EQ(size, sizeof(*value));
213*ec779b8eSAndroid Build Coastguard Worker 
214*ec779b8eSAndroid Build Coastguard Worker     *value = *(float *)data;
215*ec779b8eSAndroid Build Coastguard Worker 
216*ec779b8eSAndroid Build Coastguard Worker     return true;
217*ec779b8eSAndroid Build Coastguard Worker }
218*ec779b8eSAndroid Build Coastguard Worker 
findPointer(uint32_t key,void ** value) const219*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findPointer(uint32_t key, void **value) const {
220*ec779b8eSAndroid Build Coastguard Worker     uint32_t type = 0;
221*ec779b8eSAndroid Build Coastguard Worker     const void *data;
222*ec779b8eSAndroid Build Coastguard Worker     size_t size;
223*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
224*ec779b8eSAndroid Build Coastguard Worker         return false;
225*ec779b8eSAndroid Build Coastguard Worker     }
226*ec779b8eSAndroid Build Coastguard Worker 
227*ec779b8eSAndroid Build Coastguard Worker     CHECK_EQ(size, sizeof(*value));
228*ec779b8eSAndroid Build Coastguard Worker 
229*ec779b8eSAndroid Build Coastguard Worker     *value = *(void **)data;
230*ec779b8eSAndroid Build Coastguard Worker 
231*ec779b8eSAndroid Build Coastguard Worker     return true;
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker 
findRect(uint32_t key,int32_t * left,int32_t * top,int32_t * right,int32_t * bottom) const234*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findRect(
235*ec779b8eSAndroid Build Coastguard Worker         uint32_t key,
236*ec779b8eSAndroid Build Coastguard Worker         int32_t *left, int32_t *top,
237*ec779b8eSAndroid Build Coastguard Worker         int32_t *right, int32_t *bottom) const {
238*ec779b8eSAndroid Build Coastguard Worker     uint32_t type = 0;
239*ec779b8eSAndroid Build Coastguard Worker     const void *data;
240*ec779b8eSAndroid Build Coastguard Worker     size_t size;
241*ec779b8eSAndroid Build Coastguard Worker     if (!findData(key, &type, &data, &size) || type != TYPE_RECT) {
242*ec779b8eSAndroid Build Coastguard Worker         return false;
243*ec779b8eSAndroid Build Coastguard Worker     }
244*ec779b8eSAndroid Build Coastguard Worker 
245*ec779b8eSAndroid Build Coastguard Worker     CHECK_EQ(size, sizeof(Rect));
246*ec779b8eSAndroid Build Coastguard Worker 
247*ec779b8eSAndroid Build Coastguard Worker     const Rect *r = (const Rect *)data;
248*ec779b8eSAndroid Build Coastguard Worker     *left = r->mLeft;
249*ec779b8eSAndroid Build Coastguard Worker     *top = r->mTop;
250*ec779b8eSAndroid Build Coastguard Worker     *right = r->mRight;
251*ec779b8eSAndroid Build Coastguard Worker     *bottom = r->mBottom;
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker     return true;
254*ec779b8eSAndroid Build Coastguard Worker }
255*ec779b8eSAndroid Build Coastguard Worker 
setData(uint32_t key,uint32_t type,const void * data,size_t size)256*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::setData(
257*ec779b8eSAndroid Build Coastguard Worker         uint32_t key, uint32_t type, const void *data, size_t size) {
258*ec779b8eSAndroid Build Coastguard Worker     bool overwrote_existing = true;
259*ec779b8eSAndroid Build Coastguard Worker 
260*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
261*ec779b8eSAndroid Build Coastguard Worker     ssize_t i = mInternalData->mItems.indexOfKey(key);
262*ec779b8eSAndroid Build Coastguard Worker     if (i < 0) {
263*ec779b8eSAndroid Build Coastguard Worker         typed_data item;
264*ec779b8eSAndroid Build Coastguard Worker         i = mInternalData->mItems.add(key, item);
265*ec779b8eSAndroid Build Coastguard Worker 
266*ec779b8eSAndroid Build Coastguard Worker         overwrote_existing = false;
267*ec779b8eSAndroid Build Coastguard Worker     }
268*ec779b8eSAndroid Build Coastguard Worker 
269*ec779b8eSAndroid Build Coastguard Worker     typed_data &item = mInternalData->mItems.editValueAt(i);
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker     item.setData(type, data, size);
272*ec779b8eSAndroid Build Coastguard Worker 
273*ec779b8eSAndroid Build Coastguard Worker     return overwrote_existing;
274*ec779b8eSAndroid Build Coastguard Worker }
275*ec779b8eSAndroid Build Coastguard Worker 
findData(uint32_t key,uint32_t * type,const void ** data,size_t * size) const276*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::findData(uint32_t key, uint32_t *type,
277*ec779b8eSAndroid Build Coastguard Worker                         const void **data, size_t *size) const {
278*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
279*ec779b8eSAndroid Build Coastguard Worker     ssize_t i = mInternalData->mItems.indexOfKey(key);
280*ec779b8eSAndroid Build Coastguard Worker 
281*ec779b8eSAndroid Build Coastguard Worker     if (i < 0) {
282*ec779b8eSAndroid Build Coastguard Worker         return false;
283*ec779b8eSAndroid Build Coastguard Worker     }
284*ec779b8eSAndroid Build Coastguard Worker 
285*ec779b8eSAndroid Build Coastguard Worker     const typed_data &item = mInternalData->mItems.valueAt(i);
286*ec779b8eSAndroid Build Coastguard Worker 
287*ec779b8eSAndroid Build Coastguard Worker     item.getData(type, data, size);
288*ec779b8eSAndroid Build Coastguard Worker 
289*ec779b8eSAndroid Build Coastguard Worker     return true;
290*ec779b8eSAndroid Build Coastguard Worker }
291*ec779b8eSAndroid Build Coastguard Worker 
hasData(uint32_t key) const292*ec779b8eSAndroid Build Coastguard Worker bool MetaDataBase::hasData(uint32_t key) const {
293*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
294*ec779b8eSAndroid Build Coastguard Worker     ssize_t i = mInternalData->mItems.indexOfKey(key);
295*ec779b8eSAndroid Build Coastguard Worker 
296*ec779b8eSAndroid Build Coastguard Worker     if (i < 0) {
297*ec779b8eSAndroid Build Coastguard Worker         return false;
298*ec779b8eSAndroid Build Coastguard Worker     }
299*ec779b8eSAndroid Build Coastguard Worker 
300*ec779b8eSAndroid Build Coastguard Worker     return true;
301*ec779b8eSAndroid Build Coastguard Worker }
302*ec779b8eSAndroid Build Coastguard Worker 
typed_data()303*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::typed_data::typed_data()
304*ec779b8eSAndroid Build Coastguard Worker     : mType(0),
305*ec779b8eSAndroid Build Coastguard Worker       mSize(0) {
306*ec779b8eSAndroid Build Coastguard Worker }
307*ec779b8eSAndroid Build Coastguard Worker 
~typed_data()308*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::typed_data::~typed_data() {
309*ec779b8eSAndroid Build Coastguard Worker     clear();
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker 
typed_data(const typed_data & from)312*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::typed_data::typed_data(const typed_data &from)
313*ec779b8eSAndroid Build Coastguard Worker     : mType(from.mType),
314*ec779b8eSAndroid Build Coastguard Worker       mSize(0) {
315*ec779b8eSAndroid Build Coastguard Worker 
316*ec779b8eSAndroid Build Coastguard Worker     void *dst = allocateStorage(from.mSize);
317*ec779b8eSAndroid Build Coastguard Worker     if (dst) {
318*ec779b8eSAndroid Build Coastguard Worker         memcpy(dst, from.storage(), mSize);
319*ec779b8eSAndroid Build Coastguard Worker     }
320*ec779b8eSAndroid Build Coastguard Worker }
321*ec779b8eSAndroid Build Coastguard Worker 
operator =(const MetaDataBase::typed_data & from)322*ec779b8eSAndroid Build Coastguard Worker MetaDataBase::typed_data &MetaDataBase::typed_data::operator=(
323*ec779b8eSAndroid Build Coastguard Worker         const MetaDataBase::typed_data &from) {
324*ec779b8eSAndroid Build Coastguard Worker     if (this != &from) {
325*ec779b8eSAndroid Build Coastguard Worker         clear();
326*ec779b8eSAndroid Build Coastguard Worker         mType = from.mType;
327*ec779b8eSAndroid Build Coastguard Worker         void *dst = allocateStorage(from.mSize);
328*ec779b8eSAndroid Build Coastguard Worker         if (dst) {
329*ec779b8eSAndroid Build Coastguard Worker             memcpy(dst, from.storage(), mSize);
330*ec779b8eSAndroid Build Coastguard Worker         }
331*ec779b8eSAndroid Build Coastguard Worker     }
332*ec779b8eSAndroid Build Coastguard Worker 
333*ec779b8eSAndroid Build Coastguard Worker     return *this;
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker 
clear()336*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::typed_data::clear() {
337*ec779b8eSAndroid Build Coastguard Worker     freeStorage();
338*ec779b8eSAndroid Build Coastguard Worker 
339*ec779b8eSAndroid Build Coastguard Worker     mType = 0;
340*ec779b8eSAndroid Build Coastguard Worker }
341*ec779b8eSAndroid Build Coastguard Worker 
setData(uint32_t type,const void * data,size_t size)342*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::typed_data::setData(
343*ec779b8eSAndroid Build Coastguard Worker         uint32_t type, const void *data, size_t size) {
344*ec779b8eSAndroid Build Coastguard Worker     clear();
345*ec779b8eSAndroid Build Coastguard Worker 
346*ec779b8eSAndroid Build Coastguard Worker     mType = type;
347*ec779b8eSAndroid Build Coastguard Worker 
348*ec779b8eSAndroid Build Coastguard Worker     void *dst = allocateStorage(size);
349*ec779b8eSAndroid Build Coastguard Worker     if (dst) {
350*ec779b8eSAndroid Build Coastguard Worker         memcpy(dst, data, size);
351*ec779b8eSAndroid Build Coastguard Worker     }
352*ec779b8eSAndroid Build Coastguard Worker }
353*ec779b8eSAndroid Build Coastguard Worker 
getData(uint32_t * type,const void ** data,size_t * size) const354*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::typed_data::getData(
355*ec779b8eSAndroid Build Coastguard Worker         uint32_t *type, const void **data, size_t *size) const {
356*ec779b8eSAndroid Build Coastguard Worker     *type = mType;
357*ec779b8eSAndroid Build Coastguard Worker     *size = mSize;
358*ec779b8eSAndroid Build Coastguard Worker     *data = storage();
359*ec779b8eSAndroid Build Coastguard Worker }
360*ec779b8eSAndroid Build Coastguard Worker 
allocateStorage(size_t size)361*ec779b8eSAndroid Build Coastguard Worker void *MetaDataBase::typed_data::allocateStorage(size_t size) {
362*ec779b8eSAndroid Build Coastguard Worker     mSize = size;
363*ec779b8eSAndroid Build Coastguard Worker 
364*ec779b8eSAndroid Build Coastguard Worker     if (usesReservoir()) {
365*ec779b8eSAndroid Build Coastguard Worker         return &u.reservoir;
366*ec779b8eSAndroid Build Coastguard Worker     }
367*ec779b8eSAndroid Build Coastguard Worker 
368*ec779b8eSAndroid Build Coastguard Worker     u.ext_data = malloc(mSize);
369*ec779b8eSAndroid Build Coastguard Worker     if (u.ext_data == NULL) {
370*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Couldn't allocate %zu bytes for item", size);
371*ec779b8eSAndroid Build Coastguard Worker         mSize = 0;
372*ec779b8eSAndroid Build Coastguard Worker     }
373*ec779b8eSAndroid Build Coastguard Worker     return u.ext_data;
374*ec779b8eSAndroid Build Coastguard Worker }
375*ec779b8eSAndroid Build Coastguard Worker 
freeStorage()376*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::typed_data::freeStorage() {
377*ec779b8eSAndroid Build Coastguard Worker     if (!usesReservoir()) {
378*ec779b8eSAndroid Build Coastguard Worker         if (u.ext_data) {
379*ec779b8eSAndroid Build Coastguard Worker             free(u.ext_data);
380*ec779b8eSAndroid Build Coastguard Worker             u.ext_data = NULL;
381*ec779b8eSAndroid Build Coastguard Worker         }
382*ec779b8eSAndroid Build Coastguard Worker     }
383*ec779b8eSAndroid Build Coastguard Worker 
384*ec779b8eSAndroid Build Coastguard Worker     mSize = 0;
385*ec779b8eSAndroid Build Coastguard Worker }
386*ec779b8eSAndroid Build Coastguard Worker 
asString(bool verbose) const387*ec779b8eSAndroid Build Coastguard Worker String8 MetaDataBase::typed_data::asString(bool verbose) const {
388*ec779b8eSAndroid Build Coastguard Worker     String8 out;
389*ec779b8eSAndroid Build Coastguard Worker     const void *data = storage();
390*ec779b8eSAndroid Build Coastguard Worker     switch(mType) {
391*ec779b8eSAndroid Build Coastguard Worker         case TYPE_NONE:
392*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("no type, size %zu)", mSize);
393*ec779b8eSAndroid Build Coastguard Worker             break;
394*ec779b8eSAndroid Build Coastguard Worker         case TYPE_C_STRING:
395*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(char*) %s", (const char *)data);
396*ec779b8eSAndroid Build Coastguard Worker             break;
397*ec779b8eSAndroid Build Coastguard Worker         case TYPE_INT32:
398*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(int32_t) %d", *(int32_t *)data);
399*ec779b8eSAndroid Build Coastguard Worker             break;
400*ec779b8eSAndroid Build Coastguard Worker         case TYPE_INT64:
401*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(int64_t) %" PRId64, *(int64_t *)data);
402*ec779b8eSAndroid Build Coastguard Worker             break;
403*ec779b8eSAndroid Build Coastguard Worker         case TYPE_FLOAT:
404*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(float) %f", *(float *)data);
405*ec779b8eSAndroid Build Coastguard Worker             break;
406*ec779b8eSAndroid Build Coastguard Worker         case TYPE_POINTER:
407*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(void*) %p", *(void **)data);
408*ec779b8eSAndroid Build Coastguard Worker             break;
409*ec779b8eSAndroid Build Coastguard Worker         case TYPE_RECT:
410*ec779b8eSAndroid Build Coastguard Worker         {
411*ec779b8eSAndroid Build Coastguard Worker             const Rect *r = (const Rect *)data;
412*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("Rect(%d, %d, %d, %d)",
413*ec779b8eSAndroid Build Coastguard Worker                                   r->mLeft, r->mTop, r->mRight, r->mBottom);
414*ec779b8eSAndroid Build Coastguard Worker             break;
415*ec779b8eSAndroid Build Coastguard Worker         }
416*ec779b8eSAndroid Build Coastguard Worker 
417*ec779b8eSAndroid Build Coastguard Worker         default:
418*ec779b8eSAndroid Build Coastguard Worker             out = String8::format("(unknown type %d, size %zu)", mType, mSize);
419*ec779b8eSAndroid Build Coastguard Worker             if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it
420*ec779b8eSAndroid Build Coastguard Worker                 AString foo;
421*ec779b8eSAndroid Build Coastguard Worker                 hexdump(data, mSize, 0, &foo);
422*ec779b8eSAndroid Build Coastguard Worker                 out.append("\n");
423*ec779b8eSAndroid Build Coastguard Worker                 out.append(foo.c_str());
424*ec779b8eSAndroid Build Coastguard Worker             }
425*ec779b8eSAndroid Build Coastguard Worker             break;
426*ec779b8eSAndroid Build Coastguard Worker     }
427*ec779b8eSAndroid Build Coastguard Worker     return out;
428*ec779b8eSAndroid Build Coastguard Worker }
429*ec779b8eSAndroid Build Coastguard Worker 
MakeFourCCString(uint32_t x,char * s)430*ec779b8eSAndroid Build Coastguard Worker static void MakeFourCCString(uint32_t x, char *s) {
431*ec779b8eSAndroid Build Coastguard Worker     s[0] = x >> 24;
432*ec779b8eSAndroid Build Coastguard Worker     s[1] = (x >> 16) & 0xff;
433*ec779b8eSAndroid Build Coastguard Worker     s[2] = (x >> 8) & 0xff;
434*ec779b8eSAndroid Build Coastguard Worker     s[3] = x & 0xff;
435*ec779b8eSAndroid Build Coastguard Worker     s[4] = '\0';
436*ec779b8eSAndroid Build Coastguard Worker }
437*ec779b8eSAndroid Build Coastguard Worker 
toString() const438*ec779b8eSAndroid Build Coastguard Worker String8 MetaDataBase::toString() const {
439*ec779b8eSAndroid Build Coastguard Worker     String8 s;
440*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
441*ec779b8eSAndroid Build Coastguard Worker     for (int i = mInternalData->mItems.size(); --i >= 0;) {
442*ec779b8eSAndroid Build Coastguard Worker         int32_t key = mInternalData->mItems.keyAt(i);
443*ec779b8eSAndroid Build Coastguard Worker         char cc[5];
444*ec779b8eSAndroid Build Coastguard Worker         MakeFourCCString(key, cc);
445*ec779b8eSAndroid Build Coastguard Worker         const typed_data &item = mInternalData->mItems.valueAt(i);
446*ec779b8eSAndroid Build Coastguard Worker         s.appendFormat("%s: %s", cc, item.asString(false).c_str());
447*ec779b8eSAndroid Build Coastguard Worker         if (i != 0) {
448*ec779b8eSAndroid Build Coastguard Worker             s.append(", ");
449*ec779b8eSAndroid Build Coastguard Worker         }
450*ec779b8eSAndroid Build Coastguard Worker     }
451*ec779b8eSAndroid Build Coastguard Worker     return s;
452*ec779b8eSAndroid Build Coastguard Worker }
453*ec779b8eSAndroid Build Coastguard Worker 
dumpToLog() const454*ec779b8eSAndroid Build Coastguard Worker void MetaDataBase::dumpToLog() const {
455*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
456*ec779b8eSAndroid Build Coastguard Worker     for (int i = mInternalData->mItems.size(); --i >= 0;) {
457*ec779b8eSAndroid Build Coastguard Worker         int32_t key = mInternalData->mItems.keyAt(i);
458*ec779b8eSAndroid Build Coastguard Worker         char cc[5];
459*ec779b8eSAndroid Build Coastguard Worker         MakeFourCCString(key, cc);
460*ec779b8eSAndroid Build Coastguard Worker         const typed_data &item = mInternalData->mItems.valueAt(i);
461*ec779b8eSAndroid Build Coastguard Worker         ALOGI("%s: %s", cc, item.asString(true /* verbose */).c_str());
462*ec779b8eSAndroid Build Coastguard Worker     }
463*ec779b8eSAndroid Build Coastguard Worker }
464*ec779b8eSAndroid Build Coastguard Worker 
465*ec779b8eSAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
writeToParcel(Parcel & parcel)466*ec779b8eSAndroid Build Coastguard Worker status_t MetaDataBase::writeToParcel(Parcel &parcel) {
467*ec779b8eSAndroid Build Coastguard Worker     status_t ret;
468*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(mInternalData->mLock);
469*ec779b8eSAndroid Build Coastguard Worker     size_t numItems = mInternalData->mItems.size();
470*ec779b8eSAndroid Build Coastguard Worker     ret = parcel.writeUint32(uint32_t(numItems));
471*ec779b8eSAndroid Build Coastguard Worker     if (ret) {
472*ec779b8eSAndroid Build Coastguard Worker         return ret;
473*ec779b8eSAndroid Build Coastguard Worker     }
474*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < numItems; i++) {
475*ec779b8eSAndroid Build Coastguard Worker         int32_t key = mInternalData->mItems.keyAt(i);
476*ec779b8eSAndroid Build Coastguard Worker         const typed_data &item = mInternalData->mItems.valueAt(i);
477*ec779b8eSAndroid Build Coastguard Worker         uint32_t type;
478*ec779b8eSAndroid Build Coastguard Worker         const void *data;
479*ec779b8eSAndroid Build Coastguard Worker         size_t size;
480*ec779b8eSAndroid Build Coastguard Worker         item.getData(&type, &data, &size);
481*ec779b8eSAndroid Build Coastguard Worker         ret = parcel.writeInt32(key);
482*ec779b8eSAndroid Build Coastguard Worker         if (ret) {
483*ec779b8eSAndroid Build Coastguard Worker             return ret;
484*ec779b8eSAndroid Build Coastguard Worker         }
485*ec779b8eSAndroid Build Coastguard Worker         ret = parcel.writeUint32(type);
486*ec779b8eSAndroid Build Coastguard Worker         if (ret) {
487*ec779b8eSAndroid Build Coastguard Worker             return ret;
488*ec779b8eSAndroid Build Coastguard Worker         }
489*ec779b8eSAndroid Build Coastguard Worker         if (type == TYPE_NONE) {
490*ec779b8eSAndroid Build Coastguard Worker             android::Parcel::WritableBlob blob;
491*ec779b8eSAndroid Build Coastguard Worker             ret = parcel.writeUint32(static_cast<uint32_t>(size));
492*ec779b8eSAndroid Build Coastguard Worker             if (ret) {
493*ec779b8eSAndroid Build Coastguard Worker                 return ret;
494*ec779b8eSAndroid Build Coastguard Worker             }
495*ec779b8eSAndroid Build Coastguard Worker             ret = parcel.writeBlob(size, false, &blob);
496*ec779b8eSAndroid Build Coastguard Worker             if (ret) {
497*ec779b8eSAndroid Build Coastguard Worker                 return ret;
498*ec779b8eSAndroid Build Coastguard Worker             }
499*ec779b8eSAndroid Build Coastguard Worker             memcpy(blob.data(), data, size);
500*ec779b8eSAndroid Build Coastguard Worker             blob.release();
501*ec779b8eSAndroid Build Coastguard Worker         } else {
502*ec779b8eSAndroid Build Coastguard Worker             ret = parcel.writeByteArray(size, (uint8_t*)data);
503*ec779b8eSAndroid Build Coastguard Worker             if (ret) {
504*ec779b8eSAndroid Build Coastguard Worker                 return ret;
505*ec779b8eSAndroid Build Coastguard Worker             }
506*ec779b8eSAndroid Build Coastguard Worker         }
507*ec779b8eSAndroid Build Coastguard Worker     }
508*ec779b8eSAndroid Build Coastguard Worker     return OK;
509*ec779b8eSAndroid Build Coastguard Worker }
510*ec779b8eSAndroid Build Coastguard Worker 
updateFromParcel(const Parcel & parcel)511*ec779b8eSAndroid Build Coastguard Worker status_t MetaDataBase::updateFromParcel(const Parcel &parcel) {
512*ec779b8eSAndroid Build Coastguard Worker     uint32_t numItems;
513*ec779b8eSAndroid Build Coastguard Worker     if (parcel.readUint32(&numItems) == OK) {
514*ec779b8eSAndroid Build Coastguard Worker 
515*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < numItems; i++) {
516*ec779b8eSAndroid Build Coastguard Worker             int32_t key;
517*ec779b8eSAndroid Build Coastguard Worker             uint32_t type;
518*ec779b8eSAndroid Build Coastguard Worker             uint32_t size;
519*ec779b8eSAndroid Build Coastguard Worker             status_t ret = parcel.readInt32(&key);
520*ec779b8eSAndroid Build Coastguard Worker             ret |= parcel.readUint32(&type);
521*ec779b8eSAndroid Build Coastguard Worker             ret |= parcel.readUint32(&size);
522*ec779b8eSAndroid Build Coastguard Worker             if (ret != OK) {
523*ec779b8eSAndroid Build Coastguard Worker                 break;
524*ec779b8eSAndroid Build Coastguard Worker             }
525*ec779b8eSAndroid Build Coastguard Worker             // copy data from Blob, which may be inline in Parcel storage,
526*ec779b8eSAndroid Build Coastguard Worker             // then advance position
527*ec779b8eSAndroid Build Coastguard Worker             if (type == TYPE_NONE) {
528*ec779b8eSAndroid Build Coastguard Worker                 android::Parcel::ReadableBlob blob;
529*ec779b8eSAndroid Build Coastguard Worker                 ret = parcel.readBlob(size, &blob);
530*ec779b8eSAndroid Build Coastguard Worker                 if (ret != OK) {
531*ec779b8eSAndroid Build Coastguard Worker                     break;
532*ec779b8eSAndroid Build Coastguard Worker                 }
533*ec779b8eSAndroid Build Coastguard Worker                 setData(key, type, blob.data(), size);
534*ec779b8eSAndroid Build Coastguard Worker                 blob.release();
535*ec779b8eSAndroid Build Coastguard Worker             } else if (type == TYPE_C_STRING) {
536*ec779b8eSAndroid Build Coastguard Worker                 // copy data directly from Parcel storage, then advance position
537*ec779b8eSAndroid Build Coastguard Worker                 // NB: readInplace() bumps position, it is NOT idempotent.
538*ec779b8eSAndroid Build Coastguard Worker                 const void *src = parcel.readInplace(size);
539*ec779b8eSAndroid Build Coastguard Worker                 char *str = (char *) src;
540*ec779b8eSAndroid Build Coastguard Worker                 if (src == nullptr || size == 0 || str[size-1] != '\0') {
541*ec779b8eSAndroid Build Coastguard Worker                     char ccKey[5];
542*ec779b8eSAndroid Build Coastguard Worker                     MakeFourCCString(key, ccKey);
543*ec779b8eSAndroid Build Coastguard Worker                     if (src == nullptr) {
544*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("ignoring key '%s' string with no data (expected %d)", ccKey, size);
545*ec779b8eSAndroid Build Coastguard Worker                     } else {
546*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("ignoring key '%s': unterminated string of %d bytes", ccKey, size);
547*ec779b8eSAndroid Build Coastguard Worker                     }
548*ec779b8eSAndroid Build Coastguard Worker                 } else {
549*ec779b8eSAndroid Build Coastguard Worker                     setData(key, type, src, size);
550*ec779b8eSAndroid Build Coastguard Worker                 }
551*ec779b8eSAndroid Build Coastguard Worker             } else {
552*ec779b8eSAndroid Build Coastguard Worker                 // copy data directly from Parcel storage, then advance position
553*ec779b8eSAndroid Build Coastguard Worker                 // verify that the received size is enough
554*ec779b8eSAndroid Build Coastguard Worker                 uint32_t needed = 0;
555*ec779b8eSAndroid Build Coastguard Worker                 switch (type) {
556*ec779b8eSAndroid Build Coastguard Worker                     case TYPE_INT32:
557*ec779b8eSAndroid Build Coastguard Worker                         needed = sizeof(int32_t);
558*ec779b8eSAndroid Build Coastguard Worker                         break;
559*ec779b8eSAndroid Build Coastguard Worker                     case TYPE_INT64:
560*ec779b8eSAndroid Build Coastguard Worker                         needed = sizeof(int64_t);
561*ec779b8eSAndroid Build Coastguard Worker                         break;
562*ec779b8eSAndroid Build Coastguard Worker                     case TYPE_FLOAT:
563*ec779b8eSAndroid Build Coastguard Worker                         needed = sizeof(float);
564*ec779b8eSAndroid Build Coastguard Worker                         break;
565*ec779b8eSAndroid Build Coastguard Worker                     case TYPE_POINTER:
566*ec779b8eSAndroid Build Coastguard Worker                         // NB: this rejects passing between 32-bit and 64-bit space.
567*ec779b8eSAndroid Build Coastguard Worker                         needed = sizeof(void*);
568*ec779b8eSAndroid Build Coastguard Worker                         break;
569*ec779b8eSAndroid Build Coastguard Worker                     case TYPE_RECT:
570*ec779b8eSAndroid Build Coastguard Worker                         needed = sizeof(Rect);
571*ec779b8eSAndroid Build Coastguard Worker                         break;
572*ec779b8eSAndroid Build Coastguard Worker                     default:
573*ec779b8eSAndroid Build Coastguard Worker                         // non-standard entities can be any size >= 0
574*ec779b8eSAndroid Build Coastguard Worker                         needed = 0;
575*ec779b8eSAndroid Build Coastguard Worker                         break;
576*ec779b8eSAndroid Build Coastguard Worker                 }
577*ec779b8eSAndroid Build Coastguard Worker                 const void *src = parcel.readInplace(size);
578*ec779b8eSAndroid Build Coastguard Worker                 if (src == nullptr || (needed != 0 && size != needed)) {
579*ec779b8eSAndroid Build Coastguard Worker                     char ccKey[5];
580*ec779b8eSAndroid Build Coastguard Worker                     MakeFourCCString(key, ccKey);
581*ec779b8eSAndroid Build Coastguard Worker                     char ccType[5];
582*ec779b8eSAndroid Build Coastguard Worker                     MakeFourCCString(type, ccType);
583*ec779b8eSAndroid Build Coastguard Worker                     if (src == nullptr) {
584*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("ignoring key '%s' type '%s' missing data (expected %d)",
585*ec779b8eSAndroid Build Coastguard Worker                               ccKey, ccType, size);
586*ec779b8eSAndroid Build Coastguard Worker                     } else {
587*ec779b8eSAndroid Build Coastguard Worker                         ALOGW("ignoring key '%s': type '%s' bytes: expected %d != %d received",
588*ec779b8eSAndroid Build Coastguard Worker                                ccKey, ccType, needed, size);
589*ec779b8eSAndroid Build Coastguard Worker                     }
590*ec779b8eSAndroid Build Coastguard Worker                 } else {
591*ec779b8eSAndroid Build Coastguard Worker                     setData(key, type, src, size);
592*ec779b8eSAndroid Build Coastguard Worker                 }
593*ec779b8eSAndroid Build Coastguard Worker             }
594*ec779b8eSAndroid Build Coastguard Worker          }
595*ec779b8eSAndroid Build Coastguard Worker 
596*ec779b8eSAndroid Build Coastguard Worker         return OK;
597*ec779b8eSAndroid Build Coastguard Worker     }
598*ec779b8eSAndroid Build Coastguard Worker     ALOGW("no metadata in parcel");
599*ec779b8eSAndroid Build Coastguard Worker     return UNKNOWN_ERROR;
600*ec779b8eSAndroid Build Coastguard Worker }
601*ec779b8eSAndroid Build Coastguard Worker #endif // defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
602*ec779b8eSAndroid Build Coastguard Worker 
603*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
604*ec779b8eSAndroid Build Coastguard Worker 
605