Parcel.cpp revision 451ff582d730e27f4e22d9f158f8ee24d1bc2729
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 <errno.h>
29#include <utils/Debug.h>
30#include <utils/Log.h>
31#include <utils/String8.h>
32#include <utils/String16.h>
33#include <utils/misc.h>
34#include <utils/Flattenable.h>
35#include <cutils/ashmem.h>
36
37#include <private/binder/binder_module.h>
38#include <private/binder/Static.h>
39
40#include <inttypes.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <stdint.h>
44#include <sys/mman.h>
45
46#ifndef INT32_MAX
47#define INT32_MAX ((int32_t)(2147483647))
48#endif
49
50#define LOG_REFS(...)
51//#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
52#define LOG_ALLOC(...)
53//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
54
55// ---------------------------------------------------------------------------
56
57// This macro should never be used at runtime, as a too large value
58// of s could cause an integer overflow. Instead, you should always
59// use the wrapper function pad_size()
60#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
61
62static size_t pad_size(size_t s) {
63    if (s > (SIZE_T_MAX - 3)) {
64        abort();
65    }
66    return PAD_SIZE_UNSAFE(s);
67}
68
69// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
70#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
71
72// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
73#define EX_HAS_REPLY_HEADER -128
74
75// XXX This can be made public if we want to provide
76// support for typed data.
77struct small_flat_data
78{
79    uint32_t type;
80    uint32_t data;
81};
82
83namespace android {
84
85static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
86static size_t gParcelGlobalAllocSize = 0;
87static size_t gParcelGlobalAllocCount = 0;
88
89// Maximum size of a blob to transfer in-place.
90static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
91
92enum {
93    BLOB_INPLACE = 0,
94    BLOB_ASHMEM_IMMUTABLE = 1,
95    BLOB_ASHMEM_MUTABLE = 2,
96};
97
98void acquire_object(const sp<ProcessState>& proc,
99    const flat_binder_object& obj, const void* who)
100{
101    switch (obj.type) {
102        case BINDER_TYPE_BINDER:
103            if (obj.binder) {
104                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
105                reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
106            }
107            return;
108        case BINDER_TYPE_WEAK_BINDER:
109            if (obj.binder)
110                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
111            return;
112        case BINDER_TYPE_HANDLE: {
113            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
114            if (b != NULL) {
115                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
116                b->incStrong(who);
117            }
118            return;
119        }
120        case BINDER_TYPE_WEAK_HANDLE: {
121            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
122            if (b != NULL) b.get_refs()->incWeak(who);
123            return;
124        }
125        case BINDER_TYPE_FD: {
126            // intentionally blank -- nothing to do to acquire this, but we do
127            // recognize it as a legitimate object type.
128            return;
129        }
130    }
131
132    ALOGD("Invalid object type 0x%08x", obj.type);
133}
134
135void release_object(const sp<ProcessState>& proc,
136    const flat_binder_object& obj, const void* who)
137{
138    switch (obj.type) {
139        case BINDER_TYPE_BINDER:
140            if (obj.binder) {
141                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
142                reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
143            }
144            return;
145        case BINDER_TYPE_WEAK_BINDER:
146            if (obj.binder)
147                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
148            return;
149        case BINDER_TYPE_HANDLE: {
150            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
151            if (b != NULL) {
152                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
153                b->decStrong(who);
154            }
155            return;
156        }
157        case BINDER_TYPE_WEAK_HANDLE: {
158            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
159            if (b != NULL) b.get_refs()->decWeak(who);
160            return;
161        }
162        case BINDER_TYPE_FD: {
163            if (obj.cookie != 0) close(obj.handle);
164            return;
165        }
166    }
167
168    ALOGE("Invalid object type 0x%08x", obj.type);
169}
170
171inline static status_t finish_flatten_binder(
172    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
173{
174    return out->writeObject(flat, false);
175}
176
177status_t flatten_binder(const sp<ProcessState>& /*proc*/,
178    const sp<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        IBinder *local = binder->localBinder();
185        if (!local) {
186            BpBinder *proxy = binder->remoteBinder();
187            if (proxy == NULL) {
188                ALOGE("null proxy");
189            }
190            const int32_t handle = proxy ? proxy->handle() : 0;
191            obj.type = BINDER_TYPE_HANDLE;
192            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
193            obj.handle = handle;
194            obj.cookie = 0;
195        } else {
196            obj.type = BINDER_TYPE_BINDER;
197            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
198            obj.cookie = reinterpret_cast<uintptr_t>(local);
199        }
200    } else {
201        obj.type = BINDER_TYPE_BINDER;
202        obj.binder = 0;
203        obj.cookie = 0;
204    }
205
206    return finish_flatten_binder(binder, obj, out);
207}
208
209status_t flatten_binder(const sp<ProcessState>& /*proc*/,
210    const wp<IBinder>& binder, Parcel* out)
211{
212    flat_binder_object obj;
213
214    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
215    if (binder != NULL) {
216        sp<IBinder> real = binder.promote();
217        if (real != NULL) {
218            IBinder *local = real->localBinder();
219            if (!local) {
220                BpBinder *proxy = real->remoteBinder();
221                if (proxy == NULL) {
222                    ALOGE("null proxy");
223                }
224                const int32_t handle = proxy ? proxy->handle() : 0;
225                obj.type = BINDER_TYPE_WEAK_HANDLE;
226                obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
227                obj.handle = handle;
228                obj.cookie = 0;
229            } else {
230                obj.type = BINDER_TYPE_WEAK_BINDER;
231                obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
232                obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
233            }
234            return finish_flatten_binder(real, obj, out);
235        }
236
237        // XXX How to deal?  In order to flatten the given binder,
238        // we need to probe it for information, which requires a primary
239        // reference...  but we don't have one.
240        //
241        // The OpenBinder implementation uses a dynamic_cast<> here,
242        // but we can't do that with the different reference counting
243        // implementation we are using.
244        ALOGE("Unable to unflatten Binder weak reference!");
245        obj.type = BINDER_TYPE_BINDER;
246        obj.binder = 0;
247        obj.cookie = 0;
248        return finish_flatten_binder(NULL, obj, out);
249
250    } else {
251        obj.type = BINDER_TYPE_BINDER;
252        obj.binder = 0;
253        obj.cookie = 0;
254        return finish_flatten_binder(NULL, obj, out);
255    }
256}
257
258inline static status_t finish_unflatten_binder(
259    BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
260    const Parcel& /*in*/)
261{
262    return NO_ERROR;
263}
264
265status_t unflatten_binder(const sp<ProcessState>& proc,
266    const Parcel& in, sp<IBinder>* out)
267{
268    const flat_binder_object* flat = in.readObject(false);
269
270    if (flat) {
271        switch (flat->type) {
272            case BINDER_TYPE_BINDER:
273                *out = reinterpret_cast<IBinder*>(flat->cookie);
274                return finish_unflatten_binder(NULL, *flat, in);
275            case BINDER_TYPE_HANDLE:
276                *out = proc->getStrongProxyForHandle(flat->handle);
277                return finish_unflatten_binder(
278                    static_cast<BpBinder*>(out->get()), *flat, in);
279        }
280    }
281    return BAD_TYPE;
282}
283
284status_t unflatten_binder(const sp<ProcessState>& proc,
285    const Parcel& in, wp<IBinder>* out)
286{
287    const flat_binder_object* flat = in.readObject(false);
288
289    if (flat) {
290        switch (flat->type) {
291            case BINDER_TYPE_BINDER:
292                *out = reinterpret_cast<IBinder*>(flat->cookie);
293                return finish_unflatten_binder(NULL, *flat, in);
294            case BINDER_TYPE_WEAK_BINDER:
295                if (flat->binder != 0) {
296                    out->set_object_and_refs(
297                        reinterpret_cast<IBinder*>(flat->cookie),
298                        reinterpret_cast<RefBase::weakref_type*>(flat->binder));
299                } else {
300                    *out = NULL;
301                }
302                return finish_unflatten_binder(NULL, *flat, in);
303            case BINDER_TYPE_HANDLE:
304            case BINDER_TYPE_WEAK_HANDLE:
305                *out = proc->getWeakProxyForHandle(flat->handle);
306                return finish_unflatten_binder(
307                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
308        }
309    }
310    return BAD_TYPE;
311}
312
313// ---------------------------------------------------------------------------
314
315Parcel::Parcel()
316{
317    LOG_ALLOC("Parcel %p: constructing", this);
318    initState();
319}
320
321Parcel::~Parcel()
322{
323    freeDataNoInit();
324    LOG_ALLOC("Parcel %p: destroyed", this);
325}
326
327size_t Parcel::getGlobalAllocSize() {
328    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
329    size_t size = gParcelGlobalAllocSize;
330    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
331    return size;
332}
333
334size_t Parcel::getGlobalAllocCount() {
335    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
336    size_t count = gParcelGlobalAllocCount;
337    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
338    return count;
339}
340
341const uint8_t* Parcel::data() const
342{
343    return mData;
344}
345
346size_t Parcel::dataSize() const
347{
348    return (mDataSize > mDataPos ? mDataSize : mDataPos);
349}
350
351size_t Parcel::dataAvail() const
352{
353    // TODO: decide what to do about the possibility that this can
354    // report an available-data size that exceeds a Java int's max
355    // positive value, causing havoc.  Fortunately this will only
356    // happen if someone constructs a Parcel containing more than two
357    // gigabytes of data, which on typical phone hardware is simply
358    // not possible.
359    return dataSize() - dataPosition();
360}
361
362size_t Parcel::dataPosition() const
363{
364    return mDataPos;
365}
366
367size_t Parcel::dataCapacity() const
368{
369    return mDataCapacity;
370}
371
372status_t Parcel::setDataSize(size_t size)
373{
374    if (size > INT32_MAX) {
375        // don't accept size_t values which may have come from an
376        // inadvertent conversion from a negative int.
377        return BAD_VALUE;
378    }
379
380    status_t err;
381    err = continueWrite(size);
382    if (err == NO_ERROR) {
383        mDataSize = size;
384        ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
385    }
386    return err;
387}
388
389void Parcel::setDataPosition(size_t pos) const
390{
391    if (pos > INT32_MAX) {
392        // don't accept size_t values which may have come from an
393        // inadvertent conversion from a negative int.
394        abort();
395    }
396
397    mDataPos = pos;
398    mNextObjectHint = 0;
399}
400
401status_t Parcel::setDataCapacity(size_t size)
402{
403    if (size > INT32_MAX) {
404        // don't accept size_t values which may have come from an
405        // inadvertent conversion from a negative int.
406        return BAD_VALUE;
407    }
408
409    if (size > mDataCapacity) return continueWrite(size);
410    return NO_ERROR;
411}
412
413status_t Parcel::setData(const uint8_t* buffer, size_t len)
414{
415    if (len > INT32_MAX) {
416        // don't accept size_t values which may have come from an
417        // inadvertent conversion from a negative int.
418        return BAD_VALUE;
419    }
420
421    status_t err = restartWrite(len);
422    if (err == NO_ERROR) {
423        memcpy(const_cast<uint8_t*>(data()), buffer, len);
424        mDataSize = len;
425        mFdsKnown = false;
426    }
427    return err;
428}
429
430status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
431{
432    const sp<ProcessState> proc(ProcessState::self());
433    status_t err;
434    const uint8_t *data = parcel->mData;
435    const binder_size_t *objects = parcel->mObjects;
436    size_t size = parcel->mObjectsSize;
437    int startPos = mDataPos;
438    int firstIndex = -1, lastIndex = -2;
439
440    if (len == 0) {
441        return NO_ERROR;
442    }
443
444    if (len > INT32_MAX) {
445        // don't accept size_t values which may have come from an
446        // inadvertent conversion from a negative int.
447        return BAD_VALUE;
448    }
449
450    // range checks against the source parcel size
451    if ((offset > parcel->mDataSize)
452            || (len > parcel->mDataSize)
453            || (offset + len > parcel->mDataSize)) {
454        return BAD_VALUE;
455    }
456
457    // Count objects in range
458    for (int i = 0; i < (int) size; i++) {
459        size_t off = objects[i];
460        if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
461            if (firstIndex == -1) {
462                firstIndex = i;
463            }
464            lastIndex = i;
465        }
466    }
467    int numObjects = lastIndex - firstIndex + 1;
468
469    if ((mDataSize+len) > mDataCapacity) {
470        // grow data
471        err = growData(len);
472        if (err != NO_ERROR) {
473            return err;
474        }
475    }
476
477    // append data
478    memcpy(mData + mDataPos, data + offset, len);
479    mDataPos += len;
480    mDataSize += len;
481
482    err = NO_ERROR;
483
484    if (numObjects > 0) {
485        // grow objects
486        if (mObjectsCapacity < mObjectsSize + numObjects) {
487            size_t newSize = ((mObjectsSize + numObjects)*3)/2;
488            if (newSize < mObjectsSize) return NO_MEMORY;   // overflow
489            binder_size_t *objects =
490                (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
491            if (objects == (binder_size_t*)0) {
492                return NO_MEMORY;
493            }
494            mObjects = objects;
495            mObjectsCapacity = newSize;
496        }
497
498        // append and acquire objects
499        int idx = mObjectsSize;
500        for (int i = firstIndex; i <= lastIndex; i++) {
501            size_t off = objects[i] - offset + startPos;
502            mObjects[idx++] = off;
503            mObjectsSize++;
504
505            flat_binder_object* flat
506                = reinterpret_cast<flat_binder_object*>(mData + off);
507            acquire_object(proc, *flat, this);
508
509            if (flat->type == BINDER_TYPE_FD) {
510                // If this is a file descriptor, we need to dup it so the
511                // new Parcel now owns its own fd, and can declare that we
512                // officially know we have fds.
513                flat->handle = dup(flat->handle);
514                flat->cookie = 1;
515                mHasFds = mFdsKnown = true;
516                if (!mAllowFds) {
517                    err = FDS_NOT_ALLOWED;
518                }
519            }
520        }
521    }
522
523    return err;
524}
525
526bool Parcel::allowFds() const
527{
528    return mAllowFds;
529}
530
531bool Parcel::pushAllowFds(bool allowFds)
532{
533    const bool origValue = mAllowFds;
534    if (!allowFds) {
535        mAllowFds = false;
536    }
537    return origValue;
538}
539
540void Parcel::restoreAllowFds(bool lastValue)
541{
542    mAllowFds = lastValue;
543}
544
545bool Parcel::hasFileDescriptors() const
546{
547    if (!mFdsKnown) {
548        scanForFds();
549    }
550    return mHasFds;
551}
552
553// Write RPC headers.  (previously just the interface token)
554status_t Parcel::writeInterfaceToken(const String16& interface)
555{
556    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
557               STRICT_MODE_PENALTY_GATHER);
558    // currently the interface identification token is just its name as a string
559    return writeString16(interface);
560}
561
562bool Parcel::checkInterface(IBinder* binder) const
563{
564    return enforceInterface(binder->getInterfaceDescriptor());
565}
566
567bool Parcel::enforceInterface(const String16& interface,
568                              IPCThreadState* threadState) const
569{
570    int32_t strictPolicy = readInt32();
571    if (threadState == NULL) {
572        threadState = IPCThreadState::self();
573    }
574    if ((threadState->getLastTransactionBinderFlags() &
575         IBinder::FLAG_ONEWAY) != 0) {
576      // For one-way calls, the callee is running entirely
577      // disconnected from the caller, so disable StrictMode entirely.
578      // Not only does disk/network usage not impact the caller, but
579      // there's no way to commuicate back any violations anyway.
580      threadState->setStrictModePolicy(0);
581    } else {
582      threadState->setStrictModePolicy(strictPolicy);
583    }
584    const String16 str(readString16());
585    if (str == interface) {
586        return true;
587    } else {
588        ALOGW("**** enforceInterface() expected '%s' but read '%s'",
589                String8(interface).string(), String8(str).string());
590        return false;
591    }
592}
593
594const binder_size_t* Parcel::objects() const
595{
596    return mObjects;
597}
598
599size_t Parcel::objectsCount() const
600{
601    return mObjectsSize;
602}
603
604status_t Parcel::errorCheck() const
605{
606    return mError;
607}
608
609void Parcel::setError(status_t err)
610{
611    mError = err;
612}
613
614status_t Parcel::finishWrite(size_t len)
615{
616    if (len > INT32_MAX) {
617        // don't accept size_t values which may have come from an
618        // inadvertent conversion from a negative int.
619        return BAD_VALUE;
620    }
621
622    //printf("Finish write of %d\n", len);
623    mDataPos += len;
624    ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
625    if (mDataPos > mDataSize) {
626        mDataSize = mDataPos;
627        ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
628    }
629    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
630    return NO_ERROR;
631}
632
633status_t Parcel::writeUnpadded(const void* data, size_t len)
634{
635    if (len > INT32_MAX) {
636        // don't accept size_t values which may have come from an
637        // inadvertent conversion from a negative int.
638        return BAD_VALUE;
639    }
640
641    size_t end = mDataPos + len;
642    if (end < mDataPos) {
643        // integer overflow
644        return BAD_VALUE;
645    }
646
647    if (end <= mDataCapacity) {
648restart_write:
649        memcpy(mData+mDataPos, data, len);
650        return finishWrite(len);
651    }
652
653    status_t err = growData(len);
654    if (err == NO_ERROR) goto restart_write;
655    return err;
656}
657
658status_t Parcel::write(const void* data, size_t len)
659{
660    if (len > INT32_MAX) {
661        // don't accept size_t values which may have come from an
662        // inadvertent conversion from a negative int.
663        return BAD_VALUE;
664    }
665
666    void* const d = writeInplace(len);
667    if (d) {
668        memcpy(d, data, len);
669        return NO_ERROR;
670    }
671    return mError;
672}
673
674void* Parcel::writeInplace(size_t len)
675{
676    if (len > INT32_MAX) {
677        // don't accept size_t values which may have come from an
678        // inadvertent conversion from a negative int.
679        return NULL;
680    }
681
682    const size_t padded = pad_size(len);
683
684    // sanity check for integer overflow
685    if (mDataPos+padded < mDataPos) {
686        return NULL;
687    }
688
689    if ((mDataPos+padded) <= mDataCapacity) {
690restart_write:
691        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
692        uint8_t* const data = mData+mDataPos;
693
694        // Need to pad at end?
695        if (padded != len) {
696#if BYTE_ORDER == BIG_ENDIAN
697            static const uint32_t mask[4] = {
698                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
699            };
700#endif
701#if BYTE_ORDER == LITTLE_ENDIAN
702            static const uint32_t mask[4] = {
703                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
704            };
705#endif
706            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
707            //    *reinterpret_cast<void**>(data+padded-4));
708            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
709        }
710
711        finishWrite(padded);
712        return data;
713    }
714
715    status_t err = growData(padded);
716    if (err == NO_ERROR) goto restart_write;
717    return NULL;
718}
719
720status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
721{
722    if (val.size() > std::numeric_limits<int32_t>::max()) {
723        return BAD_VALUE;
724    }
725
726    status_t status = writeInt32(val.size());
727
728    if (status != OK) {
729        return status;
730    }
731
732    for (const auto& item : val) {
733        status = writeByte(item);
734
735        if (status != OK) {
736            return status;
737        }
738    }
739
740    return OK;
741}
742
743status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
744{
745    if (val.size() > std::numeric_limits<int32_t>::max()) {
746        return BAD_VALUE;
747    }
748
749    status_t status = writeInt32(val.size());
750
751    if (status != OK) {
752        return status;
753    }
754
755    for (const auto& item : val) {
756        status = writeInt32(item);
757
758        if (status != OK) {
759            return status;
760        }
761    }
762
763    return OK;
764}
765
766status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
767{
768    if (val.size() > std::numeric_limits<int32_t>::max()) {
769        return BAD_VALUE;
770    }
771
772    status_t status = writeInt32(val.size());
773
774    if (status != OK) {
775        return status;
776    }
777
778    for (const auto& item : val) {
779        status = writeInt64(item);
780
781        if (status != OK) {
782            return status;
783        }
784    }
785
786    return OK;
787}
788
789status_t Parcel::writeFloatVector(const std::vector<float>& val)
790{
791    if (val.size() > std::numeric_limits<int32_t>::max()) {
792        return BAD_VALUE;
793    }
794
795    status_t status = writeInt32(val.size());
796
797    if (status != OK) {
798        return status;
799    }
800
801    for (const auto& item : val) {
802        status = writeFloat(item);
803
804        if (status != OK) {
805            return status;
806        }
807    }
808
809    return OK;
810}
811
812status_t Parcel::writeDoubleVector(const std::vector<double>& val)
813{
814    if (val.size() > std::numeric_limits<int32_t>::max()) {
815        return BAD_VALUE;
816    }
817
818    status_t status = writeInt32(val.size());
819
820    if (status != OK) {
821        return status;
822    }
823
824    for (const auto& item : val) {
825        status = writeDouble(item);
826
827        if (status != OK) {
828            return status;
829        }
830    }
831
832    return OK;
833}
834
835status_t Parcel::writeBoolVector(const std::vector<bool>& val)
836{
837    if (val.size() > std::numeric_limits<int32_t>::max()) {
838        return BAD_VALUE;
839    }
840
841    status_t status = writeInt32(val.size());
842
843    if (status != OK) {
844        return status;
845    }
846
847    for (const auto& item : val) {
848        status = writeBool(item);
849
850        if (status != OK) {
851            return status;
852        }
853    }
854
855    return OK;
856}
857
858status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
859{
860    if (val.size() > std::numeric_limits<int32_t>::max()) {
861        return BAD_VALUE;
862    }
863
864    status_t status = writeInt32(val.size());
865
866    if (status != OK) {
867        return status;
868    }
869
870    for (const auto& item : val) {
871        status = writeChar(item);
872
873        if (status != OK) {
874            return status;
875        }
876    }
877
878    return OK;
879}
880
881status_t Parcel::writeString16Vector(const std::vector<String16>& val)
882{
883    if (val.size() > std::numeric_limits<int32_t>::max()) {
884        return BAD_VALUE;
885    }
886
887    status_t status = writeInt32(val.size());
888
889    if (status != OK) {
890        return status;
891    }
892
893    for (const auto& item : val) {
894        status = writeString16(item);
895
896        if (status != OK) {
897            return status;
898        }
899    }
900
901    return OK;
902}
903
904status_t Parcel::writeInt32(int32_t val)
905{
906    return writeAligned(val);
907}
908
909status_t Parcel::writeUint32(uint32_t val)
910{
911    return writeAligned(val);
912}
913
914status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
915    if (len > INT32_MAX) {
916        // don't accept size_t values which may have come from an
917        // inadvertent conversion from a negative int.
918        return BAD_VALUE;
919    }
920
921    if (!val) {
922        return writeInt32(-1);
923    }
924    status_t ret = writeInt32(static_cast<uint32_t>(len));
925    if (ret == NO_ERROR) {
926        ret = write(val, len * sizeof(*val));
927    }
928    return ret;
929}
930status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
931    if (len > INT32_MAX) {
932        // don't accept size_t values which may have come from an
933        // inadvertent conversion from a negative int.
934        return BAD_VALUE;
935    }
936
937    if (!val) {
938        return writeInt32(-1);
939    }
940    status_t ret = writeInt32(static_cast<uint32_t>(len));
941    if (ret == NO_ERROR) {
942        ret = write(val, len * sizeof(*val));
943    }
944    return ret;
945}
946
947status_t Parcel::writeBool(bool val)
948{
949    return writeInt32(int32_t(val));
950}
951
952status_t Parcel::writeChar(char16_t val)
953{
954    return writeInt32(int32_t(val));
955}
956
957status_t Parcel::writeByte(int8_t val)
958{
959    return writeInt32(int32_t(val));
960}
961
962status_t Parcel::writeInt64(int64_t val)
963{
964    return writeAligned(val);
965}
966
967status_t Parcel::writeUint64(uint64_t val)
968{
969    return writeAligned(val);
970}
971
972status_t Parcel::writePointer(uintptr_t val)
973{
974    return writeAligned<binder_uintptr_t>(val);
975}
976
977status_t Parcel::writeFloat(float val)
978{
979    return writeAligned(val);
980}
981
982#if defined(__mips__) && defined(__mips_hard_float)
983
984status_t Parcel::writeDouble(double val)
985{
986    union {
987        double d;
988        unsigned long long ll;
989    } u;
990    u.d = val;
991    return writeAligned(u.ll);
992}
993
994#else
995
996status_t Parcel::writeDouble(double val)
997{
998    return writeAligned(val);
999}
1000
1001#endif
1002
1003status_t Parcel::writeCString(const char* str)
1004{
1005    return write(str, strlen(str)+1);
1006}
1007
1008status_t Parcel::writeString8(const String8& str)
1009{
1010    status_t err = writeInt32(str.bytes());
1011    // only write string if its length is more than zero characters,
1012    // as readString8 will only read if the length field is non-zero.
1013    // this is slightly different from how writeString16 works.
1014    if (str.bytes() > 0 && err == NO_ERROR) {
1015        err = write(str.string(), str.bytes()+1);
1016    }
1017    return err;
1018}
1019
1020status_t Parcel::writeString16(const String16& str)
1021{
1022    return writeString16(str.string(), str.size());
1023}
1024
1025status_t Parcel::writeString16(const char16_t* str, size_t len)
1026{
1027    if (str == NULL) return writeInt32(-1);
1028
1029    status_t err = writeInt32(len);
1030    if (err == NO_ERROR) {
1031        len *= sizeof(char16_t);
1032        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1033        if (data) {
1034            memcpy(data, str, len);
1035            *reinterpret_cast<char16_t*>(data+len) = 0;
1036            return NO_ERROR;
1037        }
1038        err = mError;
1039    }
1040    return err;
1041}
1042
1043status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1044{
1045    return flatten_binder(ProcessState::self(), val, this);
1046}
1047
1048status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
1049{
1050    return flatten_binder(ProcessState::self(), val, this);
1051}
1052
1053status_t Parcel::writeNativeHandle(const native_handle* handle)
1054{
1055    if (!handle || handle->version != sizeof(native_handle))
1056        return BAD_TYPE;
1057
1058    status_t err;
1059    err = writeInt32(handle->numFds);
1060    if (err != NO_ERROR) return err;
1061
1062    err = writeInt32(handle->numInts);
1063    if (err != NO_ERROR) return err;
1064
1065    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1066        err = writeDupFileDescriptor(handle->data[i]);
1067
1068    if (err != NO_ERROR) {
1069        ALOGD("write native handle, write dup fd failed");
1070        return err;
1071    }
1072    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
1073    return err;
1074}
1075
1076status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
1077{
1078    flat_binder_object obj;
1079    obj.type = BINDER_TYPE_FD;
1080    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
1081    obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
1082    obj.handle = fd;
1083    obj.cookie = takeOwnership ? 1 : 0;
1084    return writeObject(obj, true);
1085}
1086
1087status_t Parcel::writeDupFileDescriptor(int fd)
1088{
1089    int dupFd = dup(fd);
1090    if (dupFd < 0) {
1091        return -errno;
1092    }
1093    status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
1094    if (err) {
1095        close(dupFd);
1096    }
1097    return err;
1098}
1099
1100status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
1101{
1102    if (len > INT32_MAX) {
1103        // don't accept size_t values which may have come from an
1104        // inadvertent conversion from a negative int.
1105        return BAD_VALUE;
1106    }
1107
1108    status_t status;
1109    if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
1110        ALOGV("writeBlob: write in place");
1111        status = writeInt32(BLOB_INPLACE);
1112        if (status) return status;
1113
1114        void* ptr = writeInplace(len);
1115        if (!ptr) return NO_MEMORY;
1116
1117        outBlob->init(-1, ptr, len, false);
1118        return NO_ERROR;
1119    }
1120
1121    ALOGV("writeBlob: write to ashmem");
1122    int fd = ashmem_create_region("Parcel Blob", len);
1123    if (fd < 0) return NO_MEMORY;
1124
1125    mBlobAshmemSize += len;
1126
1127    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1128    if (result < 0) {
1129        status = result;
1130    } else {
1131        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1132        if (ptr == MAP_FAILED) {
1133            status = -errno;
1134        } else {
1135            if (!mutableCopy) {
1136                result = ashmem_set_prot_region(fd, PROT_READ);
1137            }
1138            if (result < 0) {
1139                status = result;
1140            } else {
1141                status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
1142                if (!status) {
1143                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
1144                    if (!status) {
1145                        outBlob->init(fd, ptr, len, mutableCopy);
1146                        return NO_ERROR;
1147                    }
1148                }
1149            }
1150        }
1151        ::munmap(ptr, len);
1152    }
1153    ::close(fd);
1154    return status;
1155}
1156
1157status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1158{
1159    // Must match up with what's done in writeBlob.
1160    if (!mAllowFds) return FDS_NOT_ALLOWED;
1161    status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1162    if (status) return status;
1163    return writeDupFileDescriptor(fd);
1164}
1165
1166status_t Parcel::write(const FlattenableHelperInterface& val)
1167{
1168    status_t err;
1169
1170    // size if needed
1171    const size_t len = val.getFlattenedSize();
1172    const size_t fd_count = val.getFdCount();
1173
1174    if ((len > INT32_MAX) || (fd_count > INT32_MAX)) {
1175        // don't accept size_t values which may have come from an
1176        // inadvertent conversion from a negative int.
1177        return BAD_VALUE;
1178    }
1179
1180    err = this->writeInt32(len);
1181    if (err) return err;
1182
1183    err = this->writeInt32(fd_count);
1184    if (err) return err;
1185
1186    // payload
1187    void* const buf = this->writeInplace(pad_size(len));
1188    if (buf == NULL)
1189        return BAD_VALUE;
1190
1191    int* fds = NULL;
1192    if (fd_count) {
1193        fds = new int[fd_count];
1194    }
1195
1196    err = val.flatten(buf, len, fds, fd_count);
1197    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1198        err = this->writeDupFileDescriptor( fds[i] );
1199    }
1200
1201    if (fd_count) {
1202        delete [] fds;
1203    }
1204
1205    return err;
1206}
1207
1208status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1209{
1210    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1211    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1212    if (enoughData && enoughObjects) {
1213restart_write:
1214        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
1215
1216        // remember if it's a file descriptor
1217        if (val.type == BINDER_TYPE_FD) {
1218            if (!mAllowFds) {
1219                // fail before modifying our object index
1220                return FDS_NOT_ALLOWED;
1221            }
1222            mHasFds = mFdsKnown = true;
1223        }
1224
1225        // Need to write meta-data?
1226        if (nullMetaData || val.binder != 0) {
1227            mObjects[mObjectsSize] = mDataPos;
1228            acquire_object(ProcessState::self(), val, this);
1229            mObjectsSize++;
1230        }
1231
1232        return finishWrite(sizeof(flat_binder_object));
1233    }
1234
1235    if (!enoughData) {
1236        const status_t err = growData(sizeof(val));
1237        if (err != NO_ERROR) return err;
1238    }
1239    if (!enoughObjects) {
1240        size_t newSize = ((mObjectsSize+2)*3)/2;
1241        if (newSize < mObjectsSize) return NO_MEMORY;   // overflow
1242        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
1243        if (objects == NULL) return NO_MEMORY;
1244        mObjects = objects;
1245        mObjectsCapacity = newSize;
1246    }
1247
1248    goto restart_write;
1249}
1250
1251status_t Parcel::writeNoException()
1252{
1253    return writeInt32(0);
1254}
1255
1256void Parcel::remove(size_t /*start*/, size_t /*amt*/)
1257{
1258    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
1259}
1260
1261status_t Parcel::read(void* outData, size_t len) const
1262{
1263    if (len > INT32_MAX) {
1264        // don't accept size_t values which may have come from an
1265        // inadvertent conversion from a negative int.
1266        return BAD_VALUE;
1267    }
1268
1269    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1270            && len <= pad_size(len)) {
1271        memcpy(outData, mData+mDataPos, len);
1272        mDataPos += pad_size(len);
1273        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1274        return NO_ERROR;
1275    }
1276    return NOT_ENOUGH_DATA;
1277}
1278
1279const void* Parcel::readInplace(size_t len) const
1280{
1281    if (len > INT32_MAX) {
1282        // don't accept size_t values which may have come from an
1283        // inadvertent conversion from a negative int.
1284        return NULL;
1285    }
1286
1287    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1288            && len <= pad_size(len)) {
1289        const void* data = mData+mDataPos;
1290        mDataPos += pad_size(len);
1291        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
1292        return data;
1293    }
1294    return NULL;
1295}
1296
1297template<class T>
1298status_t Parcel::readAligned(T *pArg) const {
1299    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
1300
1301    if ((mDataPos+sizeof(T)) <= mDataSize) {
1302        const void* data = mData+mDataPos;
1303        mDataPos += sizeof(T);
1304        *pArg =  *reinterpret_cast<const T*>(data);
1305        return NO_ERROR;
1306    } else {
1307        return NOT_ENOUGH_DATA;
1308    }
1309}
1310
1311template<class T>
1312T Parcel::readAligned() const {
1313    T result;
1314    if (readAligned(&result) != NO_ERROR) {
1315        result = 0;
1316    }
1317
1318    return result;
1319}
1320
1321template<class T>
1322status_t Parcel::writeAligned(T val) {
1323    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
1324
1325    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1326restart_write:
1327        *reinterpret_cast<T*>(mData+mDataPos) = val;
1328        return finishWrite(sizeof(val));
1329    }
1330
1331    status_t err = growData(sizeof(val));
1332    if (err == NO_ERROR) goto restart_write;
1333    return err;
1334}
1335
1336status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1337    val->clear();
1338
1339    int32_t size;
1340    status_t status = readInt32(&size);
1341
1342    if (status != OK) {
1343        return status;
1344    }
1345
1346    if (size < 0) {
1347        return BAD_VALUE;
1348    }
1349
1350    val->resize(size);
1351
1352    for (auto& v : *val) {
1353        status = readByte(&v);
1354
1355        if (status != OK) {
1356            return status;
1357        }
1358    }
1359
1360    return OK;
1361}
1362
1363status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
1364    val->clear();
1365
1366    int32_t size;
1367    status_t status = readInt32(&size);
1368
1369    if (status != OK) {
1370        return status;
1371    }
1372
1373    if (size < 0) {
1374        return BAD_VALUE;
1375    }
1376
1377    val->resize(size);
1378
1379    for (auto& v: *val) {
1380        status = readInt32(&v);
1381
1382        if (status != OK) {
1383            return status;
1384        }
1385    }
1386
1387    return OK;
1388}
1389
1390status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
1391    val->clear();
1392
1393    int32_t size;
1394    status_t status = readInt32(&size);
1395
1396    if (status != OK) {
1397        return status;
1398    }
1399
1400    if (size < 0) {
1401        return BAD_VALUE;
1402    }
1403
1404    val->resize(size);
1405
1406    for (auto& v : *val) {
1407        status = readInt64(&v);
1408
1409        if (status != OK) {
1410            return status;
1411        }
1412    }
1413
1414    return OK;
1415}
1416
1417status_t Parcel::readFloatVector(std::vector<float>* val) const {
1418    val->clear();
1419
1420    int32_t size;
1421    status_t status = readInt32(&size);
1422
1423    if (status != OK) {
1424        return status;
1425    }
1426
1427    if (size < 0) {
1428        return BAD_VALUE;
1429    }
1430
1431    val->resize(size);
1432
1433    for (auto& v : *val) {
1434        status = readFloat(&v);
1435
1436        if (status != OK) {
1437            return status;
1438        }
1439    }
1440
1441    return OK;
1442}
1443
1444status_t Parcel::readDoubleVector(std::vector<double>* val) const {
1445    val->clear();
1446
1447    int32_t size;
1448    status_t status = readInt32(&size);
1449
1450    if (status != OK) {
1451        return status;
1452    }
1453
1454    if (size < 0) {
1455        return BAD_VALUE;
1456    }
1457
1458    val->resize(size);
1459
1460    for (auto& v : *val) {
1461        status = readDouble(&v);
1462
1463        if (status != OK) {
1464            return status;
1465        }
1466    }
1467
1468    return OK;
1469}
1470
1471status_t Parcel::readBoolVector(std::vector<bool>* val) const {
1472    val->clear();
1473
1474    int32_t size;
1475    status_t status = readInt32(&size);
1476
1477    if (status != OK) {
1478        return status;
1479    }
1480
1481    if (size < 0) {
1482        return BAD_VALUE;
1483    }
1484
1485    val->resize(size);
1486
1487    /* C++ bool handling means a vector of bools isn't necessarily addressable
1488     * (we might use individual bits)
1489     */
1490    for (int32_t i = 0; i < size; size++) {
1491        bool data;
1492        status = readBool(&data);
1493        (*val)[i] = data;
1494
1495        if (status != OK) {
1496            return status;
1497        }
1498    }
1499
1500    return OK;
1501}
1502
1503status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
1504    val->clear();
1505
1506    int32_t size;
1507    status_t status = readInt32(&size);
1508
1509    if (status != OK) {
1510        return status;
1511    }
1512
1513    if (size < 0) {
1514        return BAD_VALUE;
1515    }
1516
1517    val->resize(size);
1518
1519    for (auto& v : *val) {
1520        status = readChar(&v);
1521
1522        if (status != OK) {
1523            return status;
1524        }
1525    }
1526
1527    return OK;
1528}
1529
1530status_t Parcel::readString16Vector(std::vector<String16>* val) const {
1531    val->clear();
1532
1533    int32_t size;
1534    status_t status = readInt32(&size);
1535
1536    if (status != OK) {
1537        return status;
1538    }
1539
1540    if (size < 0) {
1541        return BAD_VALUE;
1542    }
1543
1544    val->reserve(size);
1545
1546    while (size-- > 0) {
1547        const char16_t *data;
1548        size_t size;
1549        data = readString16Inplace(&size);
1550
1551        if (data == nullptr) {
1552            return UNKNOWN_ERROR;
1553        }
1554
1555        val->emplace_back(data, size);
1556    }
1557
1558    return OK;
1559}
1560
1561
1562status_t Parcel::readInt32(int32_t *pArg) const
1563{
1564    return readAligned(pArg);
1565}
1566
1567int32_t Parcel::readInt32() const
1568{
1569    return readAligned<int32_t>();
1570}
1571
1572status_t Parcel::readUint32(uint32_t *pArg) const
1573{
1574    return readAligned(pArg);
1575}
1576
1577uint32_t Parcel::readUint32() const
1578{
1579    return readAligned<uint32_t>();
1580}
1581
1582status_t Parcel::readInt64(int64_t *pArg) const
1583{
1584    return readAligned(pArg);
1585}
1586
1587
1588int64_t Parcel::readInt64() const
1589{
1590    return readAligned<int64_t>();
1591}
1592
1593status_t Parcel::readUint64(uint64_t *pArg) const
1594{
1595    return readAligned(pArg);
1596}
1597
1598uint64_t Parcel::readUint64() const
1599{
1600    return readAligned<uint64_t>();
1601}
1602
1603status_t Parcel::readPointer(uintptr_t *pArg) const
1604{
1605    status_t ret;
1606    binder_uintptr_t ptr;
1607    ret = readAligned(&ptr);
1608    if (!ret)
1609        *pArg = ptr;
1610    return ret;
1611}
1612
1613uintptr_t Parcel::readPointer() const
1614{
1615    return readAligned<binder_uintptr_t>();
1616}
1617
1618
1619status_t Parcel::readFloat(float *pArg) const
1620{
1621    return readAligned(pArg);
1622}
1623
1624
1625float Parcel::readFloat() const
1626{
1627    return readAligned<float>();
1628}
1629
1630#if defined(__mips__) && defined(__mips_hard_float)
1631
1632status_t Parcel::readDouble(double *pArg) const
1633{
1634    union {
1635      double d;
1636      unsigned long long ll;
1637    } u;
1638    u.d = 0;
1639    status_t status;
1640    status = readAligned(&u.ll);
1641    *pArg = u.d;
1642    return status;
1643}
1644
1645double Parcel::readDouble() const
1646{
1647    union {
1648      double d;
1649      unsigned long long ll;
1650    } u;
1651    u.ll = readAligned<unsigned long long>();
1652    return u.d;
1653}
1654
1655#else
1656
1657status_t Parcel::readDouble(double *pArg) const
1658{
1659    return readAligned(pArg);
1660}
1661
1662double Parcel::readDouble() const
1663{
1664    return readAligned<double>();
1665}
1666
1667#endif
1668
1669status_t Parcel::readIntPtr(intptr_t *pArg) const
1670{
1671    return readAligned(pArg);
1672}
1673
1674
1675intptr_t Parcel::readIntPtr() const
1676{
1677    return readAligned<intptr_t>();
1678}
1679
1680status_t Parcel::readBool(bool *pArg) const
1681{
1682    int32_t tmp;
1683    status_t ret = readInt32(&tmp);
1684    *pArg = (tmp != 0);
1685    return ret;
1686}
1687
1688bool Parcel::readBool() const
1689{
1690    return readInt32() != 0;
1691}
1692
1693status_t Parcel::readChar(char16_t *pArg) const
1694{
1695    int32_t tmp;
1696    status_t ret = readInt32(&tmp);
1697    *pArg = char16_t(tmp);
1698    return ret;
1699}
1700
1701char16_t Parcel::readChar() const
1702{
1703    return char16_t(readInt32());
1704}
1705
1706status_t Parcel::readByte(int8_t *pArg) const
1707{
1708    int32_t tmp;
1709    status_t ret = readInt32(&tmp);
1710    *pArg = int8_t(tmp);
1711    return ret;
1712}
1713
1714int8_t Parcel::readByte() const
1715{
1716    return int8_t(readInt32());
1717}
1718
1719const char* Parcel::readCString() const
1720{
1721    const size_t avail = mDataSize-mDataPos;
1722    if (avail > 0) {
1723        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1724        // is the string's trailing NUL within the parcel's valid bounds?
1725        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1726        if (eos) {
1727            const size_t len = eos - str;
1728            mDataPos += pad_size(len+1);
1729            ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
1730            return str;
1731        }
1732    }
1733    return NULL;
1734}
1735
1736String8 Parcel::readString8() const
1737{
1738    int32_t size = readInt32();
1739    // watch for potential int overflow adding 1 for trailing NUL
1740    if (size > 0 && size < INT32_MAX) {
1741        const char* str = (const char*)readInplace(size+1);
1742        if (str) return String8(str, size);
1743    }
1744    return String8();
1745}
1746
1747String16 Parcel::readString16() const
1748{
1749    size_t len;
1750    const char16_t* str = readString16Inplace(&len);
1751    if (str) return String16(str, len);
1752    ALOGE("Reading a NULL string not supported here.");
1753    return String16();
1754}
1755
1756status_t Parcel::readString16(String16* pArg) const
1757{
1758    size_t len;
1759    const char16_t* str = readString16Inplace(&len);
1760    if (str) {
1761        *pArg->setTo(str, len);
1762        return 0;
1763    } else {
1764        *pArg = String16();
1765        return UNKNOWN_ERROR;
1766    }
1767}
1768
1769const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1770{
1771    int32_t size = readInt32();
1772    // watch for potential int overflow from size+1
1773    if (size >= 0 && size < INT32_MAX) {
1774        *outLen = size;
1775        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1776        if (str != NULL) {
1777            return str;
1778        }
1779    }
1780    *outLen = 0;
1781    return NULL;
1782}
1783
1784sp<IBinder> Parcel::readStrongBinder() const
1785{
1786    sp<IBinder> val;
1787    unflatten_binder(ProcessState::self(), *this, &val);
1788    return val;
1789}
1790
1791wp<IBinder> Parcel::readWeakBinder() const
1792{
1793    wp<IBinder> val;
1794    unflatten_binder(ProcessState::self(), *this, &val);
1795    return val;
1796}
1797
1798int32_t Parcel::readExceptionCode() const
1799{
1800  int32_t exception_code = readAligned<int32_t>();
1801  if (exception_code == EX_HAS_REPLY_HEADER) {
1802    int32_t header_start = dataPosition();
1803    int32_t header_size = readAligned<int32_t>();
1804    // Skip over fat responses headers.  Not used (or propagated) in
1805    // native code
1806    setDataPosition(header_start + header_size);
1807    // And fat response headers are currently only used when there are no
1808    // exceptions, so return no error:
1809    return 0;
1810  }
1811  return exception_code;
1812}
1813
1814native_handle* Parcel::readNativeHandle() const
1815{
1816    int numFds, numInts;
1817    status_t err;
1818    err = readInt32(&numFds);
1819    if (err != NO_ERROR) return 0;
1820    err = readInt32(&numInts);
1821    if (err != NO_ERROR) return 0;
1822
1823    native_handle* h = native_handle_create(numFds, numInts);
1824    if (!h) {
1825        return 0;
1826    }
1827
1828    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1829        h->data[i] = dup(readFileDescriptor());
1830        if (h->data[i] < 0) err = BAD_VALUE;
1831    }
1832    err = read(h->data + numFds, sizeof(int)*numInts);
1833    if (err != NO_ERROR) {
1834        native_handle_close(h);
1835        native_handle_delete(h);
1836        h = 0;
1837    }
1838    return h;
1839}
1840
1841
1842int Parcel::readFileDescriptor() const
1843{
1844    const flat_binder_object* flat = readObject(true);
1845    if (flat) {
1846        switch (flat->type) {
1847            case BINDER_TYPE_FD:
1848                //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
1849                return flat->handle;
1850        }
1851    }
1852    return BAD_TYPE;
1853}
1854
1855status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
1856{
1857    int32_t blobType;
1858    status_t status = readInt32(&blobType);
1859    if (status) return status;
1860
1861    if (blobType == BLOB_INPLACE) {
1862        ALOGV("readBlob: read in place");
1863        const void* ptr = readInplace(len);
1864        if (!ptr) return BAD_VALUE;
1865
1866        outBlob->init(-1, const_cast<void*>(ptr), len, false);
1867        return NO_ERROR;
1868    }
1869
1870    ALOGV("readBlob: read from ashmem");
1871    bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
1872    int fd = readFileDescriptor();
1873    if (fd == int(BAD_TYPE)) return BAD_VALUE;
1874
1875    void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
1876            MAP_SHARED, fd, 0);
1877    if (ptr == MAP_FAILED) return NO_MEMORY;
1878
1879    outBlob->init(fd, ptr, len, isMutable);
1880    return NO_ERROR;
1881}
1882
1883status_t Parcel::read(FlattenableHelperInterface& val) const
1884{
1885    // size
1886    const size_t len = this->readInt32();
1887    const size_t fd_count = this->readInt32();
1888
1889    if (len > INT32_MAX) {
1890        // don't accept size_t values which may have come from an
1891        // inadvertent conversion from a negative int.
1892        return BAD_VALUE;
1893    }
1894
1895    // payload
1896    void const* const buf = this->readInplace(pad_size(len));
1897    if (buf == NULL)
1898        return BAD_VALUE;
1899
1900    int* fds = NULL;
1901    if (fd_count) {
1902        fds = new int[fd_count];
1903    }
1904
1905    status_t err = NO_ERROR;
1906    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1907        fds[i] = dup(this->readFileDescriptor());
1908        if (fds[i] < 0) {
1909            err = BAD_VALUE;
1910            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
1911                i, fds[i], fd_count, strerror(errno));
1912        }
1913    }
1914
1915    if (err == NO_ERROR) {
1916        err = val.unflatten(buf, len, fds, fd_count);
1917    }
1918
1919    if (fd_count) {
1920        delete [] fds;
1921    }
1922
1923    return err;
1924}
1925const flat_binder_object* Parcel::readObject(bool nullMetaData) const
1926{
1927    const size_t DPOS = mDataPos;
1928    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
1929        const flat_binder_object* obj
1930                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
1931        mDataPos = DPOS + sizeof(flat_binder_object);
1932        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
1933            // When transferring a NULL object, we don't write it into
1934            // the object list, so we don't want to check for it when
1935            // reading.
1936            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1937            return obj;
1938        }
1939
1940        // Ensure that this object is valid...
1941        binder_size_t* const OBJS = mObjects;
1942        const size_t N = mObjectsSize;
1943        size_t opos = mNextObjectHint;
1944
1945        if (N > 0) {
1946            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
1947                 this, DPOS, opos);
1948
1949            // Start at the current hint position, looking for an object at
1950            // the current data position.
1951            if (opos < N) {
1952                while (opos < (N-1) && OBJS[opos] < DPOS) {
1953                    opos++;
1954                }
1955            } else {
1956                opos = N-1;
1957            }
1958            if (OBJS[opos] == DPOS) {
1959                // Found it!
1960                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
1961                     this, DPOS, opos);
1962                mNextObjectHint = opos+1;
1963                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1964                return obj;
1965            }
1966
1967            // Look backwards for it...
1968            while (opos > 0 && OBJS[opos] > DPOS) {
1969                opos--;
1970            }
1971            if (OBJS[opos] == DPOS) {
1972                // Found it!
1973                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
1974                     this, DPOS, opos);
1975                mNextObjectHint = opos+1;
1976                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1977                return obj;
1978            }
1979        }
1980        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1981             this, DPOS);
1982    }
1983    return NULL;
1984}
1985
1986void Parcel::closeFileDescriptors()
1987{
1988    size_t i = mObjectsSize;
1989    if (i > 0) {
1990        //ALOGI("Closing file descriptors for %zu objects...", i);
1991    }
1992    while (i > 0) {
1993        i--;
1994        const flat_binder_object* flat
1995            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1996        if (flat->type == BINDER_TYPE_FD) {
1997            //ALOGI("Closing fd: %ld", flat->handle);
1998            close(flat->handle);
1999        }
2000    }
2001}
2002
2003uintptr_t Parcel::ipcData() const
2004{
2005    return reinterpret_cast<uintptr_t>(mData);
2006}
2007
2008size_t Parcel::ipcDataSize() const
2009{
2010    return (mDataSize > mDataPos ? mDataSize : mDataPos);
2011}
2012
2013uintptr_t Parcel::ipcObjects() const
2014{
2015    return reinterpret_cast<uintptr_t>(mObjects);
2016}
2017
2018size_t Parcel::ipcObjectsCount() const
2019{
2020    return mObjectsSize;
2021}
2022
2023void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
2024    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
2025{
2026    binder_size_t minOffset = 0;
2027    freeDataNoInit();
2028    mError = NO_ERROR;
2029    mData = const_cast<uint8_t*>(data);
2030    mDataSize = mDataCapacity = dataSize;
2031    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
2032    mDataPos = 0;
2033    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
2034    mObjects = const_cast<binder_size_t*>(objects);
2035    mObjectsSize = mObjectsCapacity = objectsCount;
2036    mNextObjectHint = 0;
2037    mOwner = relFunc;
2038    mOwnerCookie = relCookie;
2039    for (size_t i = 0; i < mObjectsSize; i++) {
2040        binder_size_t offset = mObjects[i];
2041        if (offset < minOffset) {
2042            ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
2043                  __func__, (uint64_t)offset, (uint64_t)minOffset);
2044            mObjectsSize = 0;
2045            break;
2046        }
2047        minOffset = offset + sizeof(flat_binder_object);
2048    }
2049    scanForFds();
2050}
2051
2052void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
2053{
2054    to << "Parcel(";
2055
2056    if (errorCheck() != NO_ERROR) {
2057        const status_t err = errorCheck();
2058        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
2059    } else if (dataSize() > 0) {
2060        const uint8_t* DATA = data();
2061        to << indent << HexDump(DATA, dataSize()) << dedent;
2062        const binder_size_t* OBJS = objects();
2063        const size_t N = objectsCount();
2064        for (size_t i=0; i<N; i++) {
2065            const flat_binder_object* flat
2066                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2067            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
2068                << TypeCode(flat->type & 0x7f7f7f00)
2069                << " = " << flat->binder;
2070        }
2071    } else {
2072        to << "NULL";
2073    }
2074
2075    to << ")";
2076}
2077
2078void Parcel::releaseObjects()
2079{
2080    const sp<ProcessState> proc(ProcessState::self());
2081    size_t i = mObjectsSize;
2082    uint8_t* const data = mData;
2083    binder_size_t* const objects = mObjects;
2084    while (i > 0) {
2085        i--;
2086        const flat_binder_object* flat
2087            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2088        release_object(proc, *flat, this);
2089    }
2090}
2091
2092void Parcel::acquireObjects()
2093{
2094    const sp<ProcessState> proc(ProcessState::self());
2095    size_t i = mObjectsSize;
2096    uint8_t* const data = mData;
2097    binder_size_t* const objects = mObjects;
2098    while (i > 0) {
2099        i--;
2100        const flat_binder_object* flat
2101            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2102        acquire_object(proc, *flat, this);
2103    }
2104}
2105
2106void Parcel::freeData()
2107{
2108    freeDataNoInit();
2109    initState();
2110}
2111
2112void Parcel::freeDataNoInit()
2113{
2114    if (mOwner) {
2115        LOG_ALLOC("Parcel %p: freeing other owner data", this);
2116        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2117        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2118    } else {
2119        LOG_ALLOC("Parcel %p: freeing allocated data", this);
2120        releaseObjects();
2121        if (mData) {
2122            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
2123            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2124            if (mDataCapacity <= gParcelGlobalAllocSize) {
2125              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2126            } else {
2127              gParcelGlobalAllocSize = 0;
2128            }
2129            if (gParcelGlobalAllocCount > 0) {
2130              gParcelGlobalAllocCount--;
2131            }
2132            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2133            free(mData);
2134        }
2135        if (mObjects) free(mObjects);
2136    }
2137}
2138
2139status_t Parcel::growData(size_t len)
2140{
2141    if (len > INT32_MAX) {
2142        // don't accept size_t values which may have come from an
2143        // inadvertent conversion from a negative int.
2144        return BAD_VALUE;
2145    }
2146
2147    size_t newSize = ((mDataSize+len)*3)/2;
2148    return (newSize <= mDataSize)
2149            ? (status_t) NO_MEMORY
2150            : continueWrite(newSize);
2151}
2152
2153status_t Parcel::restartWrite(size_t desired)
2154{
2155    if (desired > INT32_MAX) {
2156        // don't accept size_t values which may have come from an
2157        // inadvertent conversion from a negative int.
2158        return BAD_VALUE;
2159    }
2160
2161    if (mOwner) {
2162        freeData();
2163        return continueWrite(desired);
2164    }
2165
2166    uint8_t* data = (uint8_t*)realloc(mData, desired);
2167    if (!data && desired > mDataCapacity) {
2168        mError = NO_MEMORY;
2169        return NO_MEMORY;
2170    }
2171
2172    releaseObjects();
2173
2174    if (data) {
2175        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
2176        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2177        gParcelGlobalAllocSize += desired;
2178        gParcelGlobalAllocSize -= mDataCapacity;
2179        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2180        mData = data;
2181        mDataCapacity = desired;
2182    }
2183
2184    mDataSize = mDataPos = 0;
2185    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2186    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2187
2188    free(mObjects);
2189    mObjects = NULL;
2190    mObjectsSize = mObjectsCapacity = 0;
2191    mNextObjectHint = 0;
2192    mHasFds = false;
2193    mFdsKnown = true;
2194    mAllowFds = true;
2195
2196    return NO_ERROR;
2197}
2198
2199status_t Parcel::continueWrite(size_t desired)
2200{
2201    if (desired > INT32_MAX) {
2202        // don't accept size_t values which may have come from an
2203        // inadvertent conversion from a negative int.
2204        return BAD_VALUE;
2205    }
2206
2207    // If shrinking, first adjust for any objects that appear
2208    // after the new data size.
2209    size_t objectsSize = mObjectsSize;
2210    if (desired < mDataSize) {
2211        if (desired == 0) {
2212            objectsSize = 0;
2213        } else {
2214            while (objectsSize > 0) {
2215                if (mObjects[objectsSize-1] < desired)
2216                    break;
2217                objectsSize--;
2218            }
2219        }
2220    }
2221
2222    if (mOwner) {
2223        // If the size is going to zero, just release the owner's data.
2224        if (desired == 0) {
2225            freeData();
2226            return NO_ERROR;
2227        }
2228
2229        // If there is a different owner, we need to take
2230        // posession.
2231        uint8_t* data = (uint8_t*)malloc(desired);
2232        if (!data) {
2233            mError = NO_MEMORY;
2234            return NO_MEMORY;
2235        }
2236        binder_size_t* objects = NULL;
2237
2238        if (objectsSize) {
2239            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
2240            if (!objects) {
2241                free(data);
2242
2243                mError = NO_MEMORY;
2244                return NO_MEMORY;
2245            }
2246
2247            // Little hack to only acquire references on objects
2248            // we will be keeping.
2249            size_t oldObjectsSize = mObjectsSize;
2250            mObjectsSize = objectsSize;
2251            acquireObjects();
2252            mObjectsSize = oldObjectsSize;
2253        }
2254
2255        if (mData) {
2256            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2257        }
2258        if (objects && mObjects) {
2259            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
2260        }
2261        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2262        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2263        mOwner = NULL;
2264
2265        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
2266        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2267        gParcelGlobalAllocSize += desired;
2268        gParcelGlobalAllocCount++;
2269        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2270
2271        mData = data;
2272        mObjects = objects;
2273        mDataSize = (mDataSize < desired) ? mDataSize : desired;
2274        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2275        mDataCapacity = desired;
2276        mObjectsSize = mObjectsCapacity = objectsSize;
2277        mNextObjectHint = 0;
2278
2279    } else if (mData) {
2280        if (objectsSize < mObjectsSize) {
2281            // Need to release refs on any objects we are dropping.
2282            const sp<ProcessState> proc(ProcessState::self());
2283            for (size_t i=objectsSize; i<mObjectsSize; i++) {
2284                const flat_binder_object* flat
2285                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2286                if (flat->type == BINDER_TYPE_FD) {
2287                    // will need to rescan because we may have lopped off the only FDs
2288                    mFdsKnown = false;
2289                }
2290                release_object(proc, *flat, this);
2291            }
2292            binder_size_t* objects =
2293                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2294            if (objects) {
2295                mObjects = objects;
2296            }
2297            mObjectsSize = objectsSize;
2298            mNextObjectHint = 0;
2299        }
2300
2301        // We own the data, so we can just do a realloc().
2302        if (desired > mDataCapacity) {
2303            uint8_t* data = (uint8_t*)realloc(mData, desired);
2304            if (data) {
2305                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2306                        desired);
2307                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2308                gParcelGlobalAllocSize += desired;
2309                gParcelGlobalAllocSize -= mDataCapacity;
2310                gParcelGlobalAllocCount++;
2311                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2312                mData = data;
2313                mDataCapacity = desired;
2314            } else if (desired > mDataCapacity) {
2315                mError = NO_MEMORY;
2316                return NO_MEMORY;
2317            }
2318        } else {
2319            if (mDataSize > desired) {
2320                mDataSize = desired;
2321                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2322            }
2323            if (mDataPos > desired) {
2324                mDataPos = desired;
2325                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2326            }
2327        }
2328
2329    } else {
2330        // This is the first data.  Easy!
2331        uint8_t* data = (uint8_t*)malloc(desired);
2332        if (!data) {
2333            mError = NO_MEMORY;
2334            return NO_MEMORY;
2335        }
2336
2337        if(!(mDataCapacity == 0 && mObjects == NULL
2338             && mObjectsCapacity == 0)) {
2339            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
2340        }
2341
2342        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
2343        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2344        gParcelGlobalAllocSize += desired;
2345        gParcelGlobalAllocCount++;
2346        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2347
2348        mData = data;
2349        mDataSize = mDataPos = 0;
2350        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2351        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2352        mDataCapacity = desired;
2353    }
2354
2355    return NO_ERROR;
2356}
2357
2358void Parcel::initState()
2359{
2360    LOG_ALLOC("Parcel %p: initState", this);
2361    mError = NO_ERROR;
2362    mData = 0;
2363    mDataSize = 0;
2364    mDataCapacity = 0;
2365    mDataPos = 0;
2366    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2367    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
2368    mObjects = NULL;
2369    mObjectsSize = 0;
2370    mObjectsCapacity = 0;
2371    mNextObjectHint = 0;
2372    mHasFds = false;
2373    mFdsKnown = true;
2374    mAllowFds = true;
2375    mOwner = NULL;
2376    mBlobAshmemSize = 0;
2377}
2378
2379void Parcel::scanForFds() const
2380{
2381    bool hasFds = false;
2382    for (size_t i=0; i<mObjectsSize; i++) {
2383        const flat_binder_object* flat
2384            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
2385        if (flat->type == BINDER_TYPE_FD) {
2386            hasFds = true;
2387            break;
2388        }
2389    }
2390    mHasFds = hasFds;
2391    mFdsKnown = true;
2392}
2393
2394size_t Parcel::getBlobAshmemSize() const
2395{
2396    return mBlobAshmemSize;
2397}
2398
2399// --- Parcel::Blob ---
2400
2401Parcel::Blob::Blob() :
2402        mFd(-1), mData(NULL), mSize(0), mMutable(false) {
2403}
2404
2405Parcel::Blob::~Blob() {
2406    release();
2407}
2408
2409void Parcel::Blob::release() {
2410    if (mFd != -1 && mData) {
2411        ::munmap(mData, mSize);
2412    }
2413    clear();
2414}
2415
2416void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2417    mFd = fd;
2418    mData = data;
2419    mSize = size;
2420    mMutable = isMutable;
2421}
2422
2423void Parcel::Blob::clear() {
2424    mFd = -1;
2425    mData = NULL;
2426    mSize = 0;
2427    mMutable = false;
2428}
2429
2430}; // namespace android
2431