1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2010 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_TAG "AMessage"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker //#define DUMP_STATS
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <ctype.h>
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker #include "AMessage.h"
24*ec779b8eSAndroid Build Coastguard Worker
25*ec779b8eSAndroid Build Coastguard Worker #include <log/log.h>
26*ec779b8eSAndroid Build Coastguard Worker
27*ec779b8eSAndroid Build Coastguard Worker #include "AAtomizer.h"
28*ec779b8eSAndroid Build Coastguard Worker #include "ABuffer.h"
29*ec779b8eSAndroid Build Coastguard Worker #include "ADebug.h"
30*ec779b8eSAndroid Build Coastguard Worker #include "ALooperRoster.h"
31*ec779b8eSAndroid Build Coastguard Worker #include "AHandler.h"
32*ec779b8eSAndroid Build Coastguard Worker #include "AString.h"
33*ec779b8eSAndroid Build Coastguard Worker
34*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
35*ec779b8eSAndroid Build Coastguard Worker
36*ec779b8eSAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
37*ec779b8eSAndroid Build Coastguard Worker #include <binder/Parcel.h>
38*ec779b8eSAndroid Build Coastguard Worker #endif
39*ec779b8eSAndroid Build Coastguard Worker
40*ec779b8eSAndroid Build Coastguard Worker namespace android {
41*ec779b8eSAndroid Build Coastguard Worker
42*ec779b8eSAndroid Build Coastguard Worker extern ALooperRoster gLooperRoster;
43*ec779b8eSAndroid Build Coastguard Worker
setReply(const sp<AMessage> & reply)44*ec779b8eSAndroid Build Coastguard Worker status_t AReplyToken::setReply(const sp<AMessage> &reply) {
45*ec779b8eSAndroid Build Coastguard Worker if (mReplied) {
46*ec779b8eSAndroid Build Coastguard Worker ALOGE("trying to post a duplicate reply");
47*ec779b8eSAndroid Build Coastguard Worker return -EBUSY;
48*ec779b8eSAndroid Build Coastguard Worker }
49*ec779b8eSAndroid Build Coastguard Worker CHECK(mReply == NULL);
50*ec779b8eSAndroid Build Coastguard Worker mReply = reply;
51*ec779b8eSAndroid Build Coastguard Worker mReplied = true;
52*ec779b8eSAndroid Build Coastguard Worker return OK;
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
AMessage(void)55*ec779b8eSAndroid Build Coastguard Worker AMessage::AMessage(void)
56*ec779b8eSAndroid Build Coastguard Worker : mWhat(0),
57*ec779b8eSAndroid Build Coastguard Worker mTarget(0) {
58*ec779b8eSAndroid Build Coastguard Worker }
59*ec779b8eSAndroid Build Coastguard Worker
AMessage(uint32_t what,const sp<const AHandler> & handler)60*ec779b8eSAndroid Build Coastguard Worker AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler)
61*ec779b8eSAndroid Build Coastguard Worker : mWhat(what) {
62*ec779b8eSAndroid Build Coastguard Worker setTarget(handler);
63*ec779b8eSAndroid Build Coastguard Worker }
64*ec779b8eSAndroid Build Coastguard Worker
~AMessage()65*ec779b8eSAndroid Build Coastguard Worker AMessage::~AMessage() {
66*ec779b8eSAndroid Build Coastguard Worker clear();
67*ec779b8eSAndroid Build Coastguard Worker }
68*ec779b8eSAndroid Build Coastguard Worker
setWhat(uint32_t what)69*ec779b8eSAndroid Build Coastguard Worker void AMessage::setWhat(uint32_t what) {
70*ec779b8eSAndroid Build Coastguard Worker mWhat = what;
71*ec779b8eSAndroid Build Coastguard Worker }
72*ec779b8eSAndroid Build Coastguard Worker
what() const73*ec779b8eSAndroid Build Coastguard Worker uint32_t AMessage::what() const {
74*ec779b8eSAndroid Build Coastguard Worker return mWhat;
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
setTarget(const sp<const AHandler> & handler)77*ec779b8eSAndroid Build Coastguard Worker void AMessage::setTarget(const sp<const AHandler> &handler) {
78*ec779b8eSAndroid Build Coastguard Worker if (handler == NULL) {
79*ec779b8eSAndroid Build Coastguard Worker mTarget = 0;
80*ec779b8eSAndroid Build Coastguard Worker mHandler.clear();
81*ec779b8eSAndroid Build Coastguard Worker mLooper.clear();
82*ec779b8eSAndroid Build Coastguard Worker } else {
83*ec779b8eSAndroid Build Coastguard Worker mTarget = handler->id();
84*ec779b8eSAndroid Build Coastguard Worker mHandler = handler->getHandler();
85*ec779b8eSAndroid Build Coastguard Worker mLooper = handler->getLooper();
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker }
88*ec779b8eSAndroid Build Coastguard Worker
clear()89*ec779b8eSAndroid Build Coastguard Worker void AMessage::clear() {
90*ec779b8eSAndroid Build Coastguard Worker // Item needs to be handled delicately
91*ec779b8eSAndroid Build Coastguard Worker for (Item &item : mItems) {
92*ec779b8eSAndroid Build Coastguard Worker delete[] item.mName;
93*ec779b8eSAndroid Build Coastguard Worker item.mName = NULL;
94*ec779b8eSAndroid Build Coastguard Worker freeItemValue(&item);
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker mItems.clear();
97*ec779b8eSAndroid Build Coastguard Worker }
98*ec779b8eSAndroid Build Coastguard Worker
freeItemValue(Item * item)99*ec779b8eSAndroid Build Coastguard Worker void AMessage::freeItemValue(Item *item) {
100*ec779b8eSAndroid Build Coastguard Worker switch (item->mType) {
101*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
102*ec779b8eSAndroid Build Coastguard Worker {
103*ec779b8eSAndroid Build Coastguard Worker delete item->u.stringValue;
104*ec779b8eSAndroid Build Coastguard Worker break;
105*ec779b8eSAndroid Build Coastguard Worker }
106*ec779b8eSAndroid Build Coastguard Worker
107*ec779b8eSAndroid Build Coastguard Worker case kTypeObject:
108*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
109*ec779b8eSAndroid Build Coastguard Worker case kTypeBuffer:
110*ec779b8eSAndroid Build Coastguard Worker {
111*ec779b8eSAndroid Build Coastguard Worker if (item->u.refValue != NULL) {
112*ec779b8eSAndroid Build Coastguard Worker item->u.refValue->decStrong(this);
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker break;
115*ec779b8eSAndroid Build Coastguard Worker }
116*ec779b8eSAndroid Build Coastguard Worker
117*ec779b8eSAndroid Build Coastguard Worker default:
118*ec779b8eSAndroid Build Coastguard Worker break;
119*ec779b8eSAndroid Build Coastguard Worker }
120*ec779b8eSAndroid Build Coastguard Worker item->mType = kTypeInt32; // clear type
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker
123*ec779b8eSAndroid Build Coastguard Worker #ifdef DUMP_STATS
124*ec779b8eSAndroid Build Coastguard Worker #include <utils/Mutex.h>
125*ec779b8eSAndroid Build Coastguard Worker
126*ec779b8eSAndroid Build Coastguard Worker Mutex gLock;
127*ec779b8eSAndroid Build Coastguard Worker static int32_t gFindItemCalls = 1;
128*ec779b8eSAndroid Build Coastguard Worker static int32_t gDupCalls = 1;
129*ec779b8eSAndroid Build Coastguard Worker static int32_t gAverageNumItems = 0;
130*ec779b8eSAndroid Build Coastguard Worker static int32_t gAverageNumChecks = 0;
131*ec779b8eSAndroid Build Coastguard Worker static int32_t gAverageNumMemChecks = 0;
132*ec779b8eSAndroid Build Coastguard Worker static int32_t gAverageDupItems = 0;
133*ec779b8eSAndroid Build Coastguard Worker static int32_t gLastChecked = -1;
134*ec779b8eSAndroid Build Coastguard Worker
reportStats()135*ec779b8eSAndroid Build Coastguard Worker static void reportStats() {
136*ec779b8eSAndroid Build Coastguard Worker int32_t time = (ALooper::GetNowUs() / 1000);
137*ec779b8eSAndroid Build Coastguard Worker if (time / 1000 != gLastChecked / 1000) {
138*ec779b8eSAndroid Build Coastguard Worker gLastChecked = time;
139*ec779b8eSAndroid Build Coastguard Worker ALOGI("called findItemIx %zu times (for len=%.1f i=%.1f/%.1f mem) dup %zu times (for len=%.1f)",
140*ec779b8eSAndroid Build Coastguard Worker gFindItemCalls,
141*ec779b8eSAndroid Build Coastguard Worker gAverageNumItems / (float)gFindItemCalls,
142*ec779b8eSAndroid Build Coastguard Worker gAverageNumChecks / (float)gFindItemCalls,
143*ec779b8eSAndroid Build Coastguard Worker gAverageNumMemChecks / (float)gFindItemCalls,
144*ec779b8eSAndroid Build Coastguard Worker gDupCalls,
145*ec779b8eSAndroid Build Coastguard Worker gAverageDupItems / (float)gDupCalls);
146*ec779b8eSAndroid Build Coastguard Worker gFindItemCalls = gDupCalls = 1;
147*ec779b8eSAndroid Build Coastguard Worker gAverageNumItems = gAverageNumChecks = gAverageNumMemChecks = gAverageDupItems = 0;
148*ec779b8eSAndroid Build Coastguard Worker gLastChecked = time;
149*ec779b8eSAndroid Build Coastguard Worker }
150*ec779b8eSAndroid Build Coastguard Worker }
151*ec779b8eSAndroid Build Coastguard Worker #endif
152*ec779b8eSAndroid Build Coastguard Worker
findItemIndex(const char * name,size_t len) const153*ec779b8eSAndroid Build Coastguard Worker inline size_t AMessage::findItemIndex(const char *name, size_t len) const {
154*ec779b8eSAndroid Build Coastguard Worker #ifdef DUMP_STATS
155*ec779b8eSAndroid Build Coastguard Worker size_t memchecks = 0;
156*ec779b8eSAndroid Build Coastguard Worker #endif
157*ec779b8eSAndroid Build Coastguard Worker size_t i = 0;
158*ec779b8eSAndroid Build Coastguard Worker for (; i < mItems.size(); i++) {
159*ec779b8eSAndroid Build Coastguard Worker if (len != mItems[i].mNameLength) {
160*ec779b8eSAndroid Build Coastguard Worker continue;
161*ec779b8eSAndroid Build Coastguard Worker }
162*ec779b8eSAndroid Build Coastguard Worker #ifdef DUMP_STATS
163*ec779b8eSAndroid Build Coastguard Worker ++memchecks;
164*ec779b8eSAndroid Build Coastguard Worker #endif
165*ec779b8eSAndroid Build Coastguard Worker if (!memcmp(mItems[i].mName, name, len)) {
166*ec779b8eSAndroid Build Coastguard Worker break;
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker }
169*ec779b8eSAndroid Build Coastguard Worker #ifdef DUMP_STATS
170*ec779b8eSAndroid Build Coastguard Worker {
171*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(gLock);
172*ec779b8eSAndroid Build Coastguard Worker ++gFindItemCalls;
173*ec779b8eSAndroid Build Coastguard Worker gAverageNumItems += mItems.size();
174*ec779b8eSAndroid Build Coastguard Worker gAverageNumMemChecks += memchecks;
175*ec779b8eSAndroid Build Coastguard Worker gAverageNumChecks += i;
176*ec779b8eSAndroid Build Coastguard Worker reportStats();
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker #endif
179*ec779b8eSAndroid Build Coastguard Worker return i;
180*ec779b8eSAndroid Build Coastguard Worker }
181*ec779b8eSAndroid Build Coastguard Worker
182*ec779b8eSAndroid Build Coastguard Worker // assumes item's name was uninitialized or NULL
setName(const char * name,size_t len)183*ec779b8eSAndroid Build Coastguard Worker void AMessage::Item::setName(const char *name, size_t len) {
184*ec779b8eSAndroid Build Coastguard Worker mNameLength = len;
185*ec779b8eSAndroid Build Coastguard Worker mName = new char[len + 1];
186*ec779b8eSAndroid Build Coastguard Worker memcpy((void*)mName, name, len + 1);
187*ec779b8eSAndroid Build Coastguard Worker }
188*ec779b8eSAndroid Build Coastguard Worker
Item(const char * name,size_t len)189*ec779b8eSAndroid Build Coastguard Worker AMessage::Item::Item(const char *name, size_t len)
190*ec779b8eSAndroid Build Coastguard Worker : mType(kTypeInt32) {
191*ec779b8eSAndroid Build Coastguard Worker // mName and mNameLength are initialized by setName
192*ec779b8eSAndroid Build Coastguard Worker setName(name, len);
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker
allocateItem(const char * name)195*ec779b8eSAndroid Build Coastguard Worker AMessage::Item *AMessage::allocateItem(const char *name) {
196*ec779b8eSAndroid Build Coastguard Worker size_t len = strlen(name);
197*ec779b8eSAndroid Build Coastguard Worker size_t i = findItemIndex(name, len);
198*ec779b8eSAndroid Build Coastguard Worker Item *item;
199*ec779b8eSAndroid Build Coastguard Worker
200*ec779b8eSAndroid Build Coastguard Worker if (i < mItems.size()) {
201*ec779b8eSAndroid Build Coastguard Worker item = &mItems[i];
202*ec779b8eSAndroid Build Coastguard Worker freeItemValue(item);
203*ec779b8eSAndroid Build Coastguard Worker } else {
204*ec779b8eSAndroid Build Coastguard Worker CHECK(mItems.size() < kMaxNumItems);
205*ec779b8eSAndroid Build Coastguard Worker i = mItems.size();
206*ec779b8eSAndroid Build Coastguard Worker // place a 'blank' item at the end - this is of type kTypeInt32
207*ec779b8eSAndroid Build Coastguard Worker mItems.emplace_back(name, len);
208*ec779b8eSAndroid Build Coastguard Worker item = &mItems[i];
209*ec779b8eSAndroid Build Coastguard Worker }
210*ec779b8eSAndroid Build Coastguard Worker
211*ec779b8eSAndroid Build Coastguard Worker return item;
212*ec779b8eSAndroid Build Coastguard Worker }
213*ec779b8eSAndroid Build Coastguard Worker
findItem(const char * name,Type type) const214*ec779b8eSAndroid Build Coastguard Worker const AMessage::Item *AMessage::findItem(
215*ec779b8eSAndroid Build Coastguard Worker const char *name, Type type) const {
216*ec779b8eSAndroid Build Coastguard Worker size_t i = findItemIndex(name, strlen(name));
217*ec779b8eSAndroid Build Coastguard Worker if (i < mItems.size()) {
218*ec779b8eSAndroid Build Coastguard Worker const Item *item = &mItems[i];
219*ec779b8eSAndroid Build Coastguard Worker return item->mType == type ? item : NULL;
220*ec779b8eSAndroid Build Coastguard Worker
221*ec779b8eSAndroid Build Coastguard Worker }
222*ec779b8eSAndroid Build Coastguard Worker return NULL;
223*ec779b8eSAndroid Build Coastguard Worker }
224*ec779b8eSAndroid Build Coastguard Worker
findAsFloat(const char * name,float * value) const225*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findAsFloat(const char *name, float *value) const {
226*ec779b8eSAndroid Build Coastguard Worker size_t i = findItemIndex(name, strlen(name));
227*ec779b8eSAndroid Build Coastguard Worker if (i < mItems.size()) {
228*ec779b8eSAndroid Build Coastguard Worker const Item *item = &mItems[i];
229*ec779b8eSAndroid Build Coastguard Worker switch (item->mType) {
230*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat:
231*ec779b8eSAndroid Build Coastguard Worker *value = item->u.floatValue;
232*ec779b8eSAndroid Build Coastguard Worker return true;
233*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble:
234*ec779b8eSAndroid Build Coastguard Worker *value = (float)item->u.doubleValue;
235*ec779b8eSAndroid Build Coastguard Worker return true;
236*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
237*ec779b8eSAndroid Build Coastguard Worker *value = (float)item->u.int64Value;
238*ec779b8eSAndroid Build Coastguard Worker return true;
239*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
240*ec779b8eSAndroid Build Coastguard Worker *value = (float)item->u.int32Value;
241*ec779b8eSAndroid Build Coastguard Worker return true;
242*ec779b8eSAndroid Build Coastguard Worker case kTypeSize:
243*ec779b8eSAndroid Build Coastguard Worker *value = (float)item->u.sizeValue;
244*ec779b8eSAndroid Build Coastguard Worker return true;
245*ec779b8eSAndroid Build Coastguard Worker default:
246*ec779b8eSAndroid Build Coastguard Worker return false;
247*ec779b8eSAndroid Build Coastguard Worker }
248*ec779b8eSAndroid Build Coastguard Worker }
249*ec779b8eSAndroid Build Coastguard Worker return false;
250*ec779b8eSAndroid Build Coastguard Worker }
251*ec779b8eSAndroid Build Coastguard Worker
findAsInt64(const char * name,int64_t * value) const252*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findAsInt64(const char *name, int64_t *value) const {
253*ec779b8eSAndroid Build Coastguard Worker size_t i = findItemIndex(name, strlen(name));
254*ec779b8eSAndroid Build Coastguard Worker if (i < mItems.size()) {
255*ec779b8eSAndroid Build Coastguard Worker const Item *item = &mItems[i];
256*ec779b8eSAndroid Build Coastguard Worker switch (item->mType) {
257*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
258*ec779b8eSAndroid Build Coastguard Worker *value = item->u.int64Value;
259*ec779b8eSAndroid Build Coastguard Worker return true;
260*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
261*ec779b8eSAndroid Build Coastguard Worker *value = item->u.int32Value;
262*ec779b8eSAndroid Build Coastguard Worker return true;
263*ec779b8eSAndroid Build Coastguard Worker default:
264*ec779b8eSAndroid Build Coastguard Worker return false;
265*ec779b8eSAndroid Build Coastguard Worker }
266*ec779b8eSAndroid Build Coastguard Worker }
267*ec779b8eSAndroid Build Coastguard Worker return false;
268*ec779b8eSAndroid Build Coastguard Worker }
269*ec779b8eSAndroid Build Coastguard Worker
contains(const char * name) const270*ec779b8eSAndroid Build Coastguard Worker bool AMessage::contains(const char *name) const {
271*ec779b8eSAndroid Build Coastguard Worker size_t i = findItemIndex(name, strlen(name));
272*ec779b8eSAndroid Build Coastguard Worker return i < mItems.size();
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker
275*ec779b8eSAndroid Build Coastguard Worker #define BASIC_TYPE(NAME,FIELDNAME,TYPENAME) \
276*ec779b8eSAndroid Build Coastguard Worker void AMessage::set##NAME(const char *name, TYPENAME value) { \
277*ec779b8eSAndroid Build Coastguard Worker Item *item = allocateItem(name); \
278*ec779b8eSAndroid Build Coastguard Worker if (item) { \
279*ec779b8eSAndroid Build Coastguard Worker item->mType = kType##NAME; \
280*ec779b8eSAndroid Build Coastguard Worker item->u.FIELDNAME = value; \
281*ec779b8eSAndroid Build Coastguard Worker } \
282*ec779b8eSAndroid Build Coastguard Worker } \
283*ec779b8eSAndroid Build Coastguard Worker \
284*ec779b8eSAndroid Build Coastguard Worker /* NOLINT added to avoid incorrect warning/fix from clang.tidy */ \
285*ec779b8eSAndroid Build Coastguard Worker bool AMessage::find##NAME(const char *name, TYPENAME *value) const { /* NOLINT */ \
286*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kType##NAME); \
287*ec779b8eSAndroid Build Coastguard Worker if (item) { \
288*ec779b8eSAndroid Build Coastguard Worker *value = item->u.FIELDNAME; \
289*ec779b8eSAndroid Build Coastguard Worker return true; \
290*ec779b8eSAndroid Build Coastguard Worker } \
291*ec779b8eSAndroid Build Coastguard Worker return false; \
292*ec779b8eSAndroid Build Coastguard Worker }
293*ec779b8eSAndroid Build Coastguard Worker
BASIC_TYPE(Int32,int32Value,int32_t)294*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Int32,int32Value,int32_t)
295*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Int64,int64Value,int64_t)
296*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Size,sizeValue,size_t)
297*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Float,floatValue,float)
298*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Double,doubleValue,double)
299*ec779b8eSAndroid Build Coastguard Worker BASIC_TYPE(Pointer,ptrValue,void *)
300*ec779b8eSAndroid Build Coastguard Worker
301*ec779b8eSAndroid Build Coastguard Worker #undef BASIC_TYPE
302*ec779b8eSAndroid Build Coastguard Worker
303*ec779b8eSAndroid Build Coastguard Worker void AMessage::setString(
304*ec779b8eSAndroid Build Coastguard Worker const char *name, const char *s, ssize_t len) {
305*ec779b8eSAndroid Build Coastguard Worker Item *item = allocateItem(name);
306*ec779b8eSAndroid Build Coastguard Worker if (item) {
307*ec779b8eSAndroid Build Coastguard Worker item->mType = kTypeString;
308*ec779b8eSAndroid Build Coastguard Worker item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
309*ec779b8eSAndroid Build Coastguard Worker }
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker
setString(const char * name,const AString & s)312*ec779b8eSAndroid Build Coastguard Worker void AMessage::setString(
313*ec779b8eSAndroid Build Coastguard Worker const char *name, const AString &s) {
314*ec779b8eSAndroid Build Coastguard Worker setString(name, s.c_str(), s.size());
315*ec779b8eSAndroid Build Coastguard Worker }
316*ec779b8eSAndroid Build Coastguard Worker
setObjectInternal(const char * name,const sp<RefBase> & obj,Type type)317*ec779b8eSAndroid Build Coastguard Worker void AMessage::setObjectInternal(
318*ec779b8eSAndroid Build Coastguard Worker const char *name, const sp<RefBase> &obj, Type type) {
319*ec779b8eSAndroid Build Coastguard Worker Item *item = allocateItem(name);
320*ec779b8eSAndroid Build Coastguard Worker if (item) {
321*ec779b8eSAndroid Build Coastguard Worker item->mType = type;
322*ec779b8eSAndroid Build Coastguard Worker
323*ec779b8eSAndroid Build Coastguard Worker if (obj != NULL) { obj->incStrong(this); }
324*ec779b8eSAndroid Build Coastguard Worker item->u.refValue = obj.get();
325*ec779b8eSAndroid Build Coastguard Worker }
326*ec779b8eSAndroid Build Coastguard Worker }
327*ec779b8eSAndroid Build Coastguard Worker
setObject(const char * name,const sp<RefBase> & obj)328*ec779b8eSAndroid Build Coastguard Worker void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
329*ec779b8eSAndroid Build Coastguard Worker setObjectInternal(name, obj, kTypeObject);
330*ec779b8eSAndroid Build Coastguard Worker }
331*ec779b8eSAndroid Build Coastguard Worker
setBuffer(const char * name,const sp<ABuffer> & buffer)332*ec779b8eSAndroid Build Coastguard Worker void AMessage::setBuffer(const char *name, const sp<ABuffer> &buffer) {
333*ec779b8eSAndroid Build Coastguard Worker setObjectInternal(name, sp<RefBase>(buffer), kTypeBuffer);
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker
setMessage(const char * name,const sp<AMessage> & obj)336*ec779b8eSAndroid Build Coastguard Worker void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
337*ec779b8eSAndroid Build Coastguard Worker Item *item = allocateItem(name);
338*ec779b8eSAndroid Build Coastguard Worker if (item) {
339*ec779b8eSAndroid Build Coastguard Worker item->mType = kTypeMessage;
340*ec779b8eSAndroid Build Coastguard Worker
341*ec779b8eSAndroid Build Coastguard Worker if (obj != NULL) { obj->incStrong(this); }
342*ec779b8eSAndroid Build Coastguard Worker item->u.refValue = obj.get();
343*ec779b8eSAndroid Build Coastguard Worker }
344*ec779b8eSAndroid Build Coastguard Worker }
345*ec779b8eSAndroid Build Coastguard Worker
setRect(const char * name,int32_t left,int32_t top,int32_t right,int32_t bottom)346*ec779b8eSAndroid Build Coastguard Worker void AMessage::setRect(
347*ec779b8eSAndroid Build Coastguard Worker const char *name,
348*ec779b8eSAndroid Build Coastguard Worker int32_t left, int32_t top, int32_t right, int32_t bottom) {
349*ec779b8eSAndroid Build Coastguard Worker Item *item = allocateItem(name);
350*ec779b8eSAndroid Build Coastguard Worker if (item) {
351*ec779b8eSAndroid Build Coastguard Worker item->mType = kTypeRect;
352*ec779b8eSAndroid Build Coastguard Worker
353*ec779b8eSAndroid Build Coastguard Worker item->u.rectValue.mLeft = left;
354*ec779b8eSAndroid Build Coastguard Worker item->u.rectValue.mTop = top;
355*ec779b8eSAndroid Build Coastguard Worker item->u.rectValue.mRight = right;
356*ec779b8eSAndroid Build Coastguard Worker item->u.rectValue.mBottom = bottom;
357*ec779b8eSAndroid Build Coastguard Worker }
358*ec779b8eSAndroid Build Coastguard Worker }
359*ec779b8eSAndroid Build Coastguard Worker
findString(const char * name,AString * value) const360*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findString(const char *name, AString *value) const {
361*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kTypeString);
362*ec779b8eSAndroid Build Coastguard Worker if (item) {
363*ec779b8eSAndroid Build Coastguard Worker *value = *item->u.stringValue;
364*ec779b8eSAndroid Build Coastguard Worker return true;
365*ec779b8eSAndroid Build Coastguard Worker }
366*ec779b8eSAndroid Build Coastguard Worker return false;
367*ec779b8eSAndroid Build Coastguard Worker }
368*ec779b8eSAndroid Build Coastguard Worker
findObject(const char * name,sp<RefBase> * obj) const369*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findObject(const char *name, sp<RefBase> *obj) const {
370*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kTypeObject);
371*ec779b8eSAndroid Build Coastguard Worker if (item) {
372*ec779b8eSAndroid Build Coastguard Worker *obj = item->u.refValue;
373*ec779b8eSAndroid Build Coastguard Worker return true;
374*ec779b8eSAndroid Build Coastguard Worker }
375*ec779b8eSAndroid Build Coastguard Worker return false;
376*ec779b8eSAndroid Build Coastguard Worker }
377*ec779b8eSAndroid Build Coastguard Worker
findBuffer(const char * name,sp<ABuffer> * buf) const378*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findBuffer(const char *name, sp<ABuffer> *buf) const {
379*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kTypeBuffer);
380*ec779b8eSAndroid Build Coastguard Worker if (item) {
381*ec779b8eSAndroid Build Coastguard Worker *buf = (ABuffer *)(item->u.refValue);
382*ec779b8eSAndroid Build Coastguard Worker return true;
383*ec779b8eSAndroid Build Coastguard Worker }
384*ec779b8eSAndroid Build Coastguard Worker return false;
385*ec779b8eSAndroid Build Coastguard Worker }
386*ec779b8eSAndroid Build Coastguard Worker
findMessage(const char * name,sp<AMessage> * obj) const387*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
388*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kTypeMessage);
389*ec779b8eSAndroid Build Coastguard Worker if (item) {
390*ec779b8eSAndroid Build Coastguard Worker *obj = static_cast<AMessage *>(item->u.refValue);
391*ec779b8eSAndroid Build Coastguard Worker return true;
392*ec779b8eSAndroid Build Coastguard Worker }
393*ec779b8eSAndroid Build Coastguard Worker return false;
394*ec779b8eSAndroid Build Coastguard Worker }
395*ec779b8eSAndroid Build Coastguard Worker
findRect(const char * name,int32_t * left,int32_t * top,int32_t * right,int32_t * bottom) const396*ec779b8eSAndroid Build Coastguard Worker bool AMessage::findRect(
397*ec779b8eSAndroid Build Coastguard Worker const char *name,
398*ec779b8eSAndroid Build Coastguard Worker int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
399*ec779b8eSAndroid Build Coastguard Worker const Item *item = findItem(name, kTypeRect);
400*ec779b8eSAndroid Build Coastguard Worker if (item == NULL) {
401*ec779b8eSAndroid Build Coastguard Worker return false;
402*ec779b8eSAndroid Build Coastguard Worker }
403*ec779b8eSAndroid Build Coastguard Worker
404*ec779b8eSAndroid Build Coastguard Worker *left = item->u.rectValue.mLeft;
405*ec779b8eSAndroid Build Coastguard Worker *top = item->u.rectValue.mTop;
406*ec779b8eSAndroid Build Coastguard Worker *right = item->u.rectValue.mRight;
407*ec779b8eSAndroid Build Coastguard Worker *bottom = item->u.rectValue.mBottom;
408*ec779b8eSAndroid Build Coastguard Worker
409*ec779b8eSAndroid Build Coastguard Worker return true;
410*ec779b8eSAndroid Build Coastguard Worker }
411*ec779b8eSAndroid Build Coastguard Worker
deliver()412*ec779b8eSAndroid Build Coastguard Worker void AMessage::deliver() {
413*ec779b8eSAndroid Build Coastguard Worker sp<AHandler> handler = mHandler.promote();
414*ec779b8eSAndroid Build Coastguard Worker if (handler == NULL) {
415*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to deliver message as target handler %d is gone.", mTarget);
416*ec779b8eSAndroid Build Coastguard Worker return;
417*ec779b8eSAndroid Build Coastguard Worker }
418*ec779b8eSAndroid Build Coastguard Worker
419*ec779b8eSAndroid Build Coastguard Worker handler->deliverMessage(this);
420*ec779b8eSAndroid Build Coastguard Worker }
421*ec779b8eSAndroid Build Coastguard Worker
post(int64_t delayUs)422*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::post(int64_t delayUs) {
423*ec779b8eSAndroid Build Coastguard Worker sp<ALooper> looper = mLooper.promote();
424*ec779b8eSAndroid Build Coastguard Worker if (looper == NULL) {
425*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
426*ec779b8eSAndroid Build Coastguard Worker return -ENOENT;
427*ec779b8eSAndroid Build Coastguard Worker }
428*ec779b8eSAndroid Build Coastguard Worker
429*ec779b8eSAndroid Build Coastguard Worker looper->post(this, delayUs);
430*ec779b8eSAndroid Build Coastguard Worker return OK;
431*ec779b8eSAndroid Build Coastguard Worker }
432*ec779b8eSAndroid Build Coastguard Worker
postUnique(const sp<RefBase> & token,int64_t delayUs)433*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::postUnique(const sp<RefBase> &token, int64_t delayUs) {
434*ec779b8eSAndroid Build Coastguard Worker sp<ALooper> looper = mLooper.promote();
435*ec779b8eSAndroid Build Coastguard Worker if (looper == NULL) {
436*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to post message as target looper for handler %d is gone.",
437*ec779b8eSAndroid Build Coastguard Worker mTarget);
438*ec779b8eSAndroid Build Coastguard Worker return -ENOENT;
439*ec779b8eSAndroid Build Coastguard Worker }
440*ec779b8eSAndroid Build Coastguard Worker
441*ec779b8eSAndroid Build Coastguard Worker return looper->postUnique(this, token, delayUs);
442*ec779b8eSAndroid Build Coastguard Worker }
443*ec779b8eSAndroid Build Coastguard Worker
postAndAwaitResponse(sp<AMessage> * response)444*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) {
445*ec779b8eSAndroid Build Coastguard Worker sp<ALooper> looper = mLooper.promote();
446*ec779b8eSAndroid Build Coastguard Worker if (looper == NULL) {
447*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
448*ec779b8eSAndroid Build Coastguard Worker return -ENOENT;
449*ec779b8eSAndroid Build Coastguard Worker }
450*ec779b8eSAndroid Build Coastguard Worker
451*ec779b8eSAndroid Build Coastguard Worker sp<AReplyToken> token = looper->createReplyToken();
452*ec779b8eSAndroid Build Coastguard Worker if (token == NULL) {
453*ec779b8eSAndroid Build Coastguard Worker ALOGE("failed to create reply token");
454*ec779b8eSAndroid Build Coastguard Worker return -ENOMEM;
455*ec779b8eSAndroid Build Coastguard Worker }
456*ec779b8eSAndroid Build Coastguard Worker setObject("replyID", token);
457*ec779b8eSAndroid Build Coastguard Worker
458*ec779b8eSAndroid Build Coastguard Worker looper->post(this, 0 /* delayUs */);
459*ec779b8eSAndroid Build Coastguard Worker return looper->awaitResponse(token, response);
460*ec779b8eSAndroid Build Coastguard Worker }
461*ec779b8eSAndroid Build Coastguard Worker
postReply(const sp<AReplyToken> & replyToken)462*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::postReply(const sp<AReplyToken> &replyToken) {
463*ec779b8eSAndroid Build Coastguard Worker if (replyToken == NULL) {
464*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to post reply to a NULL token");
465*ec779b8eSAndroid Build Coastguard Worker return -ENOENT;
466*ec779b8eSAndroid Build Coastguard Worker }
467*ec779b8eSAndroid Build Coastguard Worker sp<ALooper> looper = replyToken->getLooper();
468*ec779b8eSAndroid Build Coastguard Worker if (looper == NULL) {
469*ec779b8eSAndroid Build Coastguard Worker ALOGW("failed to post reply as target looper is gone.");
470*ec779b8eSAndroid Build Coastguard Worker return -ENOENT;
471*ec779b8eSAndroid Build Coastguard Worker }
472*ec779b8eSAndroid Build Coastguard Worker return looper->postReply(replyToken, this);
473*ec779b8eSAndroid Build Coastguard Worker }
474*ec779b8eSAndroid Build Coastguard Worker
senderAwaitsResponse(sp<AReplyToken> * replyToken)475*ec779b8eSAndroid Build Coastguard Worker bool AMessage::senderAwaitsResponse(sp<AReplyToken> *replyToken) {
476*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> tmp;
477*ec779b8eSAndroid Build Coastguard Worker bool found = findObject("replyID", &tmp);
478*ec779b8eSAndroid Build Coastguard Worker
479*ec779b8eSAndroid Build Coastguard Worker if (!found) {
480*ec779b8eSAndroid Build Coastguard Worker return false;
481*ec779b8eSAndroid Build Coastguard Worker }
482*ec779b8eSAndroid Build Coastguard Worker
483*ec779b8eSAndroid Build Coastguard Worker *replyToken = static_cast<AReplyToken *>(tmp.get());
484*ec779b8eSAndroid Build Coastguard Worker tmp.clear();
485*ec779b8eSAndroid Build Coastguard Worker setObject("replyID", tmp);
486*ec779b8eSAndroid Build Coastguard Worker // TODO: delete Object instead of setting it to NULL
487*ec779b8eSAndroid Build Coastguard Worker
488*ec779b8eSAndroid Build Coastguard Worker return *replyToken != NULL;
489*ec779b8eSAndroid Build Coastguard Worker }
490*ec779b8eSAndroid Build Coastguard Worker
dup() const491*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AMessage::dup() const {
492*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(mWhat, mHandler.promote());
493*ec779b8eSAndroid Build Coastguard Worker msg->mItems = mItems;
494*ec779b8eSAndroid Build Coastguard Worker
495*ec779b8eSAndroid Build Coastguard Worker #ifdef DUMP_STATS
496*ec779b8eSAndroid Build Coastguard Worker {
497*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(gLock);
498*ec779b8eSAndroid Build Coastguard Worker ++gDupCalls;
499*ec779b8eSAndroid Build Coastguard Worker gAverageDupItems += mItems.size();
500*ec779b8eSAndroid Build Coastguard Worker reportStats();
501*ec779b8eSAndroid Build Coastguard Worker }
502*ec779b8eSAndroid Build Coastguard Worker #endif
503*ec779b8eSAndroid Build Coastguard Worker
504*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mItems.size(); ++i) {
505*ec779b8eSAndroid Build Coastguard Worker const Item *from = &mItems[i];
506*ec779b8eSAndroid Build Coastguard Worker Item *to = &msg->mItems[i];
507*ec779b8eSAndroid Build Coastguard Worker
508*ec779b8eSAndroid Build Coastguard Worker to->setName(from->mName, from->mNameLength);
509*ec779b8eSAndroid Build Coastguard Worker to->mType = from->mType;
510*ec779b8eSAndroid Build Coastguard Worker
511*ec779b8eSAndroid Build Coastguard Worker switch (from->mType) {
512*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
513*ec779b8eSAndroid Build Coastguard Worker {
514*ec779b8eSAndroid Build Coastguard Worker to->u.stringValue =
515*ec779b8eSAndroid Build Coastguard Worker new AString(*from->u.stringValue);
516*ec779b8eSAndroid Build Coastguard Worker break;
517*ec779b8eSAndroid Build Coastguard Worker }
518*ec779b8eSAndroid Build Coastguard Worker
519*ec779b8eSAndroid Build Coastguard Worker case kTypeObject:
520*ec779b8eSAndroid Build Coastguard Worker case kTypeBuffer:
521*ec779b8eSAndroid Build Coastguard Worker {
522*ec779b8eSAndroid Build Coastguard Worker to->u.refValue = from->u.refValue;
523*ec779b8eSAndroid Build Coastguard Worker to->u.refValue->incStrong(msg.get());
524*ec779b8eSAndroid Build Coastguard Worker break;
525*ec779b8eSAndroid Build Coastguard Worker }
526*ec779b8eSAndroid Build Coastguard Worker
527*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
528*ec779b8eSAndroid Build Coastguard Worker {
529*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> copy =
530*ec779b8eSAndroid Build Coastguard Worker static_cast<AMessage *>(from->u.refValue)->dup();
531*ec779b8eSAndroid Build Coastguard Worker
532*ec779b8eSAndroid Build Coastguard Worker to->u.refValue = copy.get();
533*ec779b8eSAndroid Build Coastguard Worker to->u.refValue->incStrong(msg.get());
534*ec779b8eSAndroid Build Coastguard Worker break;
535*ec779b8eSAndroid Build Coastguard Worker }
536*ec779b8eSAndroid Build Coastguard Worker
537*ec779b8eSAndroid Build Coastguard Worker default:
538*ec779b8eSAndroid Build Coastguard Worker {
539*ec779b8eSAndroid Build Coastguard Worker to->u = from->u;
540*ec779b8eSAndroid Build Coastguard Worker break;
541*ec779b8eSAndroid Build Coastguard Worker }
542*ec779b8eSAndroid Build Coastguard Worker }
543*ec779b8eSAndroid Build Coastguard Worker }
544*ec779b8eSAndroid Build Coastguard Worker
545*ec779b8eSAndroid Build Coastguard Worker return msg;
546*ec779b8eSAndroid Build Coastguard Worker }
547*ec779b8eSAndroid Build Coastguard Worker
appendIndent(AString * s,int32_t indent)548*ec779b8eSAndroid Build Coastguard Worker static void appendIndent(AString *s, int32_t indent) {
549*ec779b8eSAndroid Build Coastguard Worker static const char kWhitespace[] =
550*ec779b8eSAndroid Build Coastguard Worker " "
551*ec779b8eSAndroid Build Coastguard Worker " ";
552*ec779b8eSAndroid Build Coastguard Worker
553*ec779b8eSAndroid Build Coastguard Worker CHECK_LT((size_t)indent, sizeof(kWhitespace));
554*ec779b8eSAndroid Build Coastguard Worker
555*ec779b8eSAndroid Build Coastguard Worker s->append(kWhitespace, indent);
556*ec779b8eSAndroid Build Coastguard Worker }
557*ec779b8eSAndroid Build Coastguard Worker
isFourcc(uint32_t what)558*ec779b8eSAndroid Build Coastguard Worker static bool isFourcc(uint32_t what) {
559*ec779b8eSAndroid Build Coastguard Worker return isprint(what & 0xff)
560*ec779b8eSAndroid Build Coastguard Worker && isprint((what >> 8) & 0xff)
561*ec779b8eSAndroid Build Coastguard Worker && isprint((what >> 16) & 0xff)
562*ec779b8eSAndroid Build Coastguard Worker && isprint((what >> 24) & 0xff);
563*ec779b8eSAndroid Build Coastguard Worker }
564*ec779b8eSAndroid Build Coastguard Worker
debugString(int32_t indent) const565*ec779b8eSAndroid Build Coastguard Worker AString AMessage::debugString(int32_t indent) const {
566*ec779b8eSAndroid Build Coastguard Worker AString s = "AMessage(what = ";
567*ec779b8eSAndroid Build Coastguard Worker
568*ec779b8eSAndroid Build Coastguard Worker AString tmp;
569*ec779b8eSAndroid Build Coastguard Worker if (isFourcc(mWhat)) {
570*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
571*ec779b8eSAndroid Build Coastguard Worker "'%c%c%c%c'",
572*ec779b8eSAndroid Build Coastguard Worker (char)(mWhat >> 24),
573*ec779b8eSAndroid Build Coastguard Worker (char)((mWhat >> 16) & 0xff),
574*ec779b8eSAndroid Build Coastguard Worker (char)((mWhat >> 8) & 0xff),
575*ec779b8eSAndroid Build Coastguard Worker (char)(mWhat & 0xff));
576*ec779b8eSAndroid Build Coastguard Worker } else {
577*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf("0x%08x", mWhat);
578*ec779b8eSAndroid Build Coastguard Worker }
579*ec779b8eSAndroid Build Coastguard Worker s.append(tmp);
580*ec779b8eSAndroid Build Coastguard Worker
581*ec779b8eSAndroid Build Coastguard Worker if (mTarget != 0) {
582*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(", target = %d", mTarget);
583*ec779b8eSAndroid Build Coastguard Worker s.append(tmp);
584*ec779b8eSAndroid Build Coastguard Worker }
585*ec779b8eSAndroid Build Coastguard Worker s.append(") = {\n");
586*ec779b8eSAndroid Build Coastguard Worker
587*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mItems.size(); ++i) {
588*ec779b8eSAndroid Build Coastguard Worker const Item &item = mItems[i];
589*ec779b8eSAndroid Build Coastguard Worker
590*ec779b8eSAndroid Build Coastguard Worker switch (item.mType) {
591*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
592*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
593*ec779b8eSAndroid Build Coastguard Worker "int32_t %s = %d", item.mName, item.u.int32Value);
594*ec779b8eSAndroid Build Coastguard Worker break;
595*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
596*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
597*ec779b8eSAndroid Build Coastguard Worker "int64_t %s = %lld", item.mName, item.u.int64Value);
598*ec779b8eSAndroid Build Coastguard Worker break;
599*ec779b8eSAndroid Build Coastguard Worker case kTypeSize:
600*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
601*ec779b8eSAndroid Build Coastguard Worker "size_t %s = %d", item.mName, item.u.sizeValue);
602*ec779b8eSAndroid Build Coastguard Worker break;
603*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat:
604*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
605*ec779b8eSAndroid Build Coastguard Worker "float %s = %f", item.mName, item.u.floatValue);
606*ec779b8eSAndroid Build Coastguard Worker break;
607*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble:
608*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
609*ec779b8eSAndroid Build Coastguard Worker "double %s = %f", item.mName, item.u.doubleValue);
610*ec779b8eSAndroid Build Coastguard Worker break;
611*ec779b8eSAndroid Build Coastguard Worker case kTypePointer:
612*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
613*ec779b8eSAndroid Build Coastguard Worker "void *%s = %p", item.mName, item.u.ptrValue);
614*ec779b8eSAndroid Build Coastguard Worker break;
615*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
616*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
617*ec779b8eSAndroid Build Coastguard Worker "string %s = \"%s\"",
618*ec779b8eSAndroid Build Coastguard Worker item.mName,
619*ec779b8eSAndroid Build Coastguard Worker item.u.stringValue->c_str());
620*ec779b8eSAndroid Build Coastguard Worker break;
621*ec779b8eSAndroid Build Coastguard Worker case kTypeObject:
622*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
623*ec779b8eSAndroid Build Coastguard Worker "RefBase *%s = %p", item.mName, item.u.refValue);
624*ec779b8eSAndroid Build Coastguard Worker break;
625*ec779b8eSAndroid Build Coastguard Worker case kTypeBuffer:
626*ec779b8eSAndroid Build Coastguard Worker {
627*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buffer = static_cast<ABuffer *>(item.u.refValue);
628*ec779b8eSAndroid Build Coastguard Worker
629*ec779b8eSAndroid Build Coastguard Worker if (buffer != NULL && buffer->data() != NULL && buffer->size() <= 64) {
630*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf("Buffer %s = {\n", item.mName);
631*ec779b8eSAndroid Build Coastguard Worker hexdump(buffer->data(), buffer->size(), indent + 4, &tmp);
632*ec779b8eSAndroid Build Coastguard Worker appendIndent(&tmp, indent + 2);
633*ec779b8eSAndroid Build Coastguard Worker tmp.append("}");
634*ec779b8eSAndroid Build Coastguard Worker } else {
635*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
636*ec779b8eSAndroid Build Coastguard Worker "Buffer *%s = %p", item.mName, buffer.get());
637*ec779b8eSAndroid Build Coastguard Worker }
638*ec779b8eSAndroid Build Coastguard Worker break;
639*ec779b8eSAndroid Build Coastguard Worker }
640*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
641*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
642*ec779b8eSAndroid Build Coastguard Worker "AMessage %s = %s",
643*ec779b8eSAndroid Build Coastguard Worker item.mName,
644*ec779b8eSAndroid Build Coastguard Worker static_cast<AMessage *>(
645*ec779b8eSAndroid Build Coastguard Worker item.u.refValue)->debugString(
646*ec779b8eSAndroid Build Coastguard Worker indent + strlen(item.mName) + 14).c_str());
647*ec779b8eSAndroid Build Coastguard Worker break;
648*ec779b8eSAndroid Build Coastguard Worker case kTypeRect:
649*ec779b8eSAndroid Build Coastguard Worker tmp = AStringPrintf(
650*ec779b8eSAndroid Build Coastguard Worker "Rect %s(%d, %d, %d, %d)",
651*ec779b8eSAndroid Build Coastguard Worker item.mName,
652*ec779b8eSAndroid Build Coastguard Worker item.u.rectValue.mLeft,
653*ec779b8eSAndroid Build Coastguard Worker item.u.rectValue.mTop,
654*ec779b8eSAndroid Build Coastguard Worker item.u.rectValue.mRight,
655*ec779b8eSAndroid Build Coastguard Worker item.u.rectValue.mBottom);
656*ec779b8eSAndroid Build Coastguard Worker break;
657*ec779b8eSAndroid Build Coastguard Worker default:
658*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
659*ec779b8eSAndroid Build Coastguard Worker }
660*ec779b8eSAndroid Build Coastguard Worker
661*ec779b8eSAndroid Build Coastguard Worker appendIndent(&s, indent);
662*ec779b8eSAndroid Build Coastguard Worker s.append(" ");
663*ec779b8eSAndroid Build Coastguard Worker s.append(tmp);
664*ec779b8eSAndroid Build Coastguard Worker s.append("\n");
665*ec779b8eSAndroid Build Coastguard Worker }
666*ec779b8eSAndroid Build Coastguard Worker
667*ec779b8eSAndroid Build Coastguard Worker appendIndent(&s, indent);
668*ec779b8eSAndroid Build Coastguard Worker s.append("}");
669*ec779b8eSAndroid Build Coastguard Worker
670*ec779b8eSAndroid Build Coastguard Worker return s;
671*ec779b8eSAndroid Build Coastguard Worker }
672*ec779b8eSAndroid Build Coastguard Worker
673*ec779b8eSAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
674*ec779b8eSAndroid Build Coastguard Worker // static
FromParcel(const Parcel & parcel,size_t maxNestingLevel)675*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel) {
676*ec779b8eSAndroid Build Coastguard Worker int32_t what = parcel.readInt32();
677*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage();
678*ec779b8eSAndroid Build Coastguard Worker msg->setWhat(what);
679*ec779b8eSAndroid Build Coastguard Worker
680*ec779b8eSAndroid Build Coastguard Worker size_t numItems = static_cast<size_t>(parcel.readInt32());
681*ec779b8eSAndroid Build Coastguard Worker if (numItems > kMaxNumItems) {
682*ec779b8eSAndroid Build Coastguard Worker ALOGE("Too large number of items clipped.");
683*ec779b8eSAndroid Build Coastguard Worker numItems = kMaxNumItems;
684*ec779b8eSAndroid Build Coastguard Worker }
685*ec779b8eSAndroid Build Coastguard Worker msg->mItems.resize(numItems);
686*ec779b8eSAndroid Build Coastguard Worker
687*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < msg->mItems.size(); ++i) {
688*ec779b8eSAndroid Build Coastguard Worker Item *item = &msg->mItems[i];
689*ec779b8eSAndroid Build Coastguard Worker
690*ec779b8eSAndroid Build Coastguard Worker const char *name = parcel.readCString();
691*ec779b8eSAndroid Build Coastguard Worker if (name == NULL) {
692*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed reading name for an item. Parsing aborted.");
693*ec779b8eSAndroid Build Coastguard Worker msg->mItems.resize(i);
694*ec779b8eSAndroid Build Coastguard Worker break;
695*ec779b8eSAndroid Build Coastguard Worker }
696*ec779b8eSAndroid Build Coastguard Worker
697*ec779b8eSAndroid Build Coastguard Worker item->mType = static_cast<Type>(parcel.readInt32());
698*ec779b8eSAndroid Build Coastguard Worker // setName() happens below so that we don't leak memory when parsing
699*ec779b8eSAndroid Build Coastguard Worker // is aborted in the middle.
700*ec779b8eSAndroid Build Coastguard Worker switch (item->mType) {
701*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
702*ec779b8eSAndroid Build Coastguard Worker {
703*ec779b8eSAndroid Build Coastguard Worker item->u.int32Value = parcel.readInt32();
704*ec779b8eSAndroid Build Coastguard Worker break;
705*ec779b8eSAndroid Build Coastguard Worker }
706*ec779b8eSAndroid Build Coastguard Worker
707*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
708*ec779b8eSAndroid Build Coastguard Worker {
709*ec779b8eSAndroid Build Coastguard Worker item->u.int64Value = parcel.readInt64();
710*ec779b8eSAndroid Build Coastguard Worker break;
711*ec779b8eSAndroid Build Coastguard Worker }
712*ec779b8eSAndroid Build Coastguard Worker
713*ec779b8eSAndroid Build Coastguard Worker case kTypeSize:
714*ec779b8eSAndroid Build Coastguard Worker {
715*ec779b8eSAndroid Build Coastguard Worker item->u.sizeValue = static_cast<size_t>(parcel.readInt32());
716*ec779b8eSAndroid Build Coastguard Worker break;
717*ec779b8eSAndroid Build Coastguard Worker }
718*ec779b8eSAndroid Build Coastguard Worker
719*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat:
720*ec779b8eSAndroid Build Coastguard Worker {
721*ec779b8eSAndroid Build Coastguard Worker item->u.floatValue = parcel.readFloat();
722*ec779b8eSAndroid Build Coastguard Worker break;
723*ec779b8eSAndroid Build Coastguard Worker }
724*ec779b8eSAndroid Build Coastguard Worker
725*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble:
726*ec779b8eSAndroid Build Coastguard Worker {
727*ec779b8eSAndroid Build Coastguard Worker item->u.doubleValue = parcel.readDouble();
728*ec779b8eSAndroid Build Coastguard Worker break;
729*ec779b8eSAndroid Build Coastguard Worker }
730*ec779b8eSAndroid Build Coastguard Worker
731*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
732*ec779b8eSAndroid Build Coastguard Worker {
733*ec779b8eSAndroid Build Coastguard Worker const char *stringValue = parcel.readCString();
734*ec779b8eSAndroid Build Coastguard Worker if (stringValue == NULL) {
735*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed reading string value from a parcel. "
736*ec779b8eSAndroid Build Coastguard Worker "Parsing aborted.");
737*ec779b8eSAndroid Build Coastguard Worker msg->mItems.resize(i);
738*ec779b8eSAndroid Build Coastguard Worker continue;
739*ec779b8eSAndroid Build Coastguard Worker // The loop will terminate subsequently.
740*ec779b8eSAndroid Build Coastguard Worker } else {
741*ec779b8eSAndroid Build Coastguard Worker item->u.stringValue = new AString(stringValue);
742*ec779b8eSAndroid Build Coastguard Worker }
743*ec779b8eSAndroid Build Coastguard Worker break;
744*ec779b8eSAndroid Build Coastguard Worker }
745*ec779b8eSAndroid Build Coastguard Worker
746*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
747*ec779b8eSAndroid Build Coastguard Worker {
748*ec779b8eSAndroid Build Coastguard Worker if (maxNestingLevel == 0) {
749*ec779b8eSAndroid Build Coastguard Worker ALOGE("Too many levels of AMessage nesting.");
750*ec779b8eSAndroid Build Coastguard Worker return NULL;
751*ec779b8eSAndroid Build Coastguard Worker }
752*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> subMsg = AMessage::FromParcel(
753*ec779b8eSAndroid Build Coastguard Worker parcel,
754*ec779b8eSAndroid Build Coastguard Worker maxNestingLevel - 1);
755*ec779b8eSAndroid Build Coastguard Worker if (subMsg == NULL) {
756*ec779b8eSAndroid Build Coastguard Worker // This condition will be triggered when there exists an
757*ec779b8eSAndroid Build Coastguard Worker // object that cannot cross process boundaries or when the
758*ec779b8eSAndroid Build Coastguard Worker // level of nested AMessage is too deep.
759*ec779b8eSAndroid Build Coastguard Worker return NULL;
760*ec779b8eSAndroid Build Coastguard Worker }
761*ec779b8eSAndroid Build Coastguard Worker subMsg->incStrong(msg.get());
762*ec779b8eSAndroid Build Coastguard Worker
763*ec779b8eSAndroid Build Coastguard Worker item->u.refValue = subMsg.get();
764*ec779b8eSAndroid Build Coastguard Worker break;
765*ec779b8eSAndroid Build Coastguard Worker }
766*ec779b8eSAndroid Build Coastguard Worker
767*ec779b8eSAndroid Build Coastguard Worker default:
768*ec779b8eSAndroid Build Coastguard Worker {
769*ec779b8eSAndroid Build Coastguard Worker ALOGE("This type of object cannot cross process boundaries.");
770*ec779b8eSAndroid Build Coastguard Worker return NULL;
771*ec779b8eSAndroid Build Coastguard Worker }
772*ec779b8eSAndroid Build Coastguard Worker }
773*ec779b8eSAndroid Build Coastguard Worker
774*ec779b8eSAndroid Build Coastguard Worker item->setName(name, strlen(name));
775*ec779b8eSAndroid Build Coastguard Worker }
776*ec779b8eSAndroid Build Coastguard Worker
777*ec779b8eSAndroid Build Coastguard Worker return msg;
778*ec779b8eSAndroid Build Coastguard Worker }
779*ec779b8eSAndroid Build Coastguard Worker
writeToParcel(Parcel * parcel) const780*ec779b8eSAndroid Build Coastguard Worker void AMessage::writeToParcel(Parcel *parcel) const {
781*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt32(static_cast<int32_t>(mWhat));
782*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt32(static_cast<int32_t>(mItems.size()));
783*ec779b8eSAndroid Build Coastguard Worker
784*ec779b8eSAndroid Build Coastguard Worker for (const Item &item : mItems) {
785*ec779b8eSAndroid Build Coastguard Worker parcel->writeCString(item.mName);
786*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt32(static_cast<int32_t>(item.mType));
787*ec779b8eSAndroid Build Coastguard Worker
788*ec779b8eSAndroid Build Coastguard Worker switch (item.mType) {
789*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
790*ec779b8eSAndroid Build Coastguard Worker {
791*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt32(item.u.int32Value);
792*ec779b8eSAndroid Build Coastguard Worker break;
793*ec779b8eSAndroid Build Coastguard Worker }
794*ec779b8eSAndroid Build Coastguard Worker
795*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
796*ec779b8eSAndroid Build Coastguard Worker {
797*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt64(item.u.int64Value);
798*ec779b8eSAndroid Build Coastguard Worker break;
799*ec779b8eSAndroid Build Coastguard Worker }
800*ec779b8eSAndroid Build Coastguard Worker
801*ec779b8eSAndroid Build Coastguard Worker case kTypeSize:
802*ec779b8eSAndroid Build Coastguard Worker {
803*ec779b8eSAndroid Build Coastguard Worker parcel->writeInt32(static_cast<int32_t>(item.u.sizeValue));
804*ec779b8eSAndroid Build Coastguard Worker break;
805*ec779b8eSAndroid Build Coastguard Worker }
806*ec779b8eSAndroid Build Coastguard Worker
807*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat:
808*ec779b8eSAndroid Build Coastguard Worker {
809*ec779b8eSAndroid Build Coastguard Worker parcel->writeFloat(item.u.floatValue);
810*ec779b8eSAndroid Build Coastguard Worker break;
811*ec779b8eSAndroid Build Coastguard Worker }
812*ec779b8eSAndroid Build Coastguard Worker
813*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble:
814*ec779b8eSAndroid Build Coastguard Worker {
815*ec779b8eSAndroid Build Coastguard Worker parcel->writeDouble(item.u.doubleValue);
816*ec779b8eSAndroid Build Coastguard Worker break;
817*ec779b8eSAndroid Build Coastguard Worker }
818*ec779b8eSAndroid Build Coastguard Worker
819*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
820*ec779b8eSAndroid Build Coastguard Worker {
821*ec779b8eSAndroid Build Coastguard Worker parcel->writeCString(item.u.stringValue->c_str());
822*ec779b8eSAndroid Build Coastguard Worker break;
823*ec779b8eSAndroid Build Coastguard Worker }
824*ec779b8eSAndroid Build Coastguard Worker
825*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
826*ec779b8eSAndroid Build Coastguard Worker {
827*ec779b8eSAndroid Build Coastguard Worker static_cast<AMessage *>(item.u.refValue)->writeToParcel(parcel);
828*ec779b8eSAndroid Build Coastguard Worker break;
829*ec779b8eSAndroid Build Coastguard Worker }
830*ec779b8eSAndroid Build Coastguard Worker
831*ec779b8eSAndroid Build Coastguard Worker default:
832*ec779b8eSAndroid Build Coastguard Worker {
833*ec779b8eSAndroid Build Coastguard Worker ALOGE("This type of object cannot cross process boundaries.");
834*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
835*ec779b8eSAndroid Build Coastguard Worker }
836*ec779b8eSAndroid Build Coastguard Worker }
837*ec779b8eSAndroid Build Coastguard Worker }
838*ec779b8eSAndroid Build Coastguard Worker }
839*ec779b8eSAndroid Build Coastguard Worker #endif // defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
840*ec779b8eSAndroid Build Coastguard Worker
changesFrom(const sp<const AMessage> & other,bool deep) const841*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> AMessage::changesFrom(const sp<const AMessage> &other, bool deep) const {
842*ec779b8eSAndroid Build Coastguard Worker if (other == NULL) {
843*ec779b8eSAndroid Build Coastguard Worker return const_cast<AMessage*>(this);
844*ec779b8eSAndroid Build Coastguard Worker }
845*ec779b8eSAndroid Build Coastguard Worker
846*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> diff = new AMessage;
847*ec779b8eSAndroid Build Coastguard Worker if (mWhat != other->mWhat) {
848*ec779b8eSAndroid Build Coastguard Worker diff->setWhat(mWhat);
849*ec779b8eSAndroid Build Coastguard Worker }
850*ec779b8eSAndroid Build Coastguard Worker if (mHandler != other->mHandler) {
851*ec779b8eSAndroid Build Coastguard Worker diff->setTarget(mHandler.promote());
852*ec779b8eSAndroid Build Coastguard Worker }
853*ec779b8eSAndroid Build Coastguard Worker
854*ec779b8eSAndroid Build Coastguard Worker for (const Item &item : mItems) {
855*ec779b8eSAndroid Build Coastguard Worker const Item *oitem = other->findItem(item.mName, item.mType);
856*ec779b8eSAndroid Build Coastguard Worker switch (item.mType) {
857*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32:
858*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.int32Value != oitem->u.int32Value) {
859*ec779b8eSAndroid Build Coastguard Worker diff->setInt32(item.mName, item.u.int32Value);
860*ec779b8eSAndroid Build Coastguard Worker }
861*ec779b8eSAndroid Build Coastguard Worker break;
862*ec779b8eSAndroid Build Coastguard Worker
863*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64:
864*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.int64Value != oitem->u.int64Value) {
865*ec779b8eSAndroid Build Coastguard Worker diff->setInt64(item.mName, item.u.int64Value);
866*ec779b8eSAndroid Build Coastguard Worker }
867*ec779b8eSAndroid Build Coastguard Worker break;
868*ec779b8eSAndroid Build Coastguard Worker
869*ec779b8eSAndroid Build Coastguard Worker case kTypeSize:
870*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.sizeValue != oitem->u.sizeValue) {
871*ec779b8eSAndroid Build Coastguard Worker diff->setSize(item.mName, item.u.sizeValue);
872*ec779b8eSAndroid Build Coastguard Worker }
873*ec779b8eSAndroid Build Coastguard Worker break;
874*ec779b8eSAndroid Build Coastguard Worker
875*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat:
876*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.floatValue != oitem->u.floatValue) {
877*ec779b8eSAndroid Build Coastguard Worker diff->setFloat(item.mName, item.u.sizeValue);
878*ec779b8eSAndroid Build Coastguard Worker }
879*ec779b8eSAndroid Build Coastguard Worker break;
880*ec779b8eSAndroid Build Coastguard Worker
881*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble:
882*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.doubleValue != oitem->u.doubleValue) {
883*ec779b8eSAndroid Build Coastguard Worker diff->setDouble(item.mName, item.u.sizeValue);
884*ec779b8eSAndroid Build Coastguard Worker }
885*ec779b8eSAndroid Build Coastguard Worker break;
886*ec779b8eSAndroid Build Coastguard Worker
887*ec779b8eSAndroid Build Coastguard Worker case kTypeString:
888*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || *item.u.stringValue != *oitem->u.stringValue) {
889*ec779b8eSAndroid Build Coastguard Worker diff->setString(item.mName, *item.u.stringValue);
890*ec779b8eSAndroid Build Coastguard Worker }
891*ec779b8eSAndroid Build Coastguard Worker break;
892*ec779b8eSAndroid Build Coastguard Worker
893*ec779b8eSAndroid Build Coastguard Worker case kTypeRect:
894*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || memcmp(&item.u.rectValue, &oitem->u.rectValue, sizeof(Rect))) {
895*ec779b8eSAndroid Build Coastguard Worker diff->setRect(
896*ec779b8eSAndroid Build Coastguard Worker item.mName, item.u.rectValue.mLeft, item.u.rectValue.mTop,
897*ec779b8eSAndroid Build Coastguard Worker item.u.rectValue.mRight, item.u.rectValue.mBottom);
898*ec779b8eSAndroid Build Coastguard Worker }
899*ec779b8eSAndroid Build Coastguard Worker break;
900*ec779b8eSAndroid Build Coastguard Worker
901*ec779b8eSAndroid Build Coastguard Worker case kTypePointer:
902*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.ptrValue != oitem->u.ptrValue) {
903*ec779b8eSAndroid Build Coastguard Worker diff->setPointer(item.mName, item.u.ptrValue);
904*ec779b8eSAndroid Build Coastguard Worker }
905*ec779b8eSAndroid Build Coastguard Worker break;
906*ec779b8eSAndroid Build Coastguard Worker
907*ec779b8eSAndroid Build Coastguard Worker case kTypeBuffer:
908*ec779b8eSAndroid Build Coastguard Worker {
909*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> myBuf = static_cast<ABuffer *>(item.u.refValue);
910*ec779b8eSAndroid Build Coastguard Worker if (myBuf == NULL) {
911*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || oitem->u.refValue != NULL) {
912*ec779b8eSAndroid Build Coastguard Worker diff->setBuffer(item.mName, NULL);
913*ec779b8eSAndroid Build Coastguard Worker }
914*ec779b8eSAndroid Build Coastguard Worker break;
915*ec779b8eSAndroid Build Coastguard Worker }
916*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> oBuf = oitem == NULL ? NULL : static_cast<ABuffer *>(oitem->u.refValue);
917*ec779b8eSAndroid Build Coastguard Worker if (oBuf == NULL
918*ec779b8eSAndroid Build Coastguard Worker || myBuf->size() != oBuf->size()
919*ec779b8eSAndroid Build Coastguard Worker || (!myBuf->data() ^ !oBuf->data()) // data nullness differs
920*ec779b8eSAndroid Build Coastguard Worker || (myBuf->data() && memcmp(myBuf->data(), oBuf->data(), myBuf->size()))) {
921*ec779b8eSAndroid Build Coastguard Worker diff->setBuffer(item.mName, myBuf);
922*ec779b8eSAndroid Build Coastguard Worker }
923*ec779b8eSAndroid Build Coastguard Worker break;
924*ec779b8eSAndroid Build Coastguard Worker }
925*ec779b8eSAndroid Build Coastguard Worker
926*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage:
927*ec779b8eSAndroid Build Coastguard Worker {
928*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> myMsg = static_cast<AMessage *>(item.u.refValue);
929*ec779b8eSAndroid Build Coastguard Worker if (myMsg == NULL) {
930*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || oitem->u.refValue != NULL) {
931*ec779b8eSAndroid Build Coastguard Worker diff->setMessage(item.mName, NULL);
932*ec779b8eSAndroid Build Coastguard Worker }
933*ec779b8eSAndroid Build Coastguard Worker break;
934*ec779b8eSAndroid Build Coastguard Worker }
935*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> oMsg =
936*ec779b8eSAndroid Build Coastguard Worker oitem == NULL ? NULL : static_cast<AMessage *>(oitem->u.refValue);
937*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> changes = myMsg->changesFrom(oMsg, deep);
938*ec779b8eSAndroid Build Coastguard Worker if (changes->countEntries()) {
939*ec779b8eSAndroid Build Coastguard Worker diff->setMessage(item.mName, deep ? changes : myMsg);
940*ec779b8eSAndroid Build Coastguard Worker }
941*ec779b8eSAndroid Build Coastguard Worker break;
942*ec779b8eSAndroid Build Coastguard Worker }
943*ec779b8eSAndroid Build Coastguard Worker
944*ec779b8eSAndroid Build Coastguard Worker case kTypeObject:
945*ec779b8eSAndroid Build Coastguard Worker if (oitem == NULL || item.u.refValue != oitem->u.refValue) {
946*ec779b8eSAndroid Build Coastguard Worker diff->setObject(item.mName, item.u.refValue);
947*ec779b8eSAndroid Build Coastguard Worker }
948*ec779b8eSAndroid Build Coastguard Worker break;
949*ec779b8eSAndroid Build Coastguard Worker
950*ec779b8eSAndroid Build Coastguard Worker default:
951*ec779b8eSAndroid Build Coastguard Worker {
952*ec779b8eSAndroid Build Coastguard Worker ALOGE("Unknown type %d", item.mType);
953*ec779b8eSAndroid Build Coastguard Worker TRESPASS();
954*ec779b8eSAndroid Build Coastguard Worker }
955*ec779b8eSAndroid Build Coastguard Worker }
956*ec779b8eSAndroid Build Coastguard Worker }
957*ec779b8eSAndroid Build Coastguard Worker return diff;
958*ec779b8eSAndroid Build Coastguard Worker }
959*ec779b8eSAndroid Build Coastguard Worker
countEntries() const960*ec779b8eSAndroid Build Coastguard Worker size_t AMessage::countEntries() const {
961*ec779b8eSAndroid Build Coastguard Worker return mItems.size();
962*ec779b8eSAndroid Build Coastguard Worker }
963*ec779b8eSAndroid Build Coastguard Worker
964*ec779b8eSAndroid Build Coastguard Worker /* static */
maxAllowedEntries()965*ec779b8eSAndroid Build Coastguard Worker size_t AMessage::maxAllowedEntries() {
966*ec779b8eSAndroid Build Coastguard Worker return kMaxNumItems;
967*ec779b8eSAndroid Build Coastguard Worker }
968*ec779b8eSAndroid Build Coastguard Worker
getEntryNameAt(size_t index,Type * type) const969*ec779b8eSAndroid Build Coastguard Worker const char *AMessage::getEntryNameAt(size_t index, Type *type) const {
970*ec779b8eSAndroid Build Coastguard Worker if (index >= mItems.size()) {
971*ec779b8eSAndroid Build Coastguard Worker *type = kTypeInt32;
972*ec779b8eSAndroid Build Coastguard Worker
973*ec779b8eSAndroid Build Coastguard Worker return NULL;
974*ec779b8eSAndroid Build Coastguard Worker }
975*ec779b8eSAndroid Build Coastguard Worker
976*ec779b8eSAndroid Build Coastguard Worker *type = mItems[index].mType;
977*ec779b8eSAndroid Build Coastguard Worker
978*ec779b8eSAndroid Build Coastguard Worker return mItems[index].mName;
979*ec779b8eSAndroid Build Coastguard Worker }
980*ec779b8eSAndroid Build Coastguard Worker
getEntryAt(size_t index) const981*ec779b8eSAndroid Build Coastguard Worker AMessage::ItemData AMessage::getEntryAt(size_t index) const {
982*ec779b8eSAndroid Build Coastguard Worker ItemData it;
983*ec779b8eSAndroid Build Coastguard Worker if (index < mItems.size()) {
984*ec779b8eSAndroid Build Coastguard Worker switch (mItems[index].mType) {
985*ec779b8eSAndroid Build Coastguard Worker case kTypeInt32: it.set(mItems[index].u.int32Value); break;
986*ec779b8eSAndroid Build Coastguard Worker case kTypeInt64: it.set(mItems[index].u.int64Value); break;
987*ec779b8eSAndroid Build Coastguard Worker case kTypeSize: it.set(mItems[index].u.sizeValue); break;
988*ec779b8eSAndroid Build Coastguard Worker case kTypeFloat: it.set(mItems[index].u.floatValue); break;
989*ec779b8eSAndroid Build Coastguard Worker case kTypeDouble: it.set(mItems[index].u.doubleValue); break;
990*ec779b8eSAndroid Build Coastguard Worker case kTypePointer: it.set(mItems[index].u.ptrValue); break;
991*ec779b8eSAndroid Build Coastguard Worker case kTypeRect: it.set(mItems[index].u.rectValue); break;
992*ec779b8eSAndroid Build Coastguard Worker case kTypeString: it.set(*mItems[index].u.stringValue); break;
993*ec779b8eSAndroid Build Coastguard Worker case kTypeObject: {
994*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> obj = mItems[index].u.refValue;
995*ec779b8eSAndroid Build Coastguard Worker it.set(obj);
996*ec779b8eSAndroid Build Coastguard Worker break;
997*ec779b8eSAndroid Build Coastguard Worker }
998*ec779b8eSAndroid Build Coastguard Worker case kTypeMessage: {
999*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = static_cast<AMessage *>(mItems[index].u.refValue);
1000*ec779b8eSAndroid Build Coastguard Worker it.set(msg);
1001*ec779b8eSAndroid Build Coastguard Worker break;
1002*ec779b8eSAndroid Build Coastguard Worker }
1003*ec779b8eSAndroid Build Coastguard Worker case kTypeBuffer: {
1004*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> buf = static_cast<ABuffer *>(mItems[index].u.refValue);
1005*ec779b8eSAndroid Build Coastguard Worker it.set(buf);
1006*ec779b8eSAndroid Build Coastguard Worker break;
1007*ec779b8eSAndroid Build Coastguard Worker }
1008*ec779b8eSAndroid Build Coastguard Worker default:
1009*ec779b8eSAndroid Build Coastguard Worker break;
1010*ec779b8eSAndroid Build Coastguard Worker }
1011*ec779b8eSAndroid Build Coastguard Worker }
1012*ec779b8eSAndroid Build Coastguard Worker return it;
1013*ec779b8eSAndroid Build Coastguard Worker }
1014*ec779b8eSAndroid Build Coastguard Worker
setEntryNameAt(size_t index,const char * name)1015*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::setEntryNameAt(size_t index, const char *name) {
1016*ec779b8eSAndroid Build Coastguard Worker if (index >= mItems.size()) {
1017*ec779b8eSAndroid Build Coastguard Worker return BAD_INDEX;
1018*ec779b8eSAndroid Build Coastguard Worker }
1019*ec779b8eSAndroid Build Coastguard Worker if (name == nullptr) {
1020*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
1021*ec779b8eSAndroid Build Coastguard Worker }
1022*ec779b8eSAndroid Build Coastguard Worker if (!strcmp(name, mItems[index].mName)) {
1023*ec779b8eSAndroid Build Coastguard Worker return OK; // name has not changed
1024*ec779b8eSAndroid Build Coastguard Worker }
1025*ec779b8eSAndroid Build Coastguard Worker size_t len = strlen(name);
1026*ec779b8eSAndroid Build Coastguard Worker if (findItemIndex(name, len) < mItems.size()) {
1027*ec779b8eSAndroid Build Coastguard Worker return ALREADY_EXISTS;
1028*ec779b8eSAndroid Build Coastguard Worker }
1029*ec779b8eSAndroid Build Coastguard Worker delete[] mItems[index].mName;
1030*ec779b8eSAndroid Build Coastguard Worker mItems[index].mName = nullptr;
1031*ec779b8eSAndroid Build Coastguard Worker mItems[index].setName(name, len);
1032*ec779b8eSAndroid Build Coastguard Worker return OK;
1033*ec779b8eSAndroid Build Coastguard Worker }
1034*ec779b8eSAndroid Build Coastguard Worker
setEntryAt(size_t index,const ItemData & item)1035*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::setEntryAt(size_t index, const ItemData &item) {
1036*ec779b8eSAndroid Build Coastguard Worker AString stringValue;
1037*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> refValue;
1038*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msgValue;
1039*ec779b8eSAndroid Build Coastguard Worker sp<ABuffer> bufValue;
1040*ec779b8eSAndroid Build Coastguard Worker
1041*ec779b8eSAndroid Build Coastguard Worker if (index >= mItems.size()) {
1042*ec779b8eSAndroid Build Coastguard Worker return BAD_INDEX;
1043*ec779b8eSAndroid Build Coastguard Worker }
1044*ec779b8eSAndroid Build Coastguard Worker if (!item.used()) {
1045*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
1046*ec779b8eSAndroid Build Coastguard Worker }
1047*ec779b8eSAndroid Build Coastguard Worker Item *dst = &mItems[index];
1048*ec779b8eSAndroid Build Coastguard Worker freeItemValue(dst);
1049*ec779b8eSAndroid Build Coastguard Worker
1050*ec779b8eSAndroid Build Coastguard Worker // some values can be directly set with the getter. others need items to be allocated
1051*ec779b8eSAndroid Build Coastguard Worker if (item.find(&dst->u.int32Value)) {
1052*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeInt32;
1053*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.int64Value)) {
1054*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeInt64;
1055*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.sizeValue)) {
1056*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeSize;
1057*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.floatValue)) {
1058*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeFloat;
1059*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.doubleValue)) {
1060*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeDouble;
1061*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.ptrValue)) {
1062*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypePointer;
1063*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&dst->u.rectValue)) {
1064*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeRect;
1065*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&stringValue)) {
1066*ec779b8eSAndroid Build Coastguard Worker dst->u.stringValue = new AString(stringValue);
1067*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeString;
1068*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&refValue)) {
1069*ec779b8eSAndroid Build Coastguard Worker if (refValue != NULL) { refValue->incStrong(this); }
1070*ec779b8eSAndroid Build Coastguard Worker dst->u.refValue = refValue.get();
1071*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeObject;
1072*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&msgValue)) {
1073*ec779b8eSAndroid Build Coastguard Worker if (msgValue != NULL) { msgValue->incStrong(this); }
1074*ec779b8eSAndroid Build Coastguard Worker dst->u.refValue = msgValue.get();
1075*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeMessage;
1076*ec779b8eSAndroid Build Coastguard Worker } else if (item.find(&bufValue)) {
1077*ec779b8eSAndroid Build Coastguard Worker if (bufValue != NULL) { bufValue->incStrong(this); }
1078*ec779b8eSAndroid Build Coastguard Worker dst->u.refValue = bufValue.get();
1079*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeBuffer;
1080*ec779b8eSAndroid Build Coastguard Worker } else {
1081*ec779b8eSAndroid Build Coastguard Worker // unsupported item - we should not be here.
1082*ec779b8eSAndroid Build Coastguard Worker dst->mType = kTypeInt32;
1083*ec779b8eSAndroid Build Coastguard Worker dst->u.int32Value = 0xDEADDEAD;
1084*ec779b8eSAndroid Build Coastguard Worker return BAD_TYPE;
1085*ec779b8eSAndroid Build Coastguard Worker }
1086*ec779b8eSAndroid Build Coastguard Worker return OK;
1087*ec779b8eSAndroid Build Coastguard Worker }
1088*ec779b8eSAndroid Build Coastguard Worker
removeEntryAt(size_t index)1089*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::removeEntryAt(size_t index) {
1090*ec779b8eSAndroid Build Coastguard Worker if (index >= mItems.size()) {
1091*ec779b8eSAndroid Build Coastguard Worker return BAD_INDEX;
1092*ec779b8eSAndroid Build Coastguard Worker }
1093*ec779b8eSAndroid Build Coastguard Worker // delete entry data and objects
1094*ec779b8eSAndroid Build Coastguard Worker delete[] mItems[index].mName;
1095*ec779b8eSAndroid Build Coastguard Worker mItems[index].mName = nullptr;
1096*ec779b8eSAndroid Build Coastguard Worker freeItemValue(&mItems[index]);
1097*ec779b8eSAndroid Build Coastguard Worker
1098*ec779b8eSAndroid Build Coastguard Worker // swap entry with last entry and clear last entry's data
1099*ec779b8eSAndroid Build Coastguard Worker size_t lastIndex = mItems.size() - 1;
1100*ec779b8eSAndroid Build Coastguard Worker if (index < lastIndex) {
1101*ec779b8eSAndroid Build Coastguard Worker mItems[index] = mItems[lastIndex];
1102*ec779b8eSAndroid Build Coastguard Worker mItems[lastIndex].mName = nullptr;
1103*ec779b8eSAndroid Build Coastguard Worker mItems[lastIndex].mType = kTypeInt32;
1104*ec779b8eSAndroid Build Coastguard Worker }
1105*ec779b8eSAndroid Build Coastguard Worker mItems.pop_back();
1106*ec779b8eSAndroid Build Coastguard Worker return OK;
1107*ec779b8eSAndroid Build Coastguard Worker }
1108*ec779b8eSAndroid Build Coastguard Worker
removeEntryByName(const char * name)1109*ec779b8eSAndroid Build Coastguard Worker status_t AMessage::removeEntryByName(const char *name) {
1110*ec779b8eSAndroid Build Coastguard Worker if (name == nullptr) {
1111*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
1112*ec779b8eSAndroid Build Coastguard Worker }
1113*ec779b8eSAndroid Build Coastguard Worker size_t index = findEntryByName(name);
1114*ec779b8eSAndroid Build Coastguard Worker if (index >= mItems.size()) {
1115*ec779b8eSAndroid Build Coastguard Worker return BAD_INDEX;
1116*ec779b8eSAndroid Build Coastguard Worker }
1117*ec779b8eSAndroid Build Coastguard Worker return removeEntryAt(index);
1118*ec779b8eSAndroid Build Coastguard Worker }
1119*ec779b8eSAndroid Build Coastguard Worker
setItem(const char * name,const ItemData & item)1120*ec779b8eSAndroid Build Coastguard Worker void AMessage::setItem(const char *name, const ItemData &item) {
1121*ec779b8eSAndroid Build Coastguard Worker if (item.used()) {
1122*ec779b8eSAndroid Build Coastguard Worker Item *it = allocateItem(name);
1123*ec779b8eSAndroid Build Coastguard Worker if (it != nullptr) {
1124*ec779b8eSAndroid Build Coastguard Worker setEntryAt(it - &mItems[0], item);
1125*ec779b8eSAndroid Build Coastguard Worker }
1126*ec779b8eSAndroid Build Coastguard Worker }
1127*ec779b8eSAndroid Build Coastguard Worker }
1128*ec779b8eSAndroid Build Coastguard Worker
findItem(const char * name) const1129*ec779b8eSAndroid Build Coastguard Worker AMessage::ItemData AMessage::findItem(const char *name) const {
1130*ec779b8eSAndroid Build Coastguard Worker return getEntryAt(findEntryByName(name));
1131*ec779b8eSAndroid Build Coastguard Worker }
1132*ec779b8eSAndroid Build Coastguard Worker
extend(const sp<AMessage> & other)1133*ec779b8eSAndroid Build Coastguard Worker void AMessage::extend(const sp<AMessage> &other) {
1134*ec779b8eSAndroid Build Coastguard Worker // ignore null messages
1135*ec779b8eSAndroid Build Coastguard Worker if (other == nullptr) {
1136*ec779b8eSAndroid Build Coastguard Worker return;
1137*ec779b8eSAndroid Build Coastguard Worker }
1138*ec779b8eSAndroid Build Coastguard Worker
1139*ec779b8eSAndroid Build Coastguard Worker for (size_t ix = 0; ix < other->mItems.size(); ++ix) {
1140*ec779b8eSAndroid Build Coastguard Worker Item *it = allocateItem(other->mItems[ix].mName);
1141*ec779b8eSAndroid Build Coastguard Worker if (it != nullptr) {
1142*ec779b8eSAndroid Build Coastguard Worker ItemData data = other->getEntryAt(ix);
1143*ec779b8eSAndroid Build Coastguard Worker setEntryAt(it - &mItems[0], data);
1144*ec779b8eSAndroid Build Coastguard Worker }
1145*ec779b8eSAndroid Build Coastguard Worker }
1146*ec779b8eSAndroid Build Coastguard Worker }
1147*ec779b8eSAndroid Build Coastguard Worker
findEntryByName(const char * name) const1148*ec779b8eSAndroid Build Coastguard Worker size_t AMessage::findEntryByName(const char *name) const {
1149*ec779b8eSAndroid Build Coastguard Worker return name == nullptr ? countEntries() : findItemIndex(name, strlen(name));
1150*ec779b8eSAndroid Build Coastguard Worker }
1151*ec779b8eSAndroid Build Coastguard Worker
1152*ec779b8eSAndroid Build Coastguard Worker } // namespace android
1153