• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2005 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "Parcel"
18 //#define LOG_NDEBUG 0
19 
20 #include <binder/Parcel.h>
21 
22 #include <binder/Binder.h>
23 #include <binder/BpBinder.h>
24 #include <utils/Debug.h>
25 #include <binder/ProcessState.h>
26 #include <utils/Log.h>
27 #include <utils/String8.h>
28 #include <utils/String16.h>
29 #include <utils/TextOutput.h>
30 #include <utils/misc.h>
31 
32 #include <private/binder/binder_module.h>
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdint.h>
37 
38 #ifndef INT32_MAX
39 #define INT32_MAX ((int32_t)(2147483647))
40 #endif
41 
42 #define LOG_REFS(...)
43 //#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
44 
45 // ---------------------------------------------------------------------------
46 
47 #define PAD_SIZE(s) (((s)+3)&~3)
48 
49 // XXX This can be made public if we want to provide
50 // support for typed data.
51 struct small_flat_data
52 {
53     uint32_t type;
54     uint32_t data;
55 };
56 
57 namespace android {
58 
acquire_object(const sp<ProcessState> & proc,const flat_binder_object & obj,const void * who)59 void acquire_object(const sp<ProcessState>& proc,
60     const flat_binder_object& obj, const void* who)
61 {
62     switch (obj.type) {
63         case BINDER_TYPE_BINDER:
64             if (obj.binder) {
65                 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
66                 static_cast<IBinder*>(obj.cookie)->incStrong(who);
67             }
68             return;
69         case BINDER_TYPE_WEAK_BINDER:
70             if (obj.binder)
71                 static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
72             return;
73         case BINDER_TYPE_HANDLE: {
74             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
75             if (b != NULL) {
76                 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
77                 b->incStrong(who);
78             }
79             return;
80         }
81         case BINDER_TYPE_WEAK_HANDLE: {
82             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
83             if (b != NULL) b.get_refs()->incWeak(who);
84             return;
85         }
86         case BINDER_TYPE_FD: {
87             // intentionally blank -- nothing to do to acquire this, but we do
88             // recognize it as a legitimate object type.
89             return;
90         }
91     }
92 
93     LOGD("Invalid object type 0x%08lx", obj.type);
94 }
95 
release_object(const sp<ProcessState> & proc,const flat_binder_object & obj,const void * who)96 void release_object(const sp<ProcessState>& proc,
97     const flat_binder_object& obj, const void* who)
98 {
99     switch (obj.type) {
100         case BINDER_TYPE_BINDER:
101             if (obj.binder) {
102                 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
103                 static_cast<IBinder*>(obj.cookie)->decStrong(who);
104             }
105             return;
106         case BINDER_TYPE_WEAK_BINDER:
107             if (obj.binder)
108                 static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
109             return;
110         case BINDER_TYPE_HANDLE: {
111             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
112             if (b != NULL) {
113                 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
114                 b->decStrong(who);
115             }
116             return;
117         }
118         case BINDER_TYPE_WEAK_HANDLE: {
119             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
120             if (b != NULL) b.get_refs()->decWeak(who);
121             return;
122         }
123         case BINDER_TYPE_FD: {
124             if (obj.cookie != (void*)0) close(obj.handle);
125             return;
126         }
127     }
128 
129     LOGE("Invalid object type 0x%08lx", obj.type);
130 }
131 
finish_flatten_binder(const sp<IBinder> & binder,const flat_binder_object & flat,Parcel * out)132 inline static status_t finish_flatten_binder(
133     const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
134 {
135     return out->writeObject(flat, false);
136 }
137 
flatten_binder(const sp<ProcessState> & proc,const sp<IBinder> & binder,Parcel * out)138 status_t flatten_binder(const sp<ProcessState>& proc,
139     const sp<IBinder>& binder, Parcel* out)
140 {
141     flat_binder_object obj;
142 
143     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
144     if (binder != NULL) {
145         IBinder *local = binder->localBinder();
146         if (!local) {
147             BpBinder *proxy = binder->remoteBinder();
148             if (proxy == NULL) {
149                 LOGE("null proxy");
150             }
151             const int32_t handle = proxy ? proxy->handle() : 0;
152             obj.type = BINDER_TYPE_HANDLE;
153             obj.handle = handle;
154             obj.cookie = NULL;
155         } else {
156             obj.type = BINDER_TYPE_BINDER;
157             obj.binder = local->getWeakRefs();
158             obj.cookie = local;
159         }
160     } else {
161         obj.type = BINDER_TYPE_BINDER;
162         obj.binder = NULL;
163         obj.cookie = NULL;
164     }
165 
166     return finish_flatten_binder(binder, obj, out);
167 }
168 
flatten_binder(const sp<ProcessState> & proc,const wp<IBinder> & binder,Parcel * out)169 status_t flatten_binder(const sp<ProcessState>& proc,
170     const wp<IBinder>& binder, Parcel* out)
171 {
172     flat_binder_object obj;
173 
174     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
175     if (binder != NULL) {
176         sp<IBinder> real = binder.promote();
177         if (real != NULL) {
178             IBinder *local = real->localBinder();
179             if (!local) {
180                 BpBinder *proxy = real->remoteBinder();
181                 if (proxy == NULL) {
182                     LOGE("null proxy");
183                 }
184                 const int32_t handle = proxy ? proxy->handle() : 0;
185                 obj.type = BINDER_TYPE_WEAK_HANDLE;
186                 obj.handle = handle;
187                 obj.cookie = NULL;
188             } else {
189                 obj.type = BINDER_TYPE_WEAK_BINDER;
190                 obj.binder = binder.get_refs();
191                 obj.cookie = binder.unsafe_get();
192             }
193             return finish_flatten_binder(real, obj, out);
194         }
195 
196         // XXX How to deal?  In order to flatten the given binder,
197         // we need to probe it for information, which requires a primary
198         // reference...  but we don't have one.
199         //
200         // The OpenBinder implementation uses a dynamic_cast<> here,
201         // but we can't do that with the different reference counting
202         // implementation we are using.
203         LOGE("Unable to unflatten Binder weak reference!");
204         obj.type = BINDER_TYPE_BINDER;
205         obj.binder = NULL;
206         obj.cookie = NULL;
207         return finish_flatten_binder(NULL, obj, out);
208 
209     } else {
210         obj.type = BINDER_TYPE_BINDER;
211         obj.binder = NULL;
212         obj.cookie = NULL;
213         return finish_flatten_binder(NULL, obj, out);
214     }
215 }
216 
finish_unflatten_binder(BpBinder * proxy,const flat_binder_object & flat,const Parcel & in)217 inline static status_t finish_unflatten_binder(
218     BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
219 {
220     return NO_ERROR;
221 }
222 
unflatten_binder(const sp<ProcessState> & proc,const Parcel & in,sp<IBinder> * out)223 status_t unflatten_binder(const sp<ProcessState>& proc,
224     const Parcel& in, sp<IBinder>* out)
225 {
226     const flat_binder_object* flat = in.readObject(false);
227 
228     if (flat) {
229         switch (flat->type) {
230             case BINDER_TYPE_BINDER:
231                 *out = static_cast<IBinder*>(flat->cookie);
232                 return finish_unflatten_binder(NULL, *flat, in);
233             case BINDER_TYPE_HANDLE:
234                 *out = proc->getStrongProxyForHandle(flat->handle);
235                 return finish_unflatten_binder(
236                     static_cast<BpBinder*>(out->get()), *flat, in);
237         }
238     }
239     return BAD_TYPE;
240 }
241 
unflatten_binder(const sp<ProcessState> & proc,const Parcel & in,wp<IBinder> * out)242 status_t unflatten_binder(const sp<ProcessState>& proc,
243     const Parcel& in, wp<IBinder>* out)
244 {
245     const flat_binder_object* flat = in.readObject(false);
246 
247     if (flat) {
248         switch (flat->type) {
249             case BINDER_TYPE_BINDER:
250                 *out = static_cast<IBinder*>(flat->cookie);
251                 return finish_unflatten_binder(NULL, *flat, in);
252             case BINDER_TYPE_WEAK_BINDER:
253                 if (flat->binder != NULL) {
254                     out->set_object_and_refs(
255                         static_cast<IBinder*>(flat->cookie),
256                         static_cast<RefBase::weakref_type*>(flat->binder));
257                 } else {
258                     *out = NULL;
259                 }
260                 return finish_unflatten_binder(NULL, *flat, in);
261             case BINDER_TYPE_HANDLE:
262             case BINDER_TYPE_WEAK_HANDLE:
263                 *out = proc->getWeakProxyForHandle(flat->handle);
264                 return finish_unflatten_binder(
265                     static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
266         }
267     }
268     return BAD_TYPE;
269 }
270 
271 // ---------------------------------------------------------------------------
272 
Parcel()273 Parcel::Parcel()
274 {
275     initState();
276 }
277 
~Parcel()278 Parcel::~Parcel()
279 {
280     freeDataNoInit();
281 }
282 
data() const283 const uint8_t* Parcel::data() const
284 {
285     return mData;
286 }
287 
dataSize() const288 size_t Parcel::dataSize() const
289 {
290     return (mDataSize > mDataPos ? mDataSize : mDataPos);
291 }
292 
dataAvail() const293 size_t Parcel::dataAvail() const
294 {
295     // TODO: decide what to do about the possibility that this can
296     // report an available-data size that exceeds a Java int's max
297     // positive value, causing havoc.  Fortunately this will only
298     // happen if someone constructs a Parcel containing more than two
299     // gigabytes of data, which on typical phone hardware is simply
300     // not possible.
301     return dataSize() - dataPosition();
302 }
303 
dataPosition() const304 size_t Parcel::dataPosition() const
305 {
306     return mDataPos;
307 }
308 
dataCapacity() const309 size_t Parcel::dataCapacity() const
310 {
311     return mDataCapacity;
312 }
313 
setDataSize(size_t size)314 status_t Parcel::setDataSize(size_t size)
315 {
316     status_t err;
317     err = continueWrite(size);
318     if (err == NO_ERROR) {
319         mDataSize = size;
320         LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
321     }
322     return err;
323 }
324 
setDataPosition(size_t pos) const325 void Parcel::setDataPosition(size_t pos) const
326 {
327     mDataPos = pos;
328     mNextObjectHint = 0;
329 }
330 
setDataCapacity(size_t size)331 status_t Parcel::setDataCapacity(size_t size)
332 {
333     if (size > mDataSize) return continueWrite(size);
334     return NO_ERROR;
335 }
336 
setData(const uint8_t * buffer,size_t len)337 status_t Parcel::setData(const uint8_t* buffer, size_t len)
338 {
339     status_t err = restartWrite(len);
340     if (err == NO_ERROR) {
341         memcpy(const_cast<uint8_t*>(data()), buffer, len);
342         mDataSize = len;
343         mFdsKnown = false;
344     }
345     return err;
346 }
347 
appendFrom(Parcel * parcel,size_t offset,size_t len)348 status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
349 {
350     const sp<ProcessState> proc(ProcessState::self());
351     status_t err;
352     uint8_t *data = parcel->mData;
353     size_t *objects = parcel->mObjects;
354     size_t size = parcel->mObjectsSize;
355     int startPos = mDataPos;
356     int firstIndex = -1, lastIndex = -2;
357 
358     if (len == 0) {
359         return NO_ERROR;
360     }
361 
362     // range checks against the source parcel size
363     if ((offset > parcel->mDataSize)
364             || (len > parcel->mDataSize)
365             || (offset + len > parcel->mDataSize)) {
366         return BAD_VALUE;
367     }
368 
369     // Count objects in range
370     for (int i = 0; i < (int) size; i++) {
371         size_t off = objects[i];
372         if ((off >= offset) && (off < offset + len)) {
373             if (firstIndex == -1) {
374                 firstIndex = i;
375             }
376             lastIndex = i;
377         }
378     }
379     int numObjects = lastIndex - firstIndex + 1;
380 
381     // grow data
382     err = growData(len);
383     if (err != NO_ERROR) {
384         return err;
385     }
386 
387     // append data
388     memcpy(mData + mDataPos, data + offset, len);
389     mDataPos += len;
390     mDataSize += len;
391 
392     if (numObjects > 0) {
393         // grow objects
394         if (mObjectsCapacity < mObjectsSize + numObjects) {
395             int newSize = ((mObjectsSize + numObjects)*3)/2;
396             size_t *objects =
397                 (size_t*)realloc(mObjects, newSize*sizeof(size_t));
398             if (objects == (size_t*)0) {
399                 return NO_MEMORY;
400             }
401             mObjects = objects;
402             mObjectsCapacity = newSize;
403         }
404 
405         // append and acquire objects
406         int idx = mObjectsSize;
407         for (int i = firstIndex; i <= lastIndex; i++) {
408             size_t off = objects[i] - offset + startPos;
409             mObjects[idx++] = off;
410             mObjectsSize++;
411 
412             flat_binder_object* flat
413                 = reinterpret_cast<flat_binder_object*>(mData + off);
414             acquire_object(proc, *flat, this);
415 
416             if (flat->type == BINDER_TYPE_FD) {
417                 // If this is a file descriptor, we need to dup it so the
418                 // new Parcel now owns its own fd, and can declare that we
419                 // officially know we have fds.
420                 flat->handle = dup(flat->handle);
421                 flat->cookie = (void*)1;
422                 mHasFds = mFdsKnown = true;
423             }
424         }
425     }
426 
427     return NO_ERROR;
428 }
429 
hasFileDescriptors() const430 bool Parcel::hasFileDescriptors() const
431 {
432     if (!mFdsKnown) {
433         scanForFds();
434     }
435     return mHasFds;
436 }
437 
writeInterfaceToken(const String16 & interface)438 status_t Parcel::writeInterfaceToken(const String16& interface)
439 {
440     // currently the interface identification token is just its name as a string
441     return writeString16(interface);
442 }
443 
checkInterface(IBinder * binder) const444 bool Parcel::checkInterface(IBinder* binder) const
445 {
446     return enforceInterface(binder->getInterfaceDescriptor());
447 }
448 
enforceInterface(const String16 & interface) const449 bool Parcel::enforceInterface(const String16& interface) const
450 {
451     const String16 str(readString16());
452     if (str == interface) {
453         return true;
454     } else {
455         LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
456                 String8(interface).string(), String8(str).string());
457         return false;
458     }
459 }
460 
objects() const461 const size_t* Parcel::objects() const
462 {
463     return mObjects;
464 }
465 
objectsCount() const466 size_t Parcel::objectsCount() const
467 {
468     return mObjectsSize;
469 }
470 
errorCheck() const471 status_t Parcel::errorCheck() const
472 {
473     return mError;
474 }
475 
setError(status_t err)476 void Parcel::setError(status_t err)
477 {
478     mError = err;
479 }
480 
finishWrite(size_t len)481 status_t Parcel::finishWrite(size_t len)
482 {
483     //printf("Finish write of %d\n", len);
484     mDataPos += len;
485     LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
486     if (mDataPos > mDataSize) {
487         mDataSize = mDataPos;
488         LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
489     }
490     //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
491     return NO_ERROR;
492 }
493 
writeUnpadded(const void * data,size_t len)494 status_t Parcel::writeUnpadded(const void* data, size_t len)
495 {
496     size_t end = mDataPos + len;
497     if (end < mDataPos) {
498         // integer overflow
499         return BAD_VALUE;
500     }
501 
502     if (end <= mDataCapacity) {
503 restart_write:
504         memcpy(mData+mDataPos, data, len);
505         return finishWrite(len);
506     }
507 
508     status_t err = growData(len);
509     if (err == NO_ERROR) goto restart_write;
510     return err;
511 }
512 
write(const void * data,size_t len)513 status_t Parcel::write(const void* data, size_t len)
514 {
515     void* const d = writeInplace(len);
516     if (d) {
517         memcpy(d, data, len);
518         return NO_ERROR;
519     }
520     return mError;
521 }
522 
writeInplace(size_t len)523 void* Parcel::writeInplace(size_t len)
524 {
525     const size_t padded = PAD_SIZE(len);
526 
527     // sanity check for integer overflow
528     if (mDataPos+padded < mDataPos) {
529         return NULL;
530     }
531 
532     if ((mDataPos+padded) <= mDataCapacity) {
533 restart_write:
534         //printf("Writing %ld bytes, padded to %ld\n", len, padded);
535         uint8_t* const data = mData+mDataPos;
536 
537         // Need to pad at end?
538         if (padded != len) {
539 #if BYTE_ORDER == BIG_ENDIAN
540             static const uint32_t mask[4] = {
541                 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
542             };
543 #endif
544 #if BYTE_ORDER == LITTLE_ENDIAN
545             static const uint32_t mask[4] = {
546                 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
547             };
548 #endif
549             //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
550             //    *reinterpret_cast<void**>(data+padded-4));
551             *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
552         }
553 
554         finishWrite(padded);
555         return data;
556     }
557 
558     status_t err = growData(padded);
559     if (err == NO_ERROR) goto restart_write;
560     return NULL;
561 }
562 
writeInt32(int32_t val)563 status_t Parcel::writeInt32(int32_t val)
564 {
565     return writeAligned(val);
566 }
567 
writeInt64(int64_t val)568 status_t Parcel::writeInt64(int64_t val)
569 {
570     return writeAligned(val);
571 }
572 
writeFloat(float val)573 status_t Parcel::writeFloat(float val)
574 {
575     return writeAligned(val);
576 }
577 
writeDouble(double val)578 status_t Parcel::writeDouble(double val)
579 {
580     return writeAligned(val);
581 }
582 
writeIntPtr(intptr_t val)583 status_t Parcel::writeIntPtr(intptr_t val)
584 {
585     return writeAligned(val);
586 }
587 
writeCString(const char * str)588 status_t Parcel::writeCString(const char* str)
589 {
590     return write(str, strlen(str)+1);
591 }
592 
writeString8(const String8 & str)593 status_t Parcel::writeString8(const String8& str)
594 {
595     status_t err = writeInt32(str.bytes());
596     if (err == NO_ERROR) {
597         err = write(str.string(), str.bytes()+1);
598     }
599     return err;
600 }
601 
writeString16(const String16 & str)602 status_t Parcel::writeString16(const String16& str)
603 {
604     return writeString16(str.string(), str.size());
605 }
606 
writeString16(const char16_t * str,size_t len)607 status_t Parcel::writeString16(const char16_t* str, size_t len)
608 {
609     if (str == NULL) return writeInt32(-1);
610 
611     status_t err = writeInt32(len);
612     if (err == NO_ERROR) {
613         len *= sizeof(char16_t);
614         uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
615         if (data) {
616             memcpy(data, str, len);
617             *reinterpret_cast<char16_t*>(data+len) = 0;
618             return NO_ERROR;
619         }
620         err = mError;
621     }
622     return err;
623 }
624 
writeStrongBinder(const sp<IBinder> & val)625 status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
626 {
627     return flatten_binder(ProcessState::self(), val, this);
628 }
629 
writeWeakBinder(const wp<IBinder> & val)630 status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
631 {
632     return flatten_binder(ProcessState::self(), val, this);
633 }
634 
writeNativeHandle(const native_handle * handle)635 status_t Parcel::writeNativeHandle(const native_handle* handle)
636 {
637     if (!handle || handle->version != sizeof(native_handle))
638         return BAD_TYPE;
639 
640     status_t err;
641     err = writeInt32(handle->numFds);
642     if (err != NO_ERROR) return err;
643 
644     err = writeInt32(handle->numInts);
645     if (err != NO_ERROR) return err;
646 
647     for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
648         err = writeDupFileDescriptor(handle->data[i]);
649 
650     if (err != NO_ERROR) {
651         LOGD("write native handle, write dup fd failed");
652         return err;
653     }
654     err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
655     return err;
656 }
657 
writeFileDescriptor(int fd)658 status_t Parcel::writeFileDescriptor(int fd)
659 {
660     flat_binder_object obj;
661     obj.type = BINDER_TYPE_FD;
662     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
663     obj.handle = fd;
664     obj.cookie = (void*)0;
665     return writeObject(obj, true);
666 }
667 
writeDupFileDescriptor(int fd)668 status_t Parcel::writeDupFileDescriptor(int fd)
669 {
670     flat_binder_object obj;
671     obj.type = BINDER_TYPE_FD;
672     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
673     obj.handle = dup(fd);
674     obj.cookie = (void*)1;
675     return writeObject(obj, true);
676 }
677 
writeObject(const flat_binder_object & val,bool nullMetaData)678 status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
679 {
680     const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
681     const bool enoughObjects = mObjectsSize < mObjectsCapacity;
682     if (enoughData && enoughObjects) {
683 restart_write:
684         *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
685 
686         // Need to write meta-data?
687         if (nullMetaData || val.binder != NULL) {
688             mObjects[mObjectsSize] = mDataPos;
689             acquire_object(ProcessState::self(), val, this);
690             mObjectsSize++;
691         }
692 
693         // remember if it's a file descriptor
694         if (val.type == BINDER_TYPE_FD) {
695             mHasFds = mFdsKnown = true;
696         }
697 
698         return finishWrite(sizeof(flat_binder_object));
699     }
700 
701     if (!enoughData) {
702         const status_t err = growData(sizeof(val));
703         if (err != NO_ERROR) return err;
704     }
705     if (!enoughObjects) {
706         size_t newSize = ((mObjectsSize+2)*3)/2;
707         size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
708         if (objects == NULL) return NO_MEMORY;
709         mObjects = objects;
710         mObjectsCapacity = newSize;
711     }
712 
713     goto restart_write;
714 }
715 
716 
remove(size_t start,size_t amt)717 void Parcel::remove(size_t start, size_t amt)
718 {
719     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
720 }
721 
read(void * outData,size_t len) const722 status_t Parcel::read(void* outData, size_t len) const
723 {
724     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
725         memcpy(outData, mData+mDataPos, len);
726         mDataPos += PAD_SIZE(len);
727         LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
728         return NO_ERROR;
729     }
730     return NOT_ENOUGH_DATA;
731 }
732 
readInplace(size_t len) const733 const void* Parcel::readInplace(size_t len) const
734 {
735     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
736         const void* data = mData+mDataPos;
737         mDataPos += PAD_SIZE(len);
738         LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
739         return data;
740     }
741     return NULL;
742 }
743 
744 template<class T>
readAligned(T * pArg) const745 status_t Parcel::readAligned(T *pArg) const {
746     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
747 
748     if ((mDataPos+sizeof(T)) <= mDataSize) {
749         const void* data = mData+mDataPos;
750         mDataPos += sizeof(T);
751         *pArg =  *reinterpret_cast<const T*>(data);
752         return NO_ERROR;
753     } else {
754         return NOT_ENOUGH_DATA;
755     }
756 }
757 
758 template<class T>
readAligned() const759 T Parcel::readAligned() const {
760     T result;
761     if (readAligned(&result) != NO_ERROR) {
762         result = 0;
763     }
764 
765     return result;
766 }
767 
768 template<class T>
writeAligned(T val)769 status_t Parcel::writeAligned(T val) {
770     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
771 
772     if ((mDataPos+sizeof(val)) <= mDataCapacity) {
773 restart_write:
774         *reinterpret_cast<T*>(mData+mDataPos) = val;
775         return finishWrite(sizeof(val));
776     }
777 
778     status_t err = growData(sizeof(val));
779     if (err == NO_ERROR) goto restart_write;
780     return err;
781 }
782 
readInt32(int32_t * pArg) const783 status_t Parcel::readInt32(int32_t *pArg) const
784 {
785     return readAligned(pArg);
786 }
787 
readInt32() const788 int32_t Parcel::readInt32() const
789 {
790     return readAligned<int32_t>();
791 }
792 
793 
readInt64(int64_t * pArg) const794 status_t Parcel::readInt64(int64_t *pArg) const
795 {
796     return readAligned(pArg);
797 }
798 
799 
readInt64() const800 int64_t Parcel::readInt64() const
801 {
802     return readAligned<int64_t>();
803 }
804 
readFloat(float * pArg) const805 status_t Parcel::readFloat(float *pArg) const
806 {
807     return readAligned(pArg);
808 }
809 
810 
readFloat() const811 float Parcel::readFloat() const
812 {
813     return readAligned<float>();
814 }
815 
readDouble(double * pArg) const816 status_t Parcel::readDouble(double *pArg) const
817 {
818     return readAligned(pArg);
819 }
820 
821 
readDouble() const822 double Parcel::readDouble() const
823 {
824     return readAligned<double>();
825 }
826 
readIntPtr(intptr_t * pArg) const827 status_t Parcel::readIntPtr(intptr_t *pArg) const
828 {
829     return readAligned(pArg);
830 }
831 
832 
readIntPtr() const833 intptr_t Parcel::readIntPtr() const
834 {
835     return readAligned<intptr_t>();
836 }
837 
838 
readCString() const839 const char* Parcel::readCString() const
840 {
841     const size_t avail = mDataSize-mDataPos;
842     if (avail > 0) {
843         const char* str = reinterpret_cast<const char*>(mData+mDataPos);
844         // is the string's trailing NUL within the parcel's valid bounds?
845         const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
846         if (eos) {
847             const size_t len = eos - str;
848             mDataPos += PAD_SIZE(len+1);
849             LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
850             return str;
851         }
852     }
853     return NULL;
854 }
855 
readString8() const856 String8 Parcel::readString8() const
857 {
858     int32_t size = readInt32();
859     // watch for potential int overflow adding 1 for trailing NUL
860     if (size > 0 && size < INT32_MAX) {
861         const char* str = (const char*)readInplace(size+1);
862         if (str) return String8(str, size);
863     }
864     return String8();
865 }
866 
readString16() const867 String16 Parcel::readString16() const
868 {
869     size_t len;
870     const char16_t* str = readString16Inplace(&len);
871     if (str) return String16(str, len);
872     LOGE("Reading a NULL string not supported here.");
873     return String16();
874 }
875 
readString16Inplace(size_t * outLen) const876 const char16_t* Parcel::readString16Inplace(size_t* outLen) const
877 {
878     int32_t size = readInt32();
879     // watch for potential int overflow from size+1
880     if (size >= 0 && size < INT32_MAX) {
881         *outLen = size;
882         const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
883         if (str != NULL) {
884             return str;
885         }
886     }
887     *outLen = 0;
888     return NULL;
889 }
890 
readStrongBinder() const891 sp<IBinder> Parcel::readStrongBinder() const
892 {
893     sp<IBinder> val;
894     unflatten_binder(ProcessState::self(), *this, &val);
895     return val;
896 }
897 
readWeakBinder() const898 wp<IBinder> Parcel::readWeakBinder() const
899 {
900     wp<IBinder> val;
901     unflatten_binder(ProcessState::self(), *this, &val);
902     return val;
903 }
904 
905 
readNativeHandle() const906 native_handle* Parcel::readNativeHandle() const
907 {
908     int numFds, numInts;
909     status_t err;
910     err = readInt32(&numFds);
911     if (err != NO_ERROR) return 0;
912     err = readInt32(&numInts);
913     if (err != NO_ERROR) return 0;
914 
915     native_handle* h = native_handle_create(numFds, numInts);
916     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
917         h->data[i] = dup(readFileDescriptor());
918         if (h->data[i] < 0) err = BAD_VALUE;
919     }
920     err = read(h->data + numFds, sizeof(int)*numInts);
921     if (err != NO_ERROR) {
922         native_handle_close(h);
923         native_handle_delete(h);
924         h = 0;
925     }
926     return h;
927 }
928 
929 
readFileDescriptor() const930 int Parcel::readFileDescriptor() const
931 {
932     const flat_binder_object* flat = readObject(true);
933     if (flat) {
934         switch (flat->type) {
935             case BINDER_TYPE_FD:
936                 //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
937                 return flat->handle;
938         }
939     }
940     return BAD_TYPE;
941 }
942 
readObject(bool nullMetaData) const943 const flat_binder_object* Parcel::readObject(bool nullMetaData) const
944 {
945     const size_t DPOS = mDataPos;
946     if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
947         const flat_binder_object* obj
948                 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
949         mDataPos = DPOS + sizeof(flat_binder_object);
950         if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
951             // When transferring a NULL object, we don't write it into
952             // the object list, so we don't want to check for it when
953             // reading.
954             LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
955             return obj;
956         }
957 
958         // Ensure that this object is valid...
959         size_t* const OBJS = mObjects;
960         const size_t N = mObjectsSize;
961         size_t opos = mNextObjectHint;
962 
963         if (N > 0) {
964             LOGV("Parcel %p looking for obj at %d, hint=%d\n",
965                  this, DPOS, opos);
966 
967             // Start at the current hint position, looking for an object at
968             // the current data position.
969             if (opos < N) {
970                 while (opos < (N-1) && OBJS[opos] < DPOS) {
971                     opos++;
972                 }
973             } else {
974                 opos = N-1;
975             }
976             if (OBJS[opos] == DPOS) {
977                 // Found it!
978                 LOGV("Parcel found obj %d at index %d with forward search",
979                      this, DPOS, opos);
980                 mNextObjectHint = opos+1;
981                 LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
982                 return obj;
983             }
984 
985             // Look backwards for it...
986             while (opos > 0 && OBJS[opos] > DPOS) {
987                 opos--;
988             }
989             if (OBJS[opos] == DPOS) {
990                 // Found it!
991                 LOGV("Parcel found obj %d at index %d with backward search",
992                      this, DPOS, opos);
993                 mNextObjectHint = opos+1;
994                 LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
995                 return obj;
996             }
997         }
998         LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
999              this, DPOS);
1000     }
1001     return NULL;
1002 }
1003 
closeFileDescriptors()1004 void Parcel::closeFileDescriptors()
1005 {
1006     size_t i = mObjectsSize;
1007     if (i > 0) {
1008         //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
1009     }
1010     while (i > 0) {
1011         i--;
1012         const flat_binder_object* flat
1013             = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1014         if (flat->type == BINDER_TYPE_FD) {
1015             //LOGI("Closing fd: %ld\n", flat->handle);
1016             close(flat->handle);
1017         }
1018     }
1019 }
1020 
ipcData() const1021 const uint8_t* Parcel::ipcData() const
1022 {
1023     return mData;
1024 }
1025 
ipcDataSize() const1026 size_t Parcel::ipcDataSize() const
1027 {
1028     return (mDataSize > mDataPos ? mDataSize : mDataPos);
1029 }
1030 
ipcObjects() const1031 const size_t* Parcel::ipcObjects() const
1032 {
1033     return mObjects;
1034 }
1035 
ipcObjectsCount() const1036 size_t Parcel::ipcObjectsCount() const
1037 {
1038     return mObjectsSize;
1039 }
1040 
ipcSetDataReference(const uint8_t * data,size_t dataSize,const size_t * objects,size_t objectsCount,release_func relFunc,void * relCookie)1041 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
1042     const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
1043 {
1044     freeDataNoInit();
1045     mError = NO_ERROR;
1046     mData = const_cast<uint8_t*>(data);
1047     mDataSize = mDataCapacity = dataSize;
1048     //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
1049     mDataPos = 0;
1050     LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
1051     mObjects = const_cast<size_t*>(objects);
1052     mObjectsSize = mObjectsCapacity = objectsCount;
1053     mNextObjectHint = 0;
1054     mOwner = relFunc;
1055     mOwnerCookie = relCookie;
1056     scanForFds();
1057 }
1058 
print(TextOutput & to,uint32_t flags) const1059 void Parcel::print(TextOutput& to, uint32_t flags) const
1060 {
1061     to << "Parcel(";
1062 
1063     if (errorCheck() != NO_ERROR) {
1064         const status_t err = errorCheck();
1065         to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
1066     } else if (dataSize() > 0) {
1067         const uint8_t* DATA = data();
1068         to << indent << HexDump(DATA, dataSize()) << dedent;
1069         const size_t* OBJS = objects();
1070         const size_t N = objectsCount();
1071         for (size_t i=0; i<N; i++) {
1072             const flat_binder_object* flat
1073                 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
1074             to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
1075                 << TypeCode(flat->type & 0x7f7f7f00)
1076                 << " = " << flat->binder;
1077         }
1078     } else {
1079         to << "NULL";
1080     }
1081 
1082     to << ")";
1083 }
1084 
releaseObjects()1085 void Parcel::releaseObjects()
1086 {
1087     const sp<ProcessState> proc(ProcessState::self());
1088     size_t i = mObjectsSize;
1089     uint8_t* const data = mData;
1090     size_t* const objects = mObjects;
1091     while (i > 0) {
1092         i--;
1093         const flat_binder_object* flat
1094             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1095         release_object(proc, *flat, this);
1096     }
1097 }
1098 
acquireObjects()1099 void Parcel::acquireObjects()
1100 {
1101     const sp<ProcessState> proc(ProcessState::self());
1102     size_t i = mObjectsSize;
1103     uint8_t* const data = mData;
1104     size_t* const objects = mObjects;
1105     while (i > 0) {
1106         i--;
1107         const flat_binder_object* flat
1108             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1109         acquire_object(proc, *flat, this);
1110     }
1111 }
1112 
freeData()1113 void Parcel::freeData()
1114 {
1115     freeDataNoInit();
1116     initState();
1117 }
1118 
freeDataNoInit()1119 void Parcel::freeDataNoInit()
1120 {
1121     if (mOwner) {
1122         //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
1123         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1124     } else {
1125         releaseObjects();
1126         if (mData) free(mData);
1127         if (mObjects) free(mObjects);
1128     }
1129 }
1130 
growData(size_t len)1131 status_t Parcel::growData(size_t len)
1132 {
1133     size_t newSize = ((mDataSize+len)*3)/2;
1134     return (newSize <= mDataSize)
1135             ? (status_t) NO_MEMORY
1136             : continueWrite(newSize);
1137 }
1138 
restartWrite(size_t desired)1139 status_t Parcel::restartWrite(size_t desired)
1140 {
1141     if (mOwner) {
1142         freeData();
1143         return continueWrite(desired);
1144     }
1145 
1146     uint8_t* data = (uint8_t*)realloc(mData, desired);
1147     if (!data && desired > mDataCapacity) {
1148         mError = NO_MEMORY;
1149         return NO_MEMORY;
1150     }
1151 
1152     releaseObjects();
1153 
1154     if (data) {
1155         mData = data;
1156         mDataCapacity = desired;
1157     }
1158 
1159     mDataSize = mDataPos = 0;
1160     LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
1161     LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
1162 
1163     free(mObjects);
1164     mObjects = NULL;
1165     mObjectsSize = mObjectsCapacity = 0;
1166     mNextObjectHint = 0;
1167     mHasFds = false;
1168     mFdsKnown = true;
1169 
1170     return NO_ERROR;
1171 }
1172 
continueWrite(size_t desired)1173 status_t Parcel::continueWrite(size_t desired)
1174 {
1175     // If shrinking, first adjust for any objects that appear
1176     // after the new data size.
1177     size_t objectsSize = mObjectsSize;
1178     if (desired < mDataSize) {
1179         if (desired == 0) {
1180             objectsSize = 0;
1181         } else {
1182             while (objectsSize > 0) {
1183                 if (mObjects[objectsSize-1] < desired)
1184                     break;
1185                 objectsSize--;
1186             }
1187         }
1188     }
1189 
1190     if (mOwner) {
1191         // If the size is going to zero, just release the owner's data.
1192         if (desired == 0) {
1193             freeData();
1194             return NO_ERROR;
1195         }
1196 
1197         // If there is a different owner, we need to take
1198         // posession.
1199         uint8_t* data = (uint8_t*)malloc(desired);
1200         if (!data) {
1201             mError = NO_MEMORY;
1202             return NO_MEMORY;
1203         }
1204         size_t* objects = NULL;
1205 
1206         if (objectsSize) {
1207             objects = (size_t*)malloc(objectsSize*sizeof(size_t));
1208             if (!objects) {
1209                 mError = NO_MEMORY;
1210                 return NO_MEMORY;
1211             }
1212 
1213             // Little hack to only acquire references on objects
1214             // we will be keeping.
1215             size_t oldObjectsSize = mObjectsSize;
1216             mObjectsSize = objectsSize;
1217             acquireObjects();
1218             mObjectsSize = oldObjectsSize;
1219         }
1220 
1221         if (mData) {
1222             memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
1223         }
1224         if (objects && mObjects) {
1225             memcpy(objects, mObjects, objectsSize*sizeof(size_t));
1226         }
1227         //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
1228         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1229         mOwner = NULL;
1230 
1231         mData = data;
1232         mObjects = objects;
1233         mDataSize = (mDataSize < desired) ? mDataSize : desired;
1234         LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1235         mDataCapacity = desired;
1236         mObjectsSize = mObjectsCapacity = objectsSize;
1237         mNextObjectHint = 0;
1238 
1239     } else if (mData) {
1240         if (objectsSize < mObjectsSize) {
1241             // Need to release refs on any objects we are dropping.
1242             const sp<ProcessState> proc(ProcessState::self());
1243             for (size_t i=objectsSize; i<mObjectsSize; i++) {
1244                 const flat_binder_object* flat
1245                     = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1246                 if (flat->type == BINDER_TYPE_FD) {
1247                     // will need to rescan because we may have lopped off the only FDs
1248                     mFdsKnown = false;
1249                 }
1250                 release_object(proc, *flat, this);
1251             }
1252             size_t* objects =
1253                 (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
1254             if (objects) {
1255                 mObjects = objects;
1256             }
1257             mObjectsSize = objectsSize;
1258             mNextObjectHint = 0;
1259         }
1260 
1261         // We own the data, so we can just do a realloc().
1262         if (desired > mDataCapacity) {
1263             uint8_t* data = (uint8_t*)realloc(mData, desired);
1264             if (data) {
1265                 mData = data;
1266                 mDataCapacity = desired;
1267             } else if (desired > mDataCapacity) {
1268                 mError = NO_MEMORY;
1269                 return NO_MEMORY;
1270             }
1271         } else {
1272             mDataSize = desired;
1273             LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1274             if (mDataPos > desired) {
1275                 mDataPos = desired;
1276                 LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
1277             }
1278         }
1279 
1280     } else {
1281         // This is the first data.  Easy!
1282         uint8_t* data = (uint8_t*)malloc(desired);
1283         if (!data) {
1284             mError = NO_MEMORY;
1285             return NO_MEMORY;
1286         }
1287 
1288         if(!(mDataCapacity == 0 && mObjects == NULL
1289              && mObjectsCapacity == 0)) {
1290             LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
1291         }
1292 
1293         mData = data;
1294         mDataSize = mDataPos = 0;
1295         LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1296         LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
1297         mDataCapacity = desired;
1298     }
1299 
1300     return NO_ERROR;
1301 }
1302 
initState()1303 void Parcel::initState()
1304 {
1305     mError = NO_ERROR;
1306     mData = 0;
1307     mDataSize = 0;
1308     mDataCapacity = 0;
1309     mDataPos = 0;
1310     LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
1311     LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
1312     mObjects = NULL;
1313     mObjectsSize = 0;
1314     mObjectsCapacity = 0;
1315     mNextObjectHint = 0;
1316     mHasFds = false;
1317     mFdsKnown = true;
1318     mOwner = NULL;
1319 }
1320 
scanForFds() const1321 void Parcel::scanForFds() const
1322 {
1323     bool hasFds = false;
1324     for (size_t i=0; i<mObjectsSize; i++) {
1325         const flat_binder_object* flat
1326             = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
1327         if (flat->type == BINDER_TYPE_FD) {
1328             hasFds = true;
1329             break;
1330         }
1331     }
1332     mHasFds = hasFds;
1333     mFdsKnown = true;
1334 }
1335 
1336 }; // namespace android
1337