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