OSDN Git Service

Binder: Fix some valgrind errors.
[android-x86/frameworks-native.git] / libs / binder / Parcel.cpp
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/IPCThreadState.h>
23 #include <binder/Binder.h>
24 #include <binder/BpBinder.h>
25 #include <binder/ProcessState.h>
26 #include <binder/TextOutput.h>
27
28 #include <utils/Debug.h>
29 #include <utils/Log.h>
30 #include <utils/String8.h>
31 #include <utils/String16.h>
32 #include <utils/misc.h>
33 #include <utils/Flattenable.h>
34 #include <cutils/ashmem.h>
35
36 #include <private/binder/binder_module.h>
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stdint.h>
41 #include <sys/mman.h>
42
43 #ifndef INT32_MAX
44 #define INT32_MAX ((int32_t)(2147483647))
45 #endif
46
47 #define LOG_REFS(...)
48 //#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
49
50 // ---------------------------------------------------------------------------
51
52 #define PAD_SIZE(s) (((s)+3)&~3)
53
54 // Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
55 #define STRICT_MODE_PENALTY_GATHER 0x100
56
57 // Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
58 #define EX_HAS_REPLY_HEADER -128
59
60 // Maximum size of a blob to transfer in-place.
61 static const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
62
63 // XXX This can be made public if we want to provide
64 // support for typed data.
65 struct small_flat_data
66 {
67     uint32_t type;
68     uint32_t data;
69 };
70
71 namespace android {
72
73 void acquire_object(const sp<ProcessState>& proc,
74     const flat_binder_object& obj, const void* who)
75 {
76     switch (obj.type) {
77         case BINDER_TYPE_BINDER:
78             if (obj.binder) {
79                 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
80                 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
81             }
82             return;
83         case BINDER_TYPE_WEAK_BINDER:
84             if (obj.binder)
85                 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
86             return;
87         case BINDER_TYPE_HANDLE: {
88             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
89             if (b != NULL) {
90                 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
91                 b->incStrong(who);
92             }
93             return;
94         }
95         case BINDER_TYPE_WEAK_HANDLE: {
96             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
97             if (b != NULL) b.get_refs()->incWeak(who);
98             return;
99         }
100         case BINDER_TYPE_FD: {
101             // intentionally blank -- nothing to do to acquire this, but we do
102             // recognize it as a legitimate object type.
103             return;
104         }
105     }
106
107     ALOGD("Invalid object type 0x%08x", obj.type);
108 }
109
110 void release_object(const sp<ProcessState>& proc,
111     const flat_binder_object& obj, const void* who)
112 {
113     switch (obj.type) {
114         case BINDER_TYPE_BINDER:
115             if (obj.binder) {
116                 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
117                 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
118             }
119             return;
120         case BINDER_TYPE_WEAK_BINDER:
121             if (obj.binder)
122                 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
123             return;
124         case BINDER_TYPE_HANDLE: {
125             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
126             if (b != NULL) {
127                 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
128                 b->decStrong(who);
129             }
130             return;
131         }
132         case BINDER_TYPE_WEAK_HANDLE: {
133             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
134             if (b != NULL) b.get_refs()->decWeak(who);
135             return;
136         }
137         case BINDER_TYPE_FD: {
138             if (obj.cookie != 0) close(obj.handle);
139             return;
140         }
141     }
142
143     ALOGE("Invalid object type 0x%08x", obj.type);
144 }
145
146 inline static status_t finish_flatten_binder(
147     const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
148 {
149     return out->writeObject(flat, false);
150 }
151
152 status_t flatten_binder(const sp<ProcessState>& /*proc*/,
153     const sp<IBinder>& binder, Parcel* out)
154 {
155     flat_binder_object obj;
156     
157     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
158     if (binder != NULL) {
159         IBinder *local = binder->localBinder();
160         if (!local) {
161             BpBinder *proxy = binder->remoteBinder();
162             if (proxy == NULL) {
163                 ALOGE("null proxy");
164             }
165             const int32_t handle = proxy ? proxy->handle() : 0;
166             obj.type = BINDER_TYPE_HANDLE;
167             obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
168             obj.handle = handle;
169             obj.cookie = 0;
170         } else {
171             obj.type = BINDER_TYPE_BINDER;
172             obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
173             obj.cookie = reinterpret_cast<uintptr_t>(local);
174         }
175     } else {
176         obj.type = BINDER_TYPE_BINDER;
177         obj.binder = 0;
178         obj.cookie = 0;
179     }
180     
181     return finish_flatten_binder(binder, obj, out);
182 }
183
184 status_t flatten_binder(const sp<ProcessState>& /*proc*/,
185     const wp<IBinder>& binder, Parcel* out)
186 {
187     flat_binder_object obj;
188     
189     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
190     if (binder != NULL) {
191         sp<IBinder> real = binder.promote();
192         if (real != NULL) {
193             IBinder *local = real->localBinder();
194             if (!local) {
195                 BpBinder *proxy = real->remoteBinder();
196                 if (proxy == NULL) {
197                     ALOGE("null proxy");
198                 }
199                 const int32_t handle = proxy ? proxy->handle() : 0;
200                 obj.type = BINDER_TYPE_WEAK_HANDLE;
201                 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
202                 obj.handle = handle;
203                 obj.cookie = 0;
204             } else {
205                 obj.type = BINDER_TYPE_WEAK_BINDER;
206                 obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
207                 obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
208             }
209             return finish_flatten_binder(real, obj, out);
210         }
211         
212         // XXX How to deal?  In order to flatten the given binder,
213         // we need to probe it for information, which requires a primary
214         // reference...  but we don't have one.
215         //
216         // The OpenBinder implementation uses a dynamic_cast<> here,
217         // but we can't do that with the different reference counting
218         // implementation we are using.
219         ALOGE("Unable to unflatten Binder weak reference!");
220         obj.type = BINDER_TYPE_BINDER;
221         obj.binder = 0;
222         obj.cookie = 0;
223         return finish_flatten_binder(NULL, obj, out);
224     
225     } else {
226         obj.type = BINDER_TYPE_BINDER;
227         obj.binder = 0;
228         obj.cookie = 0;
229         return finish_flatten_binder(NULL, obj, out);
230     }
231 }
232
233 inline static status_t finish_unflatten_binder(
234     BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
235     const Parcel& /*in*/)
236 {
237     return NO_ERROR;
238 }
239     
240 status_t unflatten_binder(const sp<ProcessState>& proc,
241     const Parcel& in, sp<IBinder>* out)
242 {
243     const flat_binder_object* flat = in.readObject(false);
244     
245     if (flat) {
246         switch (flat->type) {
247             case BINDER_TYPE_BINDER:
248                 *out = reinterpret_cast<IBinder*>(flat->cookie);
249                 return finish_unflatten_binder(NULL, *flat, in);
250             case BINDER_TYPE_HANDLE:
251                 *out = proc->getStrongProxyForHandle(flat->handle);
252                 return finish_unflatten_binder(
253                     static_cast<BpBinder*>(out->get()), *flat, in);
254         }        
255     }
256     return BAD_TYPE;
257 }
258
259 status_t unflatten_binder(const sp<ProcessState>& proc,
260     const Parcel& in, wp<IBinder>* out)
261 {
262     const flat_binder_object* flat = in.readObject(false);
263     
264     if (flat) {
265         switch (flat->type) {
266             case BINDER_TYPE_BINDER:
267                 *out = reinterpret_cast<IBinder*>(flat->cookie);
268                 return finish_unflatten_binder(NULL, *flat, in);
269             case BINDER_TYPE_WEAK_BINDER:
270                 if (flat->binder != 0) {
271                     out->set_object_and_refs(
272                         reinterpret_cast<IBinder*>(flat->cookie),
273                         reinterpret_cast<RefBase::weakref_type*>(flat->binder));
274                 } else {
275                     *out = NULL;
276                 }
277                 return finish_unflatten_binder(NULL, *flat, in);
278             case BINDER_TYPE_HANDLE:
279             case BINDER_TYPE_WEAK_HANDLE:
280                 *out = proc->getWeakProxyForHandle(flat->handle);
281                 return finish_unflatten_binder(
282                     static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
283         }
284     }
285     return BAD_TYPE;
286 }
287
288 // ---------------------------------------------------------------------------
289
290 Parcel::Parcel()
291 {
292     initState();
293 }
294
295 Parcel::~Parcel()
296 {
297     freeDataNoInit();
298 }
299
300 const uint8_t* Parcel::data() const
301 {
302     return mData;
303 }
304
305 size_t Parcel::dataSize() const
306 {
307     return (mDataSize > mDataPos ? mDataSize : mDataPos);
308 }
309
310 size_t Parcel::dataAvail() const
311 {
312     // TODO: decide what to do about the possibility that this can
313     // report an available-data size that exceeds a Java int's max
314     // positive value, causing havoc.  Fortunately this will only
315     // happen if someone constructs a Parcel containing more than two
316     // gigabytes of data, which on typical phone hardware is simply
317     // not possible.
318     return dataSize() - dataPosition();
319 }
320
321 size_t Parcel::dataPosition() const
322 {
323     return mDataPos;
324 }
325
326 size_t Parcel::dataCapacity() const
327 {
328     return mDataCapacity;
329 }
330
331 status_t Parcel::setDataSize(size_t size)
332 {
333     status_t err;
334     err = continueWrite(size);
335     if (err == NO_ERROR) {
336         mDataSize = size;
337         ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
338     }
339     return err;
340 }
341
342 void Parcel::setDataPosition(size_t pos) const
343 {
344     mDataPos = pos;
345     mNextObjectHint = 0;
346 }
347
348 status_t Parcel::setDataCapacity(size_t size)
349 {
350     if (size > mDataCapacity) return continueWrite(size);
351     return NO_ERROR;
352 }
353
354 status_t Parcel::setData(const uint8_t* buffer, size_t len)
355 {
356     status_t err = restartWrite(len);
357     if (err == NO_ERROR) {
358         memcpy(const_cast<uint8_t*>(data()), buffer, len);
359         mDataSize = len;
360         mFdsKnown = false;
361     }
362     return err;
363 }
364
365 status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
366 {
367     const sp<ProcessState> proc(ProcessState::self());
368     status_t err;
369     const uint8_t *data = parcel->mData;
370     const binder_size_t *objects = parcel->mObjects;
371     size_t size = parcel->mObjectsSize;
372     int startPos = mDataPos;
373     int firstIndex = -1, lastIndex = -2;
374
375     if (len == 0) {
376         return NO_ERROR;
377     }
378
379     // range checks against the source parcel size
380     if ((offset > parcel->mDataSize)
381             || (len > parcel->mDataSize)
382             || (offset + len > parcel->mDataSize)) {
383         return BAD_VALUE;
384     }
385
386     // Count objects in range
387     for (int i = 0; i < (int) size; i++) {
388         size_t off = objects[i];
389         if ((off >= offset) && (off < offset + len)) {
390             if (firstIndex == -1) {
391                 firstIndex = i;
392             }
393             lastIndex = i;
394         }
395     }
396     int numObjects = lastIndex - firstIndex + 1;
397
398     if ((mDataSize+len) > mDataCapacity) {
399         // grow data
400         err = growData(len);
401         if (err != NO_ERROR) {
402             return err;
403         }
404     }
405
406     // append data
407     memcpy(mData + mDataPos, data + offset, len);
408     mDataPos += len;
409     mDataSize += len;
410
411     err = NO_ERROR;
412
413     if (numObjects > 0) {
414         // grow objects
415         if (mObjectsCapacity < mObjectsSize + numObjects) {
416             int newSize = ((mObjectsSize + numObjects)*3)/2;
417             binder_size_t *objects =
418                 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
419             if (objects == (binder_size_t*)0) {
420                 return NO_MEMORY;
421             }
422             mObjects = objects;
423             mObjectsCapacity = newSize;
424         }
425         
426         // append and acquire objects
427         int idx = mObjectsSize;
428         for (int i = firstIndex; i <= lastIndex; i++) {
429             size_t off = objects[i] - offset + startPos;
430             mObjects[idx++] = off;
431             mObjectsSize++;
432
433             flat_binder_object* flat
434                 = reinterpret_cast<flat_binder_object*>(mData + off);
435             acquire_object(proc, *flat, this);
436
437             if (flat->type == BINDER_TYPE_FD) {
438                 // If this is a file descriptor, we need to dup it so the
439                 // new Parcel now owns its own fd, and can declare that we
440                 // officially know we have fds.
441                 flat->handle = dup(flat->handle);
442                 flat->cookie = 1;
443                 mHasFds = mFdsKnown = true;
444                 if (!mAllowFds) {
445                     err = FDS_NOT_ALLOWED;
446                 }
447             }
448         }
449     }
450
451     return err;
452 }
453
454 bool Parcel::pushAllowFds(bool allowFds)
455 {
456     const bool origValue = mAllowFds;
457     if (!allowFds) {
458         mAllowFds = false;
459     }
460     return origValue;
461 }
462
463 void Parcel::restoreAllowFds(bool lastValue)
464 {
465     mAllowFds = lastValue;
466 }
467
468 bool Parcel::hasFileDescriptors() const
469 {
470     if (!mFdsKnown) {
471         scanForFds();
472     }
473     return mHasFds;
474 }
475
476 // Write RPC headers.  (previously just the interface token)
477 status_t Parcel::writeInterfaceToken(const String16& interface)
478 {
479     writeInt32(IPCThreadState::self()->getStrictModePolicy() |
480                STRICT_MODE_PENALTY_GATHER);
481     // currently the interface identification token is just its name as a string
482     return writeString16(interface);
483 }
484
485 bool Parcel::checkInterface(IBinder* binder) const
486 {
487     return enforceInterface(binder->getInterfaceDescriptor());
488 }
489
490 bool Parcel::enforceInterface(const String16& interface,
491                               IPCThreadState* threadState) const
492 {
493     int32_t strictPolicy = readInt32();
494     if (threadState == NULL) {
495         threadState = IPCThreadState::self();
496     }
497     if ((threadState->getLastTransactionBinderFlags() &
498          IBinder::FLAG_ONEWAY) != 0) {
499       // For one-way calls, the callee is running entirely
500       // disconnected from the caller, so disable StrictMode entirely.
501       // Not only does disk/network usage not impact the caller, but
502       // there's no way to commuicate back any violations anyway.
503       threadState->setStrictModePolicy(0);
504     } else {
505       threadState->setStrictModePolicy(strictPolicy);
506     }
507     const String16 str(readString16());
508     if (str == interface) {
509         return true;
510     } else {
511         ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
512                 String8(interface).string(), String8(str).string());
513         return false;
514     }
515 }
516
517 const binder_size_t* Parcel::objects() const
518 {
519     return mObjects;
520 }
521
522 size_t Parcel::objectsCount() const
523 {
524     return mObjectsSize;
525 }
526
527 status_t Parcel::errorCheck() const
528 {
529     return mError;
530 }
531
532 void Parcel::setError(status_t err)
533 {
534     mError = err;
535 }
536
537 status_t Parcel::finishWrite(size_t len)
538 {
539     //printf("Finish write of %d\n", len);
540     mDataPos += len;
541     ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
542     if (mDataPos > mDataSize) {
543         mDataSize = mDataPos;
544         ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
545     }
546     //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
547     return NO_ERROR;
548 }
549
550 status_t Parcel::writeUnpadded(const void* data, size_t len)
551 {
552     size_t end = mDataPos + len;
553     if (end < mDataPos) {
554         // integer overflow
555         return BAD_VALUE;
556     }
557
558     if (end <= mDataCapacity) {
559 restart_write:
560         memcpy(mData+mDataPos, data, len);
561         return finishWrite(len);
562     }
563
564     status_t err = growData(len);
565     if (err == NO_ERROR) goto restart_write;
566     return err;
567 }
568
569 status_t Parcel::write(const void* data, size_t len)
570 {
571     void* const d = writeInplace(len);
572     if (d) {
573         memcpy(d, data, len);
574         return NO_ERROR;
575     }
576     return mError;
577 }
578
579 void* Parcel::writeInplace(size_t len)
580 {
581     const size_t padded = PAD_SIZE(len);
582
583     // sanity check for integer overflow
584     if (mDataPos+padded < mDataPos) {
585         return NULL;
586     }
587
588     if ((mDataPos+padded) <= mDataCapacity) {
589 restart_write:
590         //printf("Writing %ld bytes, padded to %ld\n", len, padded);
591         uint8_t* const data = mData+mDataPos;
592
593         // Need to pad at end?
594         if (padded != len) {
595 #if BYTE_ORDER == BIG_ENDIAN
596             static const uint32_t mask[4] = {
597                 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
598             };
599 #endif
600 #if BYTE_ORDER == LITTLE_ENDIAN
601             static const uint32_t mask[4] = {
602                 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
603             };
604 #endif
605             //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
606             //    *reinterpret_cast<void**>(data+padded-4));
607             *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
608         }
609
610         finishWrite(padded);
611         return data;
612     }
613
614     status_t err = growData(padded);
615     if (err == NO_ERROR) goto restart_write;
616     return NULL;
617 }
618
619 status_t Parcel::writeInt32(int32_t val)
620 {
621     return writeAligned(val);
622 }
623 status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
624     if (!val) {
625         return writeAligned(-1);
626     }
627     status_t ret = writeAligned(len);
628     if (ret == NO_ERROR) {
629         ret = write(val, len * sizeof(*val));
630     }
631     return ret;
632 }
633
634 status_t Parcel::writeInt64(int64_t val)
635 {
636     return writeAligned(val);
637 }
638
639 status_t Parcel::writePointer(uintptr_t val)
640 {
641     return writeAligned<binder_uintptr_t>(val);
642 }
643
644 status_t Parcel::writeFloat(float val)
645 {
646     return writeAligned(val);
647 }
648
649 #if defined(__mips__) && defined(__mips_hard_float)
650
651 status_t Parcel::writeDouble(double val)
652 {
653     union {
654         double d;
655         unsigned long long ll;
656     } u;
657     u.d = val;
658     return writeAligned(u.ll);
659 }
660
661 #else
662
663 status_t Parcel::writeDouble(double val)
664 {
665     return writeAligned(val);
666 }
667
668 #endif
669
670 status_t Parcel::writeIntPtr(intptr_t val)
671 {
672     return writeAligned(val);
673 }
674
675 status_t Parcel::writeCString(const char* str)
676 {
677     return write(str, strlen(str)+1);
678 }
679
680 status_t Parcel::writeString8(const String8& str)
681 {
682     status_t err = writeInt32(str.bytes());
683     // only write string if its length is more than zero characters,
684     // as readString8 will only read if the length field is non-zero.
685     // this is slightly different from how writeString16 works.
686     if (str.bytes() > 0 && err == NO_ERROR) {
687         err = write(str.string(), str.bytes()+1);
688     }
689     return err;
690 }
691
692 status_t Parcel::writeString16(const String16& str)
693 {
694     return writeString16(str.string(), str.size());
695 }
696
697 status_t Parcel::writeString16(const char16_t* str, size_t len)
698 {
699     if (str == NULL) return writeInt32(-1);
700     
701     status_t err = writeInt32(len);
702     if (err == NO_ERROR) {
703         len *= sizeof(char16_t);
704         uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
705         if (data) {
706             memcpy(data, str, len);
707             *reinterpret_cast<char16_t*>(data+len) = 0;
708             return NO_ERROR;
709         }
710         err = mError;
711     }
712     return err;
713 }
714
715 status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
716 {
717     return flatten_binder(ProcessState::self(), val, this);
718 }
719
720 status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
721 {
722     return flatten_binder(ProcessState::self(), val, this);
723 }
724
725 status_t Parcel::writeNativeHandle(const native_handle* handle)
726 {
727     if (!handle || handle->version != sizeof(native_handle))
728         return BAD_TYPE;
729
730     status_t err;
731     err = writeInt32(handle->numFds);
732     if (err != NO_ERROR) return err;
733
734     err = writeInt32(handle->numInts);
735     if (err != NO_ERROR) return err;
736
737     for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
738         err = writeDupFileDescriptor(handle->data[i]);
739
740     if (err != NO_ERROR) {
741         ALOGD("write native handle, write dup fd failed");
742         return err;
743     }
744     err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
745     return err;
746 }
747
748 status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
749 {
750     flat_binder_object obj;
751     obj.type = BINDER_TYPE_FD;
752     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
753     obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
754     obj.handle = fd;
755     obj.cookie = takeOwnership ? 1 : 0;
756     return writeObject(obj, true);
757 }
758
759 status_t Parcel::writeDupFileDescriptor(int fd)
760 {
761     int dupFd = dup(fd);
762     if (dupFd < 0) {
763         return -errno;
764     }
765     status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
766     if (err) {
767         close(dupFd);
768     }
769     return err;
770 }
771
772 status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
773 {
774     status_t status;
775
776     if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
777         ALOGV("writeBlob: write in place");
778         status = writeInt32(0);
779         if (status) return status;
780
781         void* ptr = writeInplace(len);
782         if (!ptr) return NO_MEMORY;
783
784         outBlob->init(false /*mapped*/, ptr, len);
785         return NO_ERROR;
786     }
787
788     ALOGV("writeBlob: write to ashmem");
789     int fd = ashmem_create_region("Parcel Blob", len);
790     if (fd < 0) return NO_MEMORY;
791
792     int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
793     if (result < 0) {
794         status = result;
795     } else {
796         void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
797         if (ptr == MAP_FAILED) {
798             status = -errno;
799         } else {
800             result = ashmem_set_prot_region(fd, PROT_READ);
801             if (result < 0) {
802                 status = result;
803             } else {
804                 status = writeInt32(1);
805                 if (!status) {
806                     status = writeFileDescriptor(fd, true /*takeOwnership*/);
807                     if (!status) {
808                         outBlob->init(true /*mapped*/, ptr, len);
809                         return NO_ERROR;
810                     }
811                 }
812             }
813         }
814         ::munmap(ptr, len);
815     }
816     ::close(fd);
817     return status;
818 }
819
820 status_t Parcel::write(const FlattenableHelperInterface& val)
821 {
822     status_t err;
823
824     // size if needed
825     const size_t len = val.getFlattenedSize();
826     const size_t fd_count = val.getFdCount();
827
828     err = this->writeInt32(len);
829     if (err) return err;
830
831     err = this->writeInt32(fd_count);
832     if (err) return err;
833
834     // payload
835     void* const buf = this->writeInplace(PAD_SIZE(len));
836     if (buf == NULL)
837         return BAD_VALUE;
838
839     int* fds = NULL;
840     if (fd_count) {
841         fds = new int[fd_count];
842     }
843
844     err = val.flatten(buf, len, fds, fd_count);
845     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
846         err = this->writeDupFileDescriptor( fds[i] );
847     }
848
849     if (fd_count) {
850         delete [] fds;
851     }
852
853     return err;
854 }
855
856 status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
857 {
858     const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
859     const bool enoughObjects = mObjectsSize < mObjectsCapacity;
860     if (enoughData && enoughObjects) {
861 restart_write:
862         *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
863         
864         // Need to write meta-data?
865         if (nullMetaData || val.binder != 0) {
866             mObjects[mObjectsSize] = mDataPos;
867             acquire_object(ProcessState::self(), val, this);
868             mObjectsSize++;
869         }
870         
871         // remember if it's a file descriptor
872         if (val.type == BINDER_TYPE_FD) {
873             if (!mAllowFds) {
874                 return FDS_NOT_ALLOWED;
875             }
876             mHasFds = mFdsKnown = true;
877         }
878
879         return finishWrite(sizeof(flat_binder_object));
880     }
881
882     if (!enoughData) {
883         const status_t err = growData(sizeof(val));
884         if (err != NO_ERROR) return err;
885     }
886     if (!enoughObjects) {
887         size_t newSize = ((mObjectsSize+2)*3)/2;
888         binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
889         if (objects == NULL) return NO_MEMORY;
890         mObjects = objects;
891         mObjectsCapacity = newSize;
892     }
893     
894     goto restart_write;
895 }
896
897 status_t Parcel::writeNoException()
898 {
899     return writeInt32(0);
900 }
901
902 void Parcel::remove(size_t /*start*/, size_t /*amt*/)
903 {
904     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
905 }
906
907 status_t Parcel::read(void* outData, size_t len) const
908 {
909     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
910         memcpy(outData, mData+mDataPos, len);
911         mDataPos += PAD_SIZE(len);
912         ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
913         return NO_ERROR;
914     }
915     return NOT_ENOUGH_DATA;
916 }
917
918 const void* Parcel::readInplace(size_t len) const
919 {
920     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
921         const void* data = mData+mDataPos;
922         mDataPos += PAD_SIZE(len);
923         ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
924         return data;
925     }
926     return NULL;
927 }
928
929 template<class T>
930 status_t Parcel::readAligned(T *pArg) const {
931     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
932
933     if ((mDataPos+sizeof(T)) <= mDataSize) {
934         const void* data = mData+mDataPos;
935         mDataPos += sizeof(T);
936         *pArg =  *reinterpret_cast<const T*>(data);
937         return NO_ERROR;
938     } else {
939         return NOT_ENOUGH_DATA;
940     }
941 }
942
943 template<class T>
944 T Parcel::readAligned() const {
945     T result;
946     if (readAligned(&result) != NO_ERROR) {
947         result = 0;
948     }
949
950     return result;
951 }
952
953 template<class T>
954 status_t Parcel::writeAligned(T val) {
955     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
956
957     if ((mDataPos+sizeof(val)) <= mDataCapacity) {
958 restart_write:
959         *reinterpret_cast<T*>(mData+mDataPos) = val;
960         return finishWrite(sizeof(val));
961     }
962
963     status_t err = growData(sizeof(val));
964     if (err == NO_ERROR) goto restart_write;
965     return err;
966 }
967
968 status_t Parcel::readInt32(int32_t *pArg) const
969 {
970     return readAligned(pArg);
971 }
972
973 int32_t Parcel::readInt32() const
974 {
975     return readAligned<int32_t>();
976 }
977
978
979 status_t Parcel::readInt64(int64_t *pArg) const
980 {
981     return readAligned(pArg);
982 }
983
984
985 int64_t Parcel::readInt64() const
986 {
987     return readAligned<int64_t>();
988 }
989
990 status_t Parcel::readPointer(uintptr_t *pArg) const
991 {
992     status_t ret;
993     binder_uintptr_t ptr;
994     ret = readAligned(&ptr);
995     if (!ret)
996         *pArg = ptr;
997     return ret;
998 }
999
1000 uintptr_t Parcel::readPointer() const
1001 {
1002     return readAligned<binder_uintptr_t>();
1003 }
1004
1005
1006 status_t Parcel::readFloat(float *pArg) const
1007 {
1008     return readAligned(pArg);
1009 }
1010
1011
1012 float Parcel::readFloat() const
1013 {
1014     return readAligned<float>();
1015 }
1016
1017 #if defined(__mips__) && defined(__mips_hard_float)
1018
1019 status_t Parcel::readDouble(double *pArg) const
1020 {
1021     union {
1022       double d;
1023       unsigned long long ll;
1024     } u;
1025     status_t status;
1026     status = readAligned(&u.ll);
1027     *pArg = u.d;
1028     return status;
1029 }
1030
1031 double Parcel::readDouble() const
1032 {
1033     union {
1034       double d;
1035       unsigned long long ll;
1036     } u;
1037     u.ll = readAligned<unsigned long long>();
1038     return u.d;
1039 }
1040
1041 #else
1042
1043 status_t Parcel::readDouble(double *pArg) const
1044 {
1045     return readAligned(pArg);
1046 }
1047
1048 double Parcel::readDouble() const
1049 {
1050     return readAligned<double>();
1051 }
1052
1053 #endif
1054
1055 status_t Parcel::readIntPtr(intptr_t *pArg) const
1056 {
1057     return readAligned(pArg);
1058 }
1059
1060
1061 intptr_t Parcel::readIntPtr() const
1062 {
1063     return readAligned<intptr_t>();
1064 }
1065
1066
1067 const char* Parcel::readCString() const
1068 {
1069     const size_t avail = mDataSize-mDataPos;
1070     if (avail > 0) {
1071         const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1072         // is the string's trailing NUL within the parcel's valid bounds?
1073         const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1074         if (eos) {
1075             const size_t len = eos - str;
1076             mDataPos += PAD_SIZE(len+1);
1077             ALOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
1078             return str;
1079         }
1080     }
1081     return NULL;
1082 }
1083
1084 String8 Parcel::readString8() const
1085 {
1086     int32_t size = readInt32();
1087     // watch for potential int overflow adding 1 for trailing NUL
1088     if (size > 0 && size < INT32_MAX) {
1089         const char* str = (const char*)readInplace(size+1);
1090         if (str) return String8(str, size);
1091     }
1092     return String8();
1093 }
1094
1095 String16 Parcel::readString16() const
1096 {
1097     size_t len;
1098     const char16_t* str = readString16Inplace(&len);
1099     if (str) return String16(str, len);
1100     ALOGE("Reading a NULL string not supported here.");
1101     return String16();
1102 }
1103
1104 const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1105 {
1106     int32_t size = readInt32();
1107     // watch for potential int overflow from size+1
1108     if (size >= 0 && size < INT32_MAX) {
1109         *outLen = size;
1110         const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1111         if (str != NULL) {
1112             return str;
1113         }
1114     }
1115     *outLen = 0;
1116     return NULL;
1117 }
1118
1119 sp<IBinder> Parcel::readStrongBinder() const
1120 {
1121     sp<IBinder> val;
1122     unflatten_binder(ProcessState::self(), *this, &val);
1123     return val;
1124 }
1125
1126 wp<IBinder> Parcel::readWeakBinder() const
1127 {
1128     wp<IBinder> val;
1129     unflatten_binder(ProcessState::self(), *this, &val);
1130     return val;
1131 }
1132
1133 int32_t Parcel::readExceptionCode() const
1134 {
1135   int32_t exception_code = readAligned<int32_t>();
1136   if (exception_code == EX_HAS_REPLY_HEADER) {
1137     int32_t header_start = dataPosition();
1138     int32_t header_size = readAligned<int32_t>();
1139     // Skip over fat responses headers.  Not used (or propagated) in
1140     // native code
1141     setDataPosition(header_start + header_size);
1142     // And fat response headers are currently only used when there are no
1143     // exceptions, so return no error:
1144     return 0;
1145   }
1146   return exception_code;
1147 }
1148
1149 native_handle* Parcel::readNativeHandle() const
1150 {
1151     int numFds, numInts;
1152     status_t err;
1153     err = readInt32(&numFds);
1154     if (err != NO_ERROR) return 0;
1155     err = readInt32(&numInts);
1156     if (err != NO_ERROR) return 0;
1157
1158     native_handle* h = native_handle_create(numFds, numInts);
1159     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1160         h->data[i] = dup(readFileDescriptor());
1161         if (h->data[i] < 0) err = BAD_VALUE;
1162     }
1163     err = read(h->data + numFds, sizeof(int)*numInts);
1164     if (err != NO_ERROR) {
1165         native_handle_close(h);
1166         native_handle_delete(h);
1167         h = 0;
1168     }
1169     return h;
1170 }
1171
1172
1173 int Parcel::readFileDescriptor() const
1174 {
1175     const flat_binder_object* flat = readObject(true);
1176     if (flat) {
1177         switch (flat->type) {
1178             case BINDER_TYPE_FD:
1179                 //ALOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
1180                 return flat->handle;
1181         }        
1182     }
1183     return BAD_TYPE;
1184 }
1185
1186 status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
1187 {
1188     int32_t useAshmem;
1189     status_t status = readInt32(&useAshmem);
1190     if (status) return status;
1191
1192     if (!useAshmem) {
1193         ALOGV("readBlob: read in place");
1194         const void* ptr = readInplace(len);
1195         if (!ptr) return BAD_VALUE;
1196
1197         outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
1198         return NO_ERROR;
1199     }
1200
1201     ALOGV("readBlob: read from ashmem");
1202     int fd = readFileDescriptor();
1203     if (fd == int(BAD_TYPE)) return BAD_VALUE;
1204
1205     void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
1206     if (!ptr) return NO_MEMORY;
1207
1208     outBlob->init(true /*mapped*/, ptr, len);
1209     return NO_ERROR;
1210 }
1211
1212 status_t Parcel::read(FlattenableHelperInterface& val) const
1213 {
1214     // size
1215     const size_t len = this->readInt32();
1216     const size_t fd_count = this->readInt32();
1217
1218     // payload
1219     void const* const buf = this->readInplace(PAD_SIZE(len));
1220     if (buf == NULL)
1221         return BAD_VALUE;
1222
1223     int* fds = NULL;
1224     if (fd_count) {
1225         fds = new int[fd_count];
1226     }
1227
1228     status_t err = NO_ERROR;
1229     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1230         fds[i] = dup(this->readFileDescriptor());
1231         if (fds[i] < 0) err = BAD_VALUE;
1232     }
1233
1234     if (err == NO_ERROR) {
1235         err = val.unflatten(buf, len, fds, fd_count);
1236     }
1237
1238     if (fd_count) {
1239         delete [] fds;
1240     }
1241
1242     return err;
1243 }
1244 const flat_binder_object* Parcel::readObject(bool nullMetaData) const
1245 {
1246     const size_t DPOS = mDataPos;
1247     if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
1248         const flat_binder_object* obj
1249                 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
1250         mDataPos = DPOS + sizeof(flat_binder_object);
1251         if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
1252             // When transferring a NULL object, we don't write it into
1253             // the object list, so we don't want to check for it when
1254             // reading.
1255             ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
1256             return obj;
1257         }
1258         
1259         // Ensure that this object is valid...
1260         binder_size_t* const OBJS = mObjects;
1261         const size_t N = mObjectsSize;
1262         size_t opos = mNextObjectHint;
1263         
1264         if (N > 0) {
1265             ALOGV("Parcel %p looking for obj at %d, hint=%d\n",
1266                  this, DPOS, opos);
1267             
1268             // Start at the current hint position, looking for an object at
1269             // the current data position.
1270             if (opos < N) {
1271                 while (opos < (N-1) && OBJS[opos] < DPOS) {
1272                     opos++;
1273                 }
1274             } else {
1275                 opos = N-1;
1276             }
1277             if (OBJS[opos] == DPOS) {
1278                 // Found it!
1279                 ALOGV("Parcel found obj %d at index %d with forward search",
1280                      this, DPOS, opos);
1281                 mNextObjectHint = opos+1;
1282                 ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
1283                 return obj;
1284             }
1285         
1286             // Look backwards for it...
1287             while (opos > 0 && OBJS[opos] > DPOS) {
1288                 opos--;
1289             }
1290             if (OBJS[opos] == DPOS) {
1291                 // Found it!
1292                 ALOGV("Parcel found obj %d at index %d with backward search",
1293                      this, DPOS, opos);
1294                 mNextObjectHint = opos+1;
1295                 ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
1296                 return obj;
1297             }
1298         }
1299         ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1300              this, DPOS);
1301     }
1302     return NULL;
1303 }
1304
1305 void Parcel::closeFileDescriptors()
1306 {
1307     size_t i = mObjectsSize;
1308     if (i > 0) {
1309         //ALOGI("Closing file descriptors for %d objects...", mObjectsSize);
1310     }
1311     while (i > 0) {
1312         i--;
1313         const flat_binder_object* flat
1314             = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1315         if (flat->type == BINDER_TYPE_FD) {
1316             //ALOGI("Closing fd: %ld\n", flat->handle);
1317             close(flat->handle);
1318         }
1319     }
1320 }
1321
1322 uintptr_t Parcel::ipcData() const
1323 {
1324     return reinterpret_cast<uintptr_t>(mData);
1325 }
1326
1327 size_t Parcel::ipcDataSize() const
1328 {
1329     return (mDataSize > mDataPos ? mDataSize : mDataPos);
1330 }
1331
1332 uintptr_t Parcel::ipcObjects() const
1333 {
1334     return reinterpret_cast<uintptr_t>(mObjects);
1335 }
1336
1337 size_t Parcel::ipcObjectsCount() const
1338 {
1339     return mObjectsSize;
1340 }
1341
1342 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
1343     const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
1344 {
1345     freeDataNoInit();
1346     mError = NO_ERROR;
1347     mData = const_cast<uint8_t*>(data);
1348     mDataSize = mDataCapacity = dataSize;
1349     //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
1350     mDataPos = 0;
1351     ALOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
1352     mObjects = const_cast<binder_size_t*>(objects);
1353     mObjectsSize = mObjectsCapacity = objectsCount;
1354     mNextObjectHint = 0;
1355     mOwner = relFunc;
1356     mOwnerCookie = relCookie;
1357     scanForFds();
1358 }
1359
1360 void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
1361 {
1362     to << "Parcel(";
1363     
1364     if (errorCheck() != NO_ERROR) {
1365         const status_t err = errorCheck();
1366         to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
1367     } else if (dataSize() > 0) {
1368         const uint8_t* DATA = data();
1369         to << indent << HexDump(DATA, dataSize()) << dedent;
1370         const binder_size_t* OBJS = objects();
1371         const size_t N = objectsCount();
1372         for (size_t i=0; i<N; i++) {
1373             const flat_binder_object* flat
1374                 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
1375             to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
1376                 << TypeCode(flat->type & 0x7f7f7f00)
1377                 << " = " << flat->binder;
1378         }
1379     } else {
1380         to << "NULL";
1381     }
1382     
1383     to << ")";
1384 }
1385
1386 void Parcel::releaseObjects()
1387 {
1388     const sp<ProcessState> proc(ProcessState::self());
1389     size_t i = mObjectsSize;
1390     uint8_t* const data = mData;
1391     binder_size_t* const objects = mObjects;
1392     while (i > 0) {
1393         i--;
1394         const flat_binder_object* flat
1395             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1396         release_object(proc, *flat, this);
1397     }
1398 }
1399
1400 void Parcel::acquireObjects()
1401 {
1402     const sp<ProcessState> proc(ProcessState::self());
1403     size_t i = mObjectsSize;
1404     uint8_t* const data = mData;
1405     binder_size_t* const objects = mObjects;
1406     while (i > 0) {
1407         i--;
1408         const flat_binder_object* flat
1409             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1410         acquire_object(proc, *flat, this);
1411     }
1412 }
1413
1414 void Parcel::freeData()
1415 {
1416     freeDataNoInit();
1417     initState();
1418 }
1419
1420 void Parcel::freeDataNoInit()
1421 {
1422     if (mOwner) {
1423         //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
1424         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1425     } else {
1426         releaseObjects();
1427         if (mData) free(mData);
1428         if (mObjects) free(mObjects);
1429     }
1430 }
1431
1432 status_t Parcel::growData(size_t len)
1433 {
1434     size_t newSize = ((mDataSize+len)*3)/2;
1435     return (newSize <= mDataSize)
1436             ? (status_t) NO_MEMORY
1437             : continueWrite(newSize);
1438 }
1439
1440 status_t Parcel::restartWrite(size_t desired)
1441 {
1442     if (mOwner) {
1443         freeData();
1444         return continueWrite(desired);
1445     }
1446     
1447     uint8_t* data = (uint8_t*)realloc(mData, desired);
1448     if (!data && desired > mDataCapacity) {
1449         mError = NO_MEMORY;
1450         return NO_MEMORY;
1451     }
1452     
1453     releaseObjects();
1454     
1455     if (data) {
1456         mData = data;
1457         mDataCapacity = desired;
1458     }
1459     
1460     mDataSize = mDataPos = 0;
1461     ALOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
1462     ALOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
1463         
1464     free(mObjects);
1465     mObjects = NULL;
1466     mObjectsSize = mObjectsCapacity = 0;
1467     mNextObjectHint = 0;
1468     mHasFds = false;
1469     mFdsKnown = true;
1470     mAllowFds = true;
1471     
1472     return NO_ERROR;
1473 }
1474
1475 status_t Parcel::continueWrite(size_t desired)
1476 {
1477     // If shrinking, first adjust for any objects that appear
1478     // after the new data size.
1479     size_t objectsSize = mObjectsSize;
1480     if (desired < mDataSize) {
1481         if (desired == 0) {
1482             objectsSize = 0;
1483         } else {
1484             while (objectsSize > 0) {
1485                 if (mObjects[objectsSize-1] < desired)
1486                     break;
1487                 objectsSize--;
1488             }
1489         }
1490     }
1491     
1492     if (mOwner) {
1493         // If the size is going to zero, just release the owner's data.
1494         if (desired == 0) {
1495             freeData();
1496             return NO_ERROR;
1497         }
1498
1499         // If there is a different owner, we need to take
1500         // posession.
1501         uint8_t* data = (uint8_t*)malloc(desired);
1502         if (!data) {
1503             mError = NO_MEMORY;
1504             return NO_MEMORY;
1505         }
1506         binder_size_t* objects = NULL;
1507         
1508         if (objectsSize) {
1509             objects = (binder_size_t*)malloc(objectsSize*sizeof(binder_size_t));
1510             if (!objects) {
1511                 free(data);
1512
1513                 mError = NO_MEMORY;
1514                 return NO_MEMORY;
1515             }
1516
1517             // Little hack to only acquire references on objects
1518             // we will be keeping.
1519             size_t oldObjectsSize = mObjectsSize;
1520             mObjectsSize = objectsSize;
1521             acquireObjects();
1522             mObjectsSize = oldObjectsSize;
1523         }
1524         
1525         if (mData) {
1526             memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
1527         }
1528         if (objects && mObjects) {
1529             memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
1530         }
1531         //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
1532         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1533         mOwner = NULL;
1534
1535         mData = data;
1536         mObjects = objects;
1537         mDataSize = (mDataSize < desired) ? mDataSize : desired;
1538         ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1539         mDataCapacity = desired;
1540         mObjectsSize = mObjectsCapacity = objectsSize;
1541         mNextObjectHint = 0;
1542
1543     } else if (mData) {
1544         if (objectsSize < mObjectsSize) {
1545             // Need to release refs on any objects we are dropping.
1546             const sp<ProcessState> proc(ProcessState::self());
1547             for (size_t i=objectsSize; i<mObjectsSize; i++) {
1548                 const flat_binder_object* flat
1549                     = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1550                 if (flat->type == BINDER_TYPE_FD) {
1551                     // will need to rescan because we may have lopped off the only FDs
1552                     mFdsKnown = false;
1553                 }
1554                 release_object(proc, *flat, this);
1555             }
1556             binder_size_t* objects =
1557                 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
1558             if (objects) {
1559                 mObjects = objects;
1560             }
1561             mObjectsSize = objectsSize;
1562             mNextObjectHint = 0;
1563         }
1564
1565         // We own the data, so we can just do a realloc().
1566         if (desired > mDataCapacity) {
1567             uint8_t* data = (uint8_t*)realloc(mData, desired);
1568             if (data) {
1569                 mData = data;
1570                 mDataCapacity = desired;
1571             } else if (desired > mDataCapacity) {
1572                 mError = NO_MEMORY;
1573                 return NO_MEMORY;
1574             }
1575         } else {
1576             if (mDataSize > desired) {
1577                 mDataSize = desired;
1578                 ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1579             }
1580             if (mDataPos > desired) {
1581                 mDataPos = desired;
1582                 ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
1583             }
1584         }
1585         
1586     } else {
1587         // This is the first data.  Easy!
1588         uint8_t* data = (uint8_t*)malloc(desired);
1589         if (!data) {
1590             mError = NO_MEMORY;
1591             return NO_MEMORY;
1592         }
1593
1594         if(!(mDataCapacity == 0 && mObjects == NULL
1595              && mObjectsCapacity == 0)) {
1596             ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
1597         }
1598         
1599         mData = data;
1600         mDataSize = mDataPos = 0;
1601         ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
1602         ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
1603         mDataCapacity = desired;
1604     }
1605
1606     return NO_ERROR;
1607 }
1608
1609 void Parcel::initState()
1610 {
1611     mError = NO_ERROR;
1612     mData = 0;
1613     mDataSize = 0;
1614     mDataCapacity = 0;
1615     mDataPos = 0;
1616     ALOGV("initState Setting data size of %p to %d\n", this, mDataSize);
1617     ALOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
1618     mObjects = NULL;
1619     mObjectsSize = 0;
1620     mObjectsCapacity = 0;
1621     mNextObjectHint = 0;
1622     mHasFds = false;
1623     mFdsKnown = true;
1624     mAllowFds = true;
1625     mOwner = NULL;
1626 }
1627
1628 void Parcel::scanForFds() const
1629 {
1630     bool hasFds = false;
1631     for (size_t i=0; i<mObjectsSize; i++) {
1632         const flat_binder_object* flat
1633             = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
1634         if (flat->type == BINDER_TYPE_FD) {
1635             hasFds = true;
1636             break;
1637         }
1638     }
1639     mHasFds = hasFds;
1640     mFdsKnown = true;
1641 }
1642
1643 // --- Parcel::Blob ---
1644
1645 Parcel::Blob::Blob() :
1646         mMapped(false), mData(NULL), mSize(0) {
1647 }
1648
1649 Parcel::Blob::~Blob() {
1650     release();
1651 }
1652
1653 void Parcel::Blob::release() {
1654     if (mMapped && mData) {
1655         ::munmap(mData, mSize);
1656     }
1657     clear();
1658 }
1659
1660 void Parcel::Blob::init(bool mapped, void* data, size_t size) {
1661     mMapped = mapped;
1662     mData = data;
1663     mSize = size;
1664 }
1665
1666 void Parcel::Blob::clear() {
1667     mMapped = false;
1668     mData = NULL;
1669     mSize = 0;
1670 }
1671
1672 }; // namespace android