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