Parcel.cpp revision f0c13772d95486d98f034361883b2415bb26a614
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    bool data;
1491    for (int32_t i = 0; i < size; ++i) {
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
1784status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1785{
1786    return unflatten_binder(ProcessState::self(), *this, val);
1787}
1788
1789sp<IBinder> Parcel::readStrongBinder() const
1790{
1791    sp<IBinder> val;
1792    readStrongBinder(&val);
1793    return val;
1794}
1795
1796wp<IBinder> Parcel::readWeakBinder() const
1797{
1798    wp<IBinder> val;
1799    unflatten_binder(ProcessState::self(), *this, &val);
1800    return val;
1801}
1802
1803int32_t Parcel::readExceptionCode() const
1804{
1805  int32_t exception_code = readAligned<int32_t>();
1806  if (exception_code == EX_HAS_REPLY_HEADER) {
1807    int32_t header_start = dataPosition();
1808    int32_t header_size = readAligned<int32_t>();
1809    // Skip over fat responses headers.  Not used (or propagated) in
1810    // native code
1811    setDataPosition(header_start + header_size);
1812    // And fat response headers are currently only used when there are no
1813    // exceptions, so return no error:
1814    return 0;
1815  }
1816  return exception_code;
1817}
1818
1819native_handle* Parcel::readNativeHandle() const
1820{
1821    int numFds, numInts;
1822    status_t err;
1823    err = readInt32(&numFds);
1824    if (err != NO_ERROR) return 0;
1825    err = readInt32(&numInts);
1826    if (err != NO_ERROR) return 0;
1827
1828    native_handle* h = native_handle_create(numFds, numInts);
1829    if (!h) {
1830        return 0;
1831    }
1832
1833    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1834        h->data[i] = dup(readFileDescriptor());
1835        if (h->data[i] < 0) err = BAD_VALUE;
1836    }
1837    err = read(h->data + numFds, sizeof(int)*numInts);
1838    if (err != NO_ERROR) {
1839        native_handle_close(h);
1840        native_handle_delete(h);
1841        h = 0;
1842    }
1843    return h;
1844}
1845
1846
1847int Parcel::readFileDescriptor() const
1848{
1849    const flat_binder_object* flat = readObject(true);
1850    if (flat) {
1851        switch (flat->type) {
1852            case BINDER_TYPE_FD:
1853                //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
1854                return flat->handle;
1855        }
1856    }
1857    return BAD_TYPE;
1858}
1859
1860status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
1861{
1862    int32_t blobType;
1863    status_t status = readInt32(&blobType);
1864    if (status) return status;
1865
1866    if (blobType == BLOB_INPLACE) {
1867        ALOGV("readBlob: read in place");
1868        const void* ptr = readInplace(len);
1869        if (!ptr) return BAD_VALUE;
1870
1871        outBlob->init(-1, const_cast<void*>(ptr), len, false);
1872        return NO_ERROR;
1873    }
1874
1875    ALOGV("readBlob: read from ashmem");
1876    bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
1877    int fd = readFileDescriptor();
1878    if (fd == int(BAD_TYPE)) return BAD_VALUE;
1879
1880    void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
1881            MAP_SHARED, fd, 0);
1882    if (ptr == MAP_FAILED) return NO_MEMORY;
1883
1884    outBlob->init(fd, ptr, len, isMutable);
1885    return NO_ERROR;
1886}
1887
1888status_t Parcel::read(FlattenableHelperInterface& val) const
1889{
1890    // size
1891    const size_t len = this->readInt32();
1892    const size_t fd_count = this->readInt32();
1893
1894    if (len > INT32_MAX) {
1895        // don't accept size_t values which may have come from an
1896        // inadvertent conversion from a negative int.
1897        return BAD_VALUE;
1898    }
1899
1900    // payload
1901    void const* const buf = this->readInplace(pad_size(len));
1902    if (buf == NULL)
1903        return BAD_VALUE;
1904
1905    int* fds = NULL;
1906    if (fd_count) {
1907        fds = new int[fd_count];
1908    }
1909
1910    status_t err = NO_ERROR;
1911    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1912        fds[i] = dup(this->readFileDescriptor());
1913        if (fds[i] < 0) {
1914            err = BAD_VALUE;
1915            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
1916                i, fds[i], fd_count, strerror(errno));
1917        }
1918    }
1919
1920    if (err == NO_ERROR) {
1921        err = val.unflatten(buf, len, fds, fd_count);
1922    }
1923
1924    if (fd_count) {
1925        delete [] fds;
1926    }
1927
1928    return err;
1929}
1930const flat_binder_object* Parcel::readObject(bool nullMetaData) const
1931{
1932    const size_t DPOS = mDataPos;
1933    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
1934        const flat_binder_object* obj
1935                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
1936        mDataPos = DPOS + sizeof(flat_binder_object);
1937        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
1938            // When transferring a NULL object, we don't write it into
1939            // the object list, so we don't want to check for it when
1940            // reading.
1941            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1942            return obj;
1943        }
1944
1945        // Ensure that this object is valid...
1946        binder_size_t* const OBJS = mObjects;
1947        const size_t N = mObjectsSize;
1948        size_t opos = mNextObjectHint;
1949
1950        if (N > 0) {
1951            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
1952                 this, DPOS, opos);
1953
1954            // Start at the current hint position, looking for an object at
1955            // the current data position.
1956            if (opos < N) {
1957                while (opos < (N-1) && OBJS[opos] < DPOS) {
1958                    opos++;
1959                }
1960            } else {
1961                opos = N-1;
1962            }
1963            if (OBJS[opos] == DPOS) {
1964                // Found it!
1965                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
1966                     this, DPOS, opos);
1967                mNextObjectHint = opos+1;
1968                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1969                return obj;
1970            }
1971
1972            // Look backwards for it...
1973            while (opos > 0 && OBJS[opos] > DPOS) {
1974                opos--;
1975            }
1976            if (OBJS[opos] == DPOS) {
1977                // Found it!
1978                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
1979                     this, DPOS, opos);
1980                mNextObjectHint = opos+1;
1981                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1982                return obj;
1983            }
1984        }
1985        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1986             this, DPOS);
1987    }
1988    return NULL;
1989}
1990
1991void Parcel::closeFileDescriptors()
1992{
1993    size_t i = mObjectsSize;
1994    if (i > 0) {
1995        //ALOGI("Closing file descriptors for %zu objects...", i);
1996    }
1997    while (i > 0) {
1998        i--;
1999        const flat_binder_object* flat
2000            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2001        if (flat->type == BINDER_TYPE_FD) {
2002            //ALOGI("Closing fd: %ld", flat->handle);
2003            close(flat->handle);
2004        }
2005    }
2006}
2007
2008uintptr_t Parcel::ipcData() const
2009{
2010    return reinterpret_cast<uintptr_t>(mData);
2011}
2012
2013size_t Parcel::ipcDataSize() const
2014{
2015    return (mDataSize > mDataPos ? mDataSize : mDataPos);
2016}
2017
2018uintptr_t Parcel::ipcObjects() const
2019{
2020    return reinterpret_cast<uintptr_t>(mObjects);
2021}
2022
2023size_t Parcel::ipcObjectsCount() const
2024{
2025    return mObjectsSize;
2026}
2027
2028void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
2029    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
2030{
2031    binder_size_t minOffset = 0;
2032    freeDataNoInit();
2033    mError = NO_ERROR;
2034    mData = const_cast<uint8_t*>(data);
2035    mDataSize = mDataCapacity = dataSize;
2036    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
2037    mDataPos = 0;
2038    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
2039    mObjects = const_cast<binder_size_t*>(objects);
2040    mObjectsSize = mObjectsCapacity = objectsCount;
2041    mNextObjectHint = 0;
2042    mOwner = relFunc;
2043    mOwnerCookie = relCookie;
2044    for (size_t i = 0; i < mObjectsSize; i++) {
2045        binder_size_t offset = mObjects[i];
2046        if (offset < minOffset) {
2047            ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
2048                  __func__, (uint64_t)offset, (uint64_t)minOffset);
2049            mObjectsSize = 0;
2050            break;
2051        }
2052        minOffset = offset + sizeof(flat_binder_object);
2053    }
2054    scanForFds();
2055}
2056
2057void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
2058{
2059    to << "Parcel(";
2060
2061    if (errorCheck() != NO_ERROR) {
2062        const status_t err = errorCheck();
2063        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
2064    } else if (dataSize() > 0) {
2065        const uint8_t* DATA = data();
2066        to << indent << HexDump(DATA, dataSize()) << dedent;
2067        const binder_size_t* OBJS = objects();
2068        const size_t N = objectsCount();
2069        for (size_t i=0; i<N; i++) {
2070            const flat_binder_object* flat
2071                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2072            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
2073                << TypeCode(flat->type & 0x7f7f7f00)
2074                << " = " << flat->binder;
2075        }
2076    } else {
2077        to << "NULL";
2078    }
2079
2080    to << ")";
2081}
2082
2083void Parcel::releaseObjects()
2084{
2085    const sp<ProcessState> proc(ProcessState::self());
2086    size_t i = mObjectsSize;
2087    uint8_t* const data = mData;
2088    binder_size_t* const objects = mObjects;
2089    while (i > 0) {
2090        i--;
2091        const flat_binder_object* flat
2092            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2093        release_object(proc, *flat, this);
2094    }
2095}
2096
2097void Parcel::acquireObjects()
2098{
2099    const sp<ProcessState> proc(ProcessState::self());
2100    size_t i = mObjectsSize;
2101    uint8_t* const data = mData;
2102    binder_size_t* const objects = mObjects;
2103    while (i > 0) {
2104        i--;
2105        const flat_binder_object* flat
2106            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
2107        acquire_object(proc, *flat, this);
2108    }
2109}
2110
2111void Parcel::freeData()
2112{
2113    freeDataNoInit();
2114    initState();
2115}
2116
2117void Parcel::freeDataNoInit()
2118{
2119    if (mOwner) {
2120        LOG_ALLOC("Parcel %p: freeing other owner data", this);
2121        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2122        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2123    } else {
2124        LOG_ALLOC("Parcel %p: freeing allocated data", this);
2125        releaseObjects();
2126        if (mData) {
2127            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
2128            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2129            if (mDataCapacity <= gParcelGlobalAllocSize) {
2130              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2131            } else {
2132              gParcelGlobalAllocSize = 0;
2133            }
2134            if (gParcelGlobalAllocCount > 0) {
2135              gParcelGlobalAllocCount--;
2136            }
2137            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2138            free(mData);
2139        }
2140        if (mObjects) free(mObjects);
2141    }
2142}
2143
2144status_t Parcel::growData(size_t len)
2145{
2146    if (len > INT32_MAX) {
2147        // don't accept size_t values which may have come from an
2148        // inadvertent conversion from a negative int.
2149        return BAD_VALUE;
2150    }
2151
2152    size_t newSize = ((mDataSize+len)*3)/2;
2153    return (newSize <= mDataSize)
2154            ? (status_t) NO_MEMORY
2155            : continueWrite(newSize);
2156}
2157
2158status_t Parcel::restartWrite(size_t desired)
2159{
2160    if (desired > INT32_MAX) {
2161        // don't accept size_t values which may have come from an
2162        // inadvertent conversion from a negative int.
2163        return BAD_VALUE;
2164    }
2165
2166    if (mOwner) {
2167        freeData();
2168        return continueWrite(desired);
2169    }
2170
2171    uint8_t* data = (uint8_t*)realloc(mData, desired);
2172    if (!data && desired > mDataCapacity) {
2173        mError = NO_MEMORY;
2174        return NO_MEMORY;
2175    }
2176
2177    releaseObjects();
2178
2179    if (data) {
2180        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
2181        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2182        gParcelGlobalAllocSize += desired;
2183        gParcelGlobalAllocSize -= mDataCapacity;
2184        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2185        mData = data;
2186        mDataCapacity = desired;
2187    }
2188
2189    mDataSize = mDataPos = 0;
2190    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2191    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2192
2193    free(mObjects);
2194    mObjects = NULL;
2195    mObjectsSize = mObjectsCapacity = 0;
2196    mNextObjectHint = 0;
2197    mHasFds = false;
2198    mFdsKnown = true;
2199    mAllowFds = true;
2200
2201    return NO_ERROR;
2202}
2203
2204status_t Parcel::continueWrite(size_t desired)
2205{
2206    if (desired > INT32_MAX) {
2207        // don't accept size_t values which may have come from an
2208        // inadvertent conversion from a negative int.
2209        return BAD_VALUE;
2210    }
2211
2212    // If shrinking, first adjust for any objects that appear
2213    // after the new data size.
2214    size_t objectsSize = mObjectsSize;
2215    if (desired < mDataSize) {
2216        if (desired == 0) {
2217            objectsSize = 0;
2218        } else {
2219            while (objectsSize > 0) {
2220                if (mObjects[objectsSize-1] < desired)
2221                    break;
2222                objectsSize--;
2223            }
2224        }
2225    }
2226
2227    if (mOwner) {
2228        // If the size is going to zero, just release the owner's data.
2229        if (desired == 0) {
2230            freeData();
2231            return NO_ERROR;
2232        }
2233
2234        // If there is a different owner, we need to take
2235        // posession.
2236        uint8_t* data = (uint8_t*)malloc(desired);
2237        if (!data) {
2238            mError = NO_MEMORY;
2239            return NO_MEMORY;
2240        }
2241        binder_size_t* objects = NULL;
2242
2243        if (objectsSize) {
2244            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
2245            if (!objects) {
2246                free(data);
2247
2248                mError = NO_MEMORY;
2249                return NO_MEMORY;
2250            }
2251
2252            // Little hack to only acquire references on objects
2253            // we will be keeping.
2254            size_t oldObjectsSize = mObjectsSize;
2255            mObjectsSize = objectsSize;
2256            acquireObjects();
2257            mObjectsSize = oldObjectsSize;
2258        }
2259
2260        if (mData) {
2261            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2262        }
2263        if (objects && mObjects) {
2264            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
2265        }
2266        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
2267        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2268        mOwner = NULL;
2269
2270        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
2271        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2272        gParcelGlobalAllocSize += desired;
2273        gParcelGlobalAllocCount++;
2274        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2275
2276        mData = data;
2277        mObjects = objects;
2278        mDataSize = (mDataSize < desired) ? mDataSize : desired;
2279        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2280        mDataCapacity = desired;
2281        mObjectsSize = mObjectsCapacity = objectsSize;
2282        mNextObjectHint = 0;
2283
2284    } else if (mData) {
2285        if (objectsSize < mObjectsSize) {
2286            // Need to release refs on any objects we are dropping.
2287            const sp<ProcessState> proc(ProcessState::self());
2288            for (size_t i=objectsSize; i<mObjectsSize; i++) {
2289                const flat_binder_object* flat
2290                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2291                if (flat->type == BINDER_TYPE_FD) {
2292                    // will need to rescan because we may have lopped off the only FDs
2293                    mFdsKnown = false;
2294                }
2295                release_object(proc, *flat, this);
2296            }
2297            binder_size_t* objects =
2298                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2299            if (objects) {
2300                mObjects = objects;
2301            }
2302            mObjectsSize = objectsSize;
2303            mNextObjectHint = 0;
2304        }
2305
2306        // We own the data, so we can just do a realloc().
2307        if (desired > mDataCapacity) {
2308            uint8_t* data = (uint8_t*)realloc(mData, desired);
2309            if (data) {
2310                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2311                        desired);
2312                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2313                gParcelGlobalAllocSize += desired;
2314                gParcelGlobalAllocSize -= mDataCapacity;
2315                gParcelGlobalAllocCount++;
2316                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2317                mData = data;
2318                mDataCapacity = desired;
2319            } else if (desired > mDataCapacity) {
2320                mError = NO_MEMORY;
2321                return NO_MEMORY;
2322            }
2323        } else {
2324            if (mDataSize > desired) {
2325                mDataSize = desired;
2326                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2327            }
2328            if (mDataPos > desired) {
2329                mDataPos = desired;
2330                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2331            }
2332        }
2333
2334    } else {
2335        // This is the first data.  Easy!
2336        uint8_t* data = (uint8_t*)malloc(desired);
2337        if (!data) {
2338            mError = NO_MEMORY;
2339            return NO_MEMORY;
2340        }
2341
2342        if(!(mDataCapacity == 0 && mObjects == NULL
2343             && mObjectsCapacity == 0)) {
2344            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
2345        }
2346
2347        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
2348        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
2349        gParcelGlobalAllocSize += desired;
2350        gParcelGlobalAllocCount++;
2351        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
2352
2353        mData = data;
2354        mDataSize = mDataPos = 0;
2355        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2356        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
2357        mDataCapacity = desired;
2358    }
2359
2360    return NO_ERROR;
2361}
2362
2363void Parcel::initState()
2364{
2365    LOG_ALLOC("Parcel %p: initState", this);
2366    mError = NO_ERROR;
2367    mData = 0;
2368    mDataSize = 0;
2369    mDataCapacity = 0;
2370    mDataPos = 0;
2371    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2372    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
2373    mObjects = NULL;
2374    mObjectsSize = 0;
2375    mObjectsCapacity = 0;
2376    mNextObjectHint = 0;
2377    mHasFds = false;
2378    mFdsKnown = true;
2379    mAllowFds = true;
2380    mOwner = NULL;
2381    mBlobAshmemSize = 0;
2382}
2383
2384void Parcel::scanForFds() const
2385{
2386    bool hasFds = false;
2387    for (size_t i=0; i<mObjectsSize; i++) {
2388        const flat_binder_object* flat
2389            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
2390        if (flat->type == BINDER_TYPE_FD) {
2391            hasFds = true;
2392            break;
2393        }
2394    }
2395    mHasFds = hasFds;
2396    mFdsKnown = true;
2397}
2398
2399size_t Parcel::getBlobAshmemSize() const
2400{
2401    return mBlobAshmemSize;
2402}
2403
2404// --- Parcel::Blob ---
2405
2406Parcel::Blob::Blob() :
2407        mFd(-1), mData(NULL), mSize(0), mMutable(false) {
2408}
2409
2410Parcel::Blob::~Blob() {
2411    release();
2412}
2413
2414void Parcel::Blob::release() {
2415    if (mFd != -1 && mData) {
2416        ::munmap(mData, mSize);
2417    }
2418    clear();
2419}
2420
2421void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2422    mFd = fd;
2423    mData = data;
2424    mSize = size;
2425    mMutable = isMutable;
2426}
2427
2428void Parcel::Blob::clear() {
2429    mFd = -1;
2430    mData = NULL;
2431    mSize = 0;
2432    mMutable = false;
2433}
2434
2435}; // namespace android
2436