Parcel.cpp revision f0fc52b59be0bf39912f7b698d9bde26415a6096
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    status_t status;
723    if (val.size() > std::numeric_limits<int32_t>::max()) {
724        status = BAD_VALUE;
725        return status;
726    }
727
728    status = writeInt32(val.size());
729    if (status != OK) {
730        return status;
731    }
732
733    void* data = writeInplace(val.size());
734    if (!data) {
735        status = BAD_VALUE;
736        return status;
737    }
738
739    memcpy(data, val.data(), val.size());
740    return status;
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 || size_t(size) > dataAvail()) {
1347        status = BAD_VALUE;
1348        return status;
1349    }
1350    const void* data = readInplace(size);
1351    if (!data) {
1352        status = BAD_VALUE;
1353        return status;
1354    }
1355    val->resize(size);
1356    memcpy(val->data(), data, size);
1357
1358    return status;
1359}
1360
1361status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
1362    val->clear();
1363
1364    int32_t size;
1365    status_t status = readInt32(&size);
1366
1367    if (status != OK) {
1368        return status;
1369    }
1370
1371    if (size < 0) {
1372        return BAD_VALUE;
1373    }
1374
1375    val->resize(size);
1376
1377    for (auto& v: *val) {
1378        status = readInt32(&v);
1379
1380        if (status != OK) {
1381            return status;
1382        }
1383    }
1384
1385    return OK;
1386}
1387
1388status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
1389    val->clear();
1390
1391    int32_t size;
1392    status_t status = readInt32(&size);
1393
1394    if (status != OK) {
1395        return status;
1396    }
1397
1398    if (size < 0) {
1399        return BAD_VALUE;
1400    }
1401
1402    val->resize(size);
1403
1404    for (auto& v : *val) {
1405        status = readInt64(&v);
1406
1407        if (status != OK) {
1408            return status;
1409        }
1410    }
1411
1412    return OK;
1413}
1414
1415status_t Parcel::readFloatVector(std::vector<float>* val) const {
1416    val->clear();
1417
1418    int32_t size;
1419    status_t status = readInt32(&size);
1420
1421    if (status != OK) {
1422        return status;
1423    }
1424
1425    if (size < 0) {
1426        return BAD_VALUE;
1427    }
1428
1429    val->resize(size);
1430
1431    for (auto& v : *val) {
1432        status = readFloat(&v);
1433
1434        if (status != OK) {
1435            return status;
1436        }
1437    }
1438
1439    return OK;
1440}
1441
1442status_t Parcel::readDoubleVector(std::vector<double>* val) const {
1443    val->clear();
1444
1445    int32_t size;
1446    status_t status = readInt32(&size);
1447
1448    if (status != OK) {
1449        return status;
1450    }
1451
1452    if (size < 0) {
1453        return BAD_VALUE;
1454    }
1455
1456    val->resize(size);
1457
1458    for (auto& v : *val) {
1459        status = readDouble(&v);
1460
1461        if (status != OK) {
1462            return status;
1463        }
1464    }
1465
1466    return OK;
1467}
1468
1469status_t Parcel::readBoolVector(std::vector<bool>* val) const {
1470    val->clear();
1471
1472    int32_t size;
1473    status_t status = readInt32(&size);
1474
1475    if (status != OK) {
1476        return status;
1477    }
1478
1479    if (size < 0) {
1480        return BAD_VALUE;
1481    }
1482
1483    val->resize(size);
1484
1485    /* C++ bool handling means a vector of bools isn't necessarily addressable
1486     * (we might use individual bits)
1487     */
1488    bool data;
1489    for (int32_t i = 0; i < size; ++i) {
1490        status = readBool(&data);
1491        (*val)[i] = data;
1492
1493        if (status != OK) {
1494            return status;
1495        }
1496    }
1497
1498    return OK;
1499}
1500
1501status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
1502    val->clear();
1503
1504    int32_t size;
1505    status_t status = readInt32(&size);
1506
1507    if (status != OK) {
1508        return status;
1509    }
1510
1511    if (size < 0) {
1512        return BAD_VALUE;
1513    }
1514
1515    val->resize(size);
1516
1517    for (auto& v : *val) {
1518        status = readChar(&v);
1519
1520        if (status != OK) {
1521            return status;
1522        }
1523    }
1524
1525    return OK;
1526}
1527
1528status_t Parcel::readString16Vector(std::vector<String16>* val) const {
1529    val->clear();
1530
1531    int32_t size;
1532    status_t status = readInt32(&size);
1533
1534    if (status != OK) {
1535        return status;
1536    }
1537
1538    if (size < 0) {
1539        return BAD_VALUE;
1540    }
1541
1542    val->reserve(size);
1543
1544    while (size-- > 0) {
1545        const char16_t *data;
1546        size_t size;
1547        data = readString16Inplace(&size);
1548
1549        if (data == nullptr) {
1550            return UNKNOWN_ERROR;
1551        }
1552
1553        val->emplace_back(data, size);
1554    }
1555
1556    return OK;
1557}
1558
1559
1560status_t Parcel::readInt32(int32_t *pArg) const
1561{
1562    return readAligned(pArg);
1563}
1564
1565int32_t Parcel::readInt32() const
1566{
1567    return readAligned<int32_t>();
1568}
1569
1570status_t Parcel::readUint32(uint32_t *pArg) const
1571{
1572    return readAligned(pArg);
1573}
1574
1575uint32_t Parcel::readUint32() const
1576{
1577    return readAligned<uint32_t>();
1578}
1579
1580status_t Parcel::readInt64(int64_t *pArg) const
1581{
1582    return readAligned(pArg);
1583}
1584
1585
1586int64_t Parcel::readInt64() const
1587{
1588    return readAligned<int64_t>();
1589}
1590
1591status_t Parcel::readUint64(uint64_t *pArg) const
1592{
1593    return readAligned(pArg);
1594}
1595
1596uint64_t Parcel::readUint64() const
1597{
1598    return readAligned<uint64_t>();
1599}
1600
1601status_t Parcel::readPointer(uintptr_t *pArg) const
1602{
1603    status_t ret;
1604    binder_uintptr_t ptr;
1605    ret = readAligned(&ptr);
1606    if (!ret)
1607        *pArg = ptr;
1608    return ret;
1609}
1610
1611uintptr_t Parcel::readPointer() const
1612{
1613    return readAligned<binder_uintptr_t>();
1614}
1615
1616
1617status_t Parcel::readFloat(float *pArg) const
1618{
1619    return readAligned(pArg);
1620}
1621
1622
1623float Parcel::readFloat() const
1624{
1625    return readAligned<float>();
1626}
1627
1628#if defined(__mips__) && defined(__mips_hard_float)
1629
1630status_t Parcel::readDouble(double *pArg) const
1631{
1632    union {
1633      double d;
1634      unsigned long long ll;
1635    } u;
1636    u.d = 0;
1637    status_t status;
1638    status = readAligned(&u.ll);
1639    *pArg = u.d;
1640    return status;
1641}
1642
1643double Parcel::readDouble() const
1644{
1645    union {
1646      double d;
1647      unsigned long long ll;
1648    } u;
1649    u.ll = readAligned<unsigned long long>();
1650    return u.d;
1651}
1652
1653#else
1654
1655status_t Parcel::readDouble(double *pArg) const
1656{
1657    return readAligned(pArg);
1658}
1659
1660double Parcel::readDouble() const
1661{
1662    return readAligned<double>();
1663}
1664
1665#endif
1666
1667status_t Parcel::readIntPtr(intptr_t *pArg) const
1668{
1669    return readAligned(pArg);
1670}
1671
1672
1673intptr_t Parcel::readIntPtr() const
1674{
1675    return readAligned<intptr_t>();
1676}
1677
1678status_t Parcel::readBool(bool *pArg) const
1679{
1680    int32_t tmp;
1681    status_t ret = readInt32(&tmp);
1682    *pArg = (tmp != 0);
1683    return ret;
1684}
1685
1686bool Parcel::readBool() const
1687{
1688    return readInt32() != 0;
1689}
1690
1691status_t Parcel::readChar(char16_t *pArg) const
1692{
1693    int32_t tmp;
1694    status_t ret = readInt32(&tmp);
1695    *pArg = char16_t(tmp);
1696    return ret;
1697}
1698
1699char16_t Parcel::readChar() const
1700{
1701    return char16_t(readInt32());
1702}
1703
1704status_t Parcel::readByte(int8_t *pArg) const
1705{
1706    int32_t tmp;
1707    status_t ret = readInt32(&tmp);
1708    *pArg = int8_t(tmp);
1709    return ret;
1710}
1711
1712int8_t Parcel::readByte() const
1713{
1714    return int8_t(readInt32());
1715}
1716
1717const char* Parcel::readCString() const
1718{
1719    const size_t avail = mDataSize-mDataPos;
1720    if (avail > 0) {
1721        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1722        // is the string's trailing NUL within the parcel's valid bounds?
1723        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1724        if (eos) {
1725            const size_t len = eos - str;
1726            mDataPos += pad_size(len+1);
1727            ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
1728            return str;
1729        }
1730    }
1731    return NULL;
1732}
1733
1734String8 Parcel::readString8() const
1735{
1736    int32_t size = readInt32();
1737    // watch for potential int overflow adding 1 for trailing NUL
1738    if (size > 0 && size < INT32_MAX) {
1739        const char* str = (const char*)readInplace(size+1);
1740        if (str) return String8(str, size);
1741    }
1742    return String8();
1743}
1744
1745String16 Parcel::readString16() const
1746{
1747    size_t len;
1748    const char16_t* str = readString16Inplace(&len);
1749    if (str) return String16(str, len);
1750    ALOGE("Reading a NULL string not supported here.");
1751    return String16();
1752}
1753
1754status_t Parcel::readString16(String16* pArg) const
1755{
1756    size_t len;
1757    const char16_t* str = readString16Inplace(&len);
1758    if (str) {
1759        pArg->setTo(str, len);
1760        return 0;
1761    } else {
1762        *pArg = String16();
1763        return UNKNOWN_ERROR;
1764    }
1765}
1766
1767const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1768{
1769    int32_t size = readInt32();
1770    // watch for potential int overflow from size+1
1771    if (size >= 0 && size < INT32_MAX) {
1772        *outLen = size;
1773        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1774        if (str != NULL) {
1775            return str;
1776        }
1777    }
1778    *outLen = 0;
1779    return NULL;
1780}
1781
1782status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1783{
1784    return unflatten_binder(ProcessState::self(), *this, val);
1785}
1786
1787sp<IBinder> Parcel::readStrongBinder() const
1788{
1789    sp<IBinder> val;
1790    readStrongBinder(&val);
1791    return val;
1792}
1793
1794wp<IBinder> Parcel::readWeakBinder() const
1795{
1796    wp<IBinder> val;
1797    unflatten_binder(ProcessState::self(), *this, &val);
1798    return val;
1799}
1800
1801int32_t Parcel::readExceptionCode() const
1802{
1803  int32_t exception_code = readAligned<int32_t>();
1804  if (exception_code == EX_HAS_REPLY_HEADER) {
1805    int32_t header_start = dataPosition();
1806    int32_t header_size = readAligned<int32_t>();
1807    // Skip over fat responses headers.  Not used (or propagated) in
1808    // native code
1809    setDataPosition(header_start + header_size);
1810    // And fat response headers are currently only used when there are no
1811    // exceptions, so return no error:
1812    return 0;
1813  }
1814  return exception_code;
1815}
1816
1817native_handle* Parcel::readNativeHandle() const
1818{
1819    int numFds, numInts;
1820    status_t err;
1821    err = readInt32(&numFds);
1822    if (err != NO_ERROR) return 0;
1823    err = readInt32(&numInts);
1824    if (err != NO_ERROR) return 0;
1825
1826    native_handle* h = native_handle_create(numFds, numInts);
1827    if (!h) {
1828        return 0;
1829    }
1830
1831    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1832        h->data[i] = dup(readFileDescriptor());
1833        if (h->data[i] < 0) err = BAD_VALUE;
1834    }
1835    err = read(h->data + numFds, sizeof(int)*numInts);
1836    if (err != NO_ERROR) {
1837        native_handle_close(h);
1838        native_handle_delete(h);
1839        h = 0;
1840    }
1841    return h;
1842}
1843
1844
1845int Parcel::readFileDescriptor() const
1846{
1847    const flat_binder_object* flat = readObject(true);
1848    if (flat) {
1849        switch (flat->type) {
1850            case BINDER_TYPE_FD:
1851                //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
1852                return flat->handle;
1853        }
1854    }
1855    return BAD_TYPE;
1856}
1857
1858status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
1859{
1860    int32_t blobType;
1861    status_t status = readInt32(&blobType);
1862    if (status) return status;
1863
1864    if (blobType == BLOB_INPLACE) {
1865        ALOGV("readBlob: read in place");
1866        const void* ptr = readInplace(len);
1867        if (!ptr) return BAD_VALUE;
1868
1869        outBlob->init(-1, const_cast<void*>(ptr), len, false);
1870        return NO_ERROR;
1871    }
1872
1873    ALOGV("readBlob: read from ashmem");
1874    bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
1875    int fd = readFileDescriptor();
1876    if (fd == int(BAD_TYPE)) return BAD_VALUE;
1877
1878    void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
1879            MAP_SHARED, fd, 0);
1880    if (ptr == MAP_FAILED) return NO_MEMORY;
1881
1882    outBlob->init(fd, ptr, len, isMutable);
1883    return NO_ERROR;
1884}
1885
1886status_t Parcel::read(FlattenableHelperInterface& val) const
1887{
1888    // size
1889    const size_t len = this->readInt32();
1890    const size_t fd_count = this->readInt32();
1891
1892    if (len > INT32_MAX) {
1893        // don't accept size_t values which may have come from an
1894        // inadvertent conversion from a negative int.
1895        return BAD_VALUE;
1896    }
1897
1898    // payload
1899    void const* const buf = this->readInplace(pad_size(len));
1900    if (buf == NULL)
1901        return BAD_VALUE;
1902
1903    int* fds = NULL;
1904    if (fd_count) {
1905        fds = new int[fd_count];
1906    }
1907
1908    status_t err = NO_ERROR;
1909    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1910        fds[i] = dup(this->readFileDescriptor());
1911        if (fds[i] < 0) {
1912            err = BAD_VALUE;
1913            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
1914                i, fds[i], fd_count, strerror(errno));
1915        }
1916    }
1917
1918    if (err == NO_ERROR) {
1919        err = val.unflatten(buf, len, fds, fd_count);
1920    }
1921
1922    if (fd_count) {
1923        delete [] fds;
1924    }
1925
1926    return err;
1927}
1928const flat_binder_object* Parcel::readObject(bool nullMetaData) const
1929{
1930    const size_t DPOS = mDataPos;
1931    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
1932        const flat_binder_object* obj
1933                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
1934        mDataPos = DPOS + sizeof(flat_binder_object);
1935        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
1936            // When transferring a NULL object, we don't write it into
1937            // the object list, so we don't want to check for it when
1938            // reading.
1939            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1940            return obj;
1941        }
1942
1943        // Ensure that this object is valid...
1944        binder_size_t* const OBJS = mObjects;
1945        const size_t N = mObjectsSize;
1946        size_t opos = mNextObjectHint;
1947
1948        if (N > 0) {
1949            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
1950                 this, DPOS, opos);
1951
1952            // Start at the current hint position, looking for an object at
1953            // the current data position.
1954            if (opos < N) {
1955                while (opos < (N-1) && OBJS[opos] < DPOS) {
1956                    opos++;
1957                }
1958            } else {
1959                opos = N-1;
1960            }
1961            if (OBJS[opos] == DPOS) {
1962                // Found it!
1963                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
1964                     this, DPOS, opos);
1965                mNextObjectHint = opos+1;
1966                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1967                return obj;
1968            }
1969
1970            // Look backwards for it...
1971            while (opos > 0 && OBJS[opos] > DPOS) {
1972                opos--;
1973            }
1974            if (OBJS[opos] == DPOS) {
1975                // Found it!
1976                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
1977                     this, DPOS, opos);
1978                mNextObjectHint = opos+1;
1979                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1980                return obj;
1981            }
1982        }
1983        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1984             this, DPOS);
1985    }
1986    return NULL;
1987}
1988
1989void Parcel::closeFileDescriptors()
1990{
1991    size_t i = mObjectsSize;
1992    if (i > 0) {
1993        //ALOGI("Closing file descriptors for %zu objects...", i);
1994    }
1995    while (i > 0) {
1996        i--;
1997        const flat_binder_object* flat
1998            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1999        if (flat->type == BINDER_TYPE_FD) {
2000            //ALOGI("Closing fd: %ld", flat->handle);
2001            close(flat->handle);
2002        }
2003    }
2004}
2005
2006uintptr_t Parcel::ipcData() const
2007{
2008    return reinterpret_cast<uintptr_t>(mData);
2009}
2010
2011size_t Parcel::ipcDataSize() const
2012{
2013    return (mDataSize > mDataPos ? mDataSize : mDataPos);
2014}
2015
2016uintptr_t Parcel::ipcObjects() const
2017{
2018    return reinterpret_cast<uintptr_t>(mObjects);
2019}
2020
2021size_t Parcel::ipcObjectsCount() const
2022{
2023    return mObjectsSize;
2024}
2025
2026void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
2027    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
2028{
2029    binder_size_t minOffset = 0;
2030    freeDataNoInit();
2031    mError = NO_ERROR;
2032    mData = const_cast<uint8_t*>(data);
2033    mDataSize = mDataCapacity = dataSize;
2034    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
2035    mDataPos = 0;
2036    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
2037    mObjects = const_cast<binder_size_t*>(objects);
2038    mObjectsSize = mObjectsCapacity = objectsCount;
2039    mNextObjectHint = 0;
2040    mOwner = relFunc;
2041    mOwnerCookie = relCookie;
2042    for (size_t i = 0; i < mObjectsSize; i++) {
2043        binder_size_t offset = mObjects[i];
2044        if (offset < minOffset) {
2045            ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
2046                  __func__, (uint64_t)offset, (uint64_t)minOffset);
2047            mObjectsSize = 0;
2048            break;
2049        }
2050        minOffset = offset + sizeof(flat_binder_object);
2051    }
2052    scanForFds();
2053}
2054
2055void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
2056{
2057    to << "Parcel(";
2058
2059    if (errorCheck() != NO_ERROR) {
2060        const status_t err = errorCheck();
2061        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
2062    } else if (dataSize() > 0) {
2063        const uint8_t* DATA = data();
2064        to << indent << HexDump(DATA, dataSize()) << dedent;
2065        const binder_size_t* OBJS = objects();
2066        const size_t N = objectsCount();
2067        for (size_t i=0; i<N; i++) {
2068            const flat_binder_object* flat
2069                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2070            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
2071                << TypeCode(flat->type & 0x7f7f7f00)
2072                << " = " << flat->binder;
2073        }
2074    } else {
2075        to << "NULL";
2076    }
2077
2078    to << ")";
2079}
2080
2081void Parcel::releaseObjects()
2082{
2083    const sp<ProcessState> proc(ProcessState::self());
2084    size_t i = mObjectsSize;
2085    uint8_t* const data = mData;
2086    binder_size_t* const objects = mObjects;
2087    while (i > 0) {
2088        i--;
2089        const flat_binder_object* flat
2090            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2091        release_object(proc, *flat, this);
2092    }
2093}
2094
2095void Parcel::acquireObjects()
2096{
2097    const sp<ProcessState> proc(ProcessState::self());
2098    size_t i = mObjectsSize;
2099    uint8_t* const data = mData;
2100    binder_size_t* const objects = mObjects;
2101    while (i > 0) {
2102        i--;
2103        const flat_binder_object* flat
2104            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2105        acquire_object(proc, *flat, this);
2106    }
2107}
2108
2109void Parcel::freeData()
2110{
2111    freeDataNoInit();
2112    initState();
2113}
2114
2115void Parcel::freeDataNoInit()
2116{
2117    if (mOwner) {
2118        LOG_ALLOC("Parcel %p: freeing other owner data", this);
2119        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2120        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2121    } else {
2122        LOG_ALLOC("Parcel %p: freeing allocated data", this);
2123        releaseObjects();
2124        if (mData) {
2125            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
2126            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2127            if (mDataCapacity <= gParcelGlobalAllocSize) {
2128              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2129            } else {
2130              gParcelGlobalAllocSize = 0;
2131            }
2132            if (gParcelGlobalAllocCount > 0) {
2133              gParcelGlobalAllocCount--;
2134            }
2135            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2136            free(mData);
2137        }
2138        if (mObjects) free(mObjects);
2139    }
2140}
2141
2142status_t Parcel::growData(size_t len)
2143{
2144    if (len > INT32_MAX) {
2145        // don't accept size_t values which may have come from an
2146        // inadvertent conversion from a negative int.
2147        return BAD_VALUE;
2148    }
2149
2150    size_t newSize = ((mDataSize+len)*3)/2;
2151    return (newSize <= mDataSize)
2152            ? (status_t) NO_MEMORY
2153            : continueWrite(newSize);
2154}
2155
2156status_t Parcel::restartWrite(size_t desired)
2157{
2158    if (desired > INT32_MAX) {
2159        // don't accept size_t values which may have come from an
2160        // inadvertent conversion from a negative int.
2161        return BAD_VALUE;
2162    }
2163
2164    if (mOwner) {
2165        freeData();
2166        return continueWrite(desired);
2167    }
2168
2169    uint8_t* data = (uint8_t*)realloc(mData, desired);
2170    if (!data && desired > mDataCapacity) {
2171        mError = NO_MEMORY;
2172        return NO_MEMORY;
2173    }
2174
2175    releaseObjects();
2176
2177    if (data) {
2178        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
2179        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2180        gParcelGlobalAllocSize += desired;
2181        gParcelGlobalAllocSize -= mDataCapacity;
2182        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2183        mData = data;
2184        mDataCapacity = desired;
2185    }
2186
2187    mDataSize = mDataPos = 0;
2188    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2189    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2190
2191    free(mObjects);
2192    mObjects = NULL;
2193    mObjectsSize = mObjectsCapacity = 0;
2194    mNextObjectHint = 0;
2195    mHasFds = false;
2196    mFdsKnown = true;
2197    mAllowFds = true;
2198
2199    return NO_ERROR;
2200}
2201
2202status_t Parcel::continueWrite(size_t desired)
2203{
2204    if (desired > INT32_MAX) {
2205        // don't accept size_t values which may have come from an
2206        // inadvertent conversion from a negative int.
2207        return BAD_VALUE;
2208    }
2209
2210    // If shrinking, first adjust for any objects that appear
2211    // after the new data size.
2212    size_t objectsSize = mObjectsSize;
2213    if (desired < mDataSize) {
2214        if (desired == 0) {
2215            objectsSize = 0;
2216        } else {
2217            while (objectsSize > 0) {
2218                if (mObjects[objectsSize-1] < desired)
2219                    break;
2220                objectsSize--;
2221            }
2222        }
2223    }
2224
2225    if (mOwner) {
2226        // If the size is going to zero, just release the owner's data.
2227        if (desired == 0) {
2228            freeData();
2229            return NO_ERROR;
2230        }
2231
2232        // If there is a different owner, we need to take
2233        // posession.
2234        uint8_t* data = (uint8_t*)malloc(desired);
2235        if (!data) {
2236            mError = NO_MEMORY;
2237            return NO_MEMORY;
2238        }
2239        binder_size_t* objects = NULL;
2240
2241        if (objectsSize) {
2242            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
2243            if (!objects) {
2244                free(data);
2245
2246                mError = NO_MEMORY;
2247                return NO_MEMORY;
2248            }
2249
2250            // Little hack to only acquire references on objects
2251            // we will be keeping.
2252            size_t oldObjectsSize = mObjectsSize;
2253            mObjectsSize = objectsSize;
2254            acquireObjects();
2255            mObjectsSize = oldObjectsSize;
2256        }
2257
2258        if (mData) {
2259            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2260        }
2261        if (objects && mObjects) {
2262            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
2263        }
2264        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2265        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2266        mOwner = NULL;
2267
2268        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
2269        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2270        gParcelGlobalAllocSize += desired;
2271        gParcelGlobalAllocCount++;
2272        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2273
2274        mData = data;
2275        mObjects = objects;
2276        mDataSize = (mDataSize < desired) ? mDataSize : desired;
2277        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2278        mDataCapacity = desired;
2279        mObjectsSize = mObjectsCapacity = objectsSize;
2280        mNextObjectHint = 0;
2281
2282    } else if (mData) {
2283        if (objectsSize < mObjectsSize) {
2284            // Need to release refs on any objects we are dropping.
2285            const sp<ProcessState> proc(ProcessState::self());
2286            for (size_t i=objectsSize; i<mObjectsSize; i++) {
2287                const flat_binder_object* flat
2288                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2289                if (flat->type == BINDER_TYPE_FD) {
2290                    // will need to rescan because we may have lopped off the only FDs
2291                    mFdsKnown = false;
2292                }
2293                release_object(proc, *flat, this);
2294            }
2295            binder_size_t* objects =
2296                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2297            if (objects) {
2298                mObjects = objects;
2299            }
2300            mObjectsSize = objectsSize;
2301            mNextObjectHint = 0;
2302        }
2303
2304        // We own the data, so we can just do a realloc().
2305        if (desired > mDataCapacity) {
2306            uint8_t* data = (uint8_t*)realloc(mData, desired);
2307            if (data) {
2308                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2309                        desired);
2310                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2311                gParcelGlobalAllocSize += desired;
2312                gParcelGlobalAllocSize -= mDataCapacity;
2313                gParcelGlobalAllocCount++;
2314                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2315                mData = data;
2316                mDataCapacity = desired;
2317            } else if (desired > mDataCapacity) {
2318                mError = NO_MEMORY;
2319                return NO_MEMORY;
2320            }
2321        } else {
2322            if (mDataSize > desired) {
2323                mDataSize = desired;
2324                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2325            }
2326            if (mDataPos > desired) {
2327                mDataPos = desired;
2328                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2329            }
2330        }
2331
2332    } else {
2333        // This is the first data.  Easy!
2334        uint8_t* data = (uint8_t*)malloc(desired);
2335        if (!data) {
2336            mError = NO_MEMORY;
2337            return NO_MEMORY;
2338        }
2339
2340        if(!(mDataCapacity == 0 && mObjects == NULL
2341             && mObjectsCapacity == 0)) {
2342            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
2343        }
2344
2345        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
2346        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2347        gParcelGlobalAllocSize += desired;
2348        gParcelGlobalAllocCount++;
2349        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2350
2351        mData = data;
2352        mDataSize = mDataPos = 0;
2353        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2354        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2355        mDataCapacity = desired;
2356    }
2357
2358    return NO_ERROR;
2359}
2360
2361void Parcel::initState()
2362{
2363    LOG_ALLOC("Parcel %p: initState", this);
2364    mError = NO_ERROR;
2365    mData = 0;
2366    mDataSize = 0;
2367    mDataCapacity = 0;
2368    mDataPos = 0;
2369    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2370    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
2371    mObjects = NULL;
2372    mObjectsSize = 0;
2373    mObjectsCapacity = 0;
2374    mNextObjectHint = 0;
2375    mHasFds = false;
2376    mFdsKnown = true;
2377    mAllowFds = true;
2378    mOwner = NULL;
2379    mBlobAshmemSize = 0;
2380}
2381
2382void Parcel::scanForFds() const
2383{
2384    bool hasFds = false;
2385    for (size_t i=0; i<mObjectsSize; i++) {
2386        const flat_binder_object* flat
2387            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
2388        if (flat->type == BINDER_TYPE_FD) {
2389            hasFds = true;
2390            break;
2391        }
2392    }
2393    mHasFds = hasFds;
2394    mFdsKnown = true;
2395}
2396
2397size_t Parcel::getBlobAshmemSize() const
2398{
2399    return mBlobAshmemSize;
2400}
2401
2402// --- Parcel::Blob ---
2403
2404Parcel::Blob::Blob() :
2405        mFd(-1), mData(NULL), mSize(0), mMutable(false) {
2406}
2407
2408Parcel::Blob::~Blob() {
2409    release();
2410}
2411
2412void Parcel::Blob::release() {
2413    if (mFd != -1 && mData) {
2414        ::munmap(mData, mSize);
2415    }
2416    clear();
2417}
2418
2419void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2420    mFd = fd;
2421    mData = data;
2422    mSize = size;
2423    mMutable = isMutable;
2424}
2425
2426void Parcel::Blob::clear() {
2427    mFd = -1;
2428    mData = NULL;
2429    mSize = 0;
2430    mMutable = false;
2431}
2432
2433}; // namespace android
2434