Parcel.cpp revision 13b1604018968408bcc5553e1fa5ea9df3e4e009
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            int newSize = ((mObjectsSize + numObjects)*3)/2;
488            binder_size_t *objects =
489                (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
490            if (objects == (binder_size_t*)0) {
491                return NO_MEMORY;
492            }
493            mObjects = objects;
494            mObjectsCapacity = newSize;
495        }
496
497        // append and acquire objects
498        int idx = mObjectsSize;
499        for (int i = firstIndex; i <= lastIndex; i++) {
500            size_t off = objects[i] - offset + startPos;
501            mObjects[idx++] = off;
502            mObjectsSize++;
503
504            flat_binder_object* flat
505                = reinterpret_cast<flat_binder_object*>(mData + off);
506            acquire_object(proc, *flat, this);
507
508            if (flat->type == BINDER_TYPE_FD) {
509                // If this is a file descriptor, we need to dup it so the
510                // new Parcel now owns its own fd, and can declare that we
511                // officially know we have fds.
512                flat->handle = dup(flat->handle);
513                flat->cookie = 1;
514                mHasFds = mFdsKnown = true;
515                if (!mAllowFds) {
516                    err = FDS_NOT_ALLOWED;
517                }
518            }
519        }
520    }
521
522    return err;
523}
524
525bool Parcel::allowFds() const
526{
527    return mAllowFds;
528}
529
530bool Parcel::pushAllowFds(bool allowFds)
531{
532    const bool origValue = mAllowFds;
533    if (!allowFds) {
534        mAllowFds = false;
535    }
536    return origValue;
537}
538
539void Parcel::restoreAllowFds(bool lastValue)
540{
541    mAllowFds = lastValue;
542}
543
544bool Parcel::hasFileDescriptors() const
545{
546    if (!mFdsKnown) {
547        scanForFds();
548    }
549    return mHasFds;
550}
551
552// Write RPC headers.  (previously just the interface token)
553status_t Parcel::writeInterfaceToken(const String16& interface)
554{
555    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
556               STRICT_MODE_PENALTY_GATHER);
557    // currently the interface identification token is just its name as a string
558    return writeString16(interface);
559}
560
561bool Parcel::checkInterface(IBinder* binder) const
562{
563    return enforceInterface(binder->getInterfaceDescriptor());
564}
565
566bool Parcel::enforceInterface(const String16& interface,
567                              IPCThreadState* threadState) const
568{
569    int32_t strictPolicy = readInt32();
570    if (threadState == NULL) {
571        threadState = IPCThreadState::self();
572    }
573    if ((threadState->getLastTransactionBinderFlags() &
574         IBinder::FLAG_ONEWAY) != 0) {
575      // For one-way calls, the callee is running entirely
576      // disconnected from the caller, so disable StrictMode entirely.
577      // Not only does disk/network usage not impact the caller, but
578      // there's no way to commuicate back any violations anyway.
579      threadState->setStrictModePolicy(0);
580    } else {
581      threadState->setStrictModePolicy(strictPolicy);
582    }
583    const String16 str(readString16());
584    if (str == interface) {
585        return true;
586    } else {
587        ALOGW("**** enforceInterface() expected '%s' but read '%s'",
588                String8(interface).string(), String8(str).string());
589        return false;
590    }
591}
592
593const binder_size_t* Parcel::objects() const
594{
595    return mObjects;
596}
597
598size_t Parcel::objectsCount() const
599{
600    return mObjectsSize;
601}
602
603status_t Parcel::errorCheck() const
604{
605    return mError;
606}
607
608void Parcel::setError(status_t err)
609{
610    mError = err;
611}
612
613status_t Parcel::finishWrite(size_t len)
614{
615    if (len > INT32_MAX) {
616        // don't accept size_t values which may have come from an
617        // inadvertent conversion from a negative int.
618        return BAD_VALUE;
619    }
620
621    //printf("Finish write of %d\n", len);
622    mDataPos += len;
623    ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
624    if (mDataPos > mDataSize) {
625        mDataSize = mDataPos;
626        ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
627    }
628    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
629    return NO_ERROR;
630}
631
632status_t Parcel::writeUnpadded(const void* data, size_t len)
633{
634    if (len > INT32_MAX) {
635        // don't accept size_t values which may have come from an
636        // inadvertent conversion from a negative int.
637        return BAD_VALUE;
638    }
639
640    size_t end = mDataPos + len;
641    if (end < mDataPos) {
642        // integer overflow
643        return BAD_VALUE;
644    }
645
646    if (end <= mDataCapacity) {
647restart_write:
648        memcpy(mData+mDataPos, data, len);
649        return finishWrite(len);
650    }
651
652    status_t err = growData(len);
653    if (err == NO_ERROR) goto restart_write;
654    return err;
655}
656
657status_t Parcel::write(const void* data, size_t len)
658{
659    if (len > INT32_MAX) {
660        // don't accept size_t values which may have come from an
661        // inadvertent conversion from a negative int.
662        return BAD_VALUE;
663    }
664
665    void* const d = writeInplace(len);
666    if (d) {
667        memcpy(d, data, len);
668        return NO_ERROR;
669    }
670    return mError;
671}
672
673void* Parcel::writeInplace(size_t len)
674{
675    if (len > INT32_MAX) {
676        // don't accept size_t values which may have come from an
677        // inadvertent conversion from a negative int.
678        return NULL;
679    }
680
681    const size_t padded = pad_size(len);
682
683    // sanity check for integer overflow
684    if (mDataPos+padded < mDataPos) {
685        return NULL;
686    }
687
688    if ((mDataPos+padded) <= mDataCapacity) {
689restart_write:
690        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
691        uint8_t* const data = mData+mDataPos;
692
693        // Need to pad at end?
694        if (padded != len) {
695#if BYTE_ORDER == BIG_ENDIAN
696            static const uint32_t mask[4] = {
697                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
698            };
699#endif
700#if BYTE_ORDER == LITTLE_ENDIAN
701            static const uint32_t mask[4] = {
702                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
703            };
704#endif
705            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
706            //    *reinterpret_cast<void**>(data+padded-4));
707            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
708        }
709
710        finishWrite(padded);
711        return data;
712    }
713
714    status_t err = growData(padded);
715    if (err == NO_ERROR) goto restart_write;
716    return NULL;
717}
718
719status_t Parcel::writeInt32(int32_t val)
720{
721    return writeAligned(val);
722}
723
724status_t Parcel::writeUint32(uint32_t val)
725{
726    return writeAligned(val);
727}
728
729status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
730    if (len > INT32_MAX) {
731        // don't accept size_t values which may have come from an
732        // inadvertent conversion from a negative int.
733        return BAD_VALUE;
734    }
735
736    if (!val) {
737        return writeAligned(-1);
738    }
739    status_t ret = writeAligned(len);
740    if (ret == NO_ERROR) {
741        ret = write(val, len * sizeof(*val));
742    }
743    return ret;
744}
745status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
746    if (len > INT32_MAX) {
747        // don't accept size_t values which may have come from an
748        // inadvertent conversion from a negative int.
749        return BAD_VALUE;
750    }
751
752    if (!val) {
753        return writeAligned(-1);
754    }
755    status_t ret = writeAligned(len);
756    if (ret == NO_ERROR) {
757        ret = write(val, len * sizeof(*val));
758    }
759    return ret;
760}
761
762status_t Parcel::writeInt64(int64_t val)
763{
764    return writeAligned(val);
765}
766
767status_t Parcel::writeUint64(uint64_t val)
768{
769    return writeAligned(val);
770}
771
772status_t Parcel::writePointer(uintptr_t val)
773{
774    return writeAligned<binder_uintptr_t>(val);
775}
776
777status_t Parcel::writeFloat(float val)
778{
779    return writeAligned(val);
780}
781
782#if defined(__mips__) && defined(__mips_hard_float)
783
784status_t Parcel::writeDouble(double val)
785{
786    union {
787        double d;
788        unsigned long long ll;
789    } u;
790    u.d = val;
791    return writeAligned(u.ll);
792}
793
794#else
795
796status_t Parcel::writeDouble(double val)
797{
798    return writeAligned(val);
799}
800
801#endif
802
803status_t Parcel::writeCString(const char* str)
804{
805    return write(str, strlen(str)+1);
806}
807
808status_t Parcel::writeString8(const String8& str)
809{
810    status_t err = writeInt32(str.bytes());
811    // only write string if its length is more than zero characters,
812    // as readString8 will only read if the length field is non-zero.
813    // this is slightly different from how writeString16 works.
814    if (str.bytes() > 0 && err == NO_ERROR) {
815        err = write(str.string(), str.bytes()+1);
816    }
817    return err;
818}
819
820status_t Parcel::writeString16(const String16& str)
821{
822    return writeString16(str.string(), str.size());
823}
824
825status_t Parcel::writeString16(const char16_t* str, size_t len)
826{
827    if (str == NULL) return writeInt32(-1);
828
829    status_t err = writeInt32(len);
830    if (err == NO_ERROR) {
831        len *= sizeof(char16_t);
832        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
833        if (data) {
834            memcpy(data, str, len);
835            *reinterpret_cast<char16_t*>(data+len) = 0;
836            return NO_ERROR;
837        }
838        err = mError;
839    }
840    return err;
841}
842
843status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
844{
845    return flatten_binder(ProcessState::self(), val, this);
846}
847
848status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
849{
850    return flatten_binder(ProcessState::self(), val, this);
851}
852
853status_t Parcel::writeNativeHandle(const native_handle* handle)
854{
855    if (!handle || handle->version != sizeof(native_handle))
856        return BAD_TYPE;
857
858    status_t err;
859    err = writeInt32(handle->numFds);
860    if (err != NO_ERROR) return err;
861
862    err = writeInt32(handle->numInts);
863    if (err != NO_ERROR) return err;
864
865    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
866        err = writeDupFileDescriptor(handle->data[i]);
867
868    if (err != NO_ERROR) {
869        ALOGD("write native handle, write dup fd failed");
870        return err;
871    }
872    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
873    return err;
874}
875
876status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
877{
878    flat_binder_object obj;
879    obj.type = BINDER_TYPE_FD;
880    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
881    obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
882    obj.handle = fd;
883    obj.cookie = takeOwnership ? 1 : 0;
884    return writeObject(obj, true);
885}
886
887status_t Parcel::writeDupFileDescriptor(int fd)
888{
889    int dupFd = dup(fd);
890    if (dupFd < 0) {
891        return -errno;
892    }
893    status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
894    if (err) {
895        close(dupFd);
896    }
897    return err;
898}
899
900status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
901{
902    if (len > INT32_MAX) {
903        // don't accept size_t values which may have come from an
904        // inadvertent conversion from a negative int.
905        return BAD_VALUE;
906    }
907
908    status_t status;
909    if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
910        ALOGV("writeBlob: write in place");
911        status = writeInt32(BLOB_INPLACE);
912        if (status) return status;
913
914        void* ptr = writeInplace(len);
915        if (!ptr) return NO_MEMORY;
916
917        outBlob->init(-1, ptr, len, false);
918        return NO_ERROR;
919    }
920
921    ALOGV("writeBlob: write to ashmem");
922    int fd = ashmem_create_region("Parcel Blob", len);
923    if (fd < 0) return NO_MEMORY;
924
925    mBlobAshmemSize += len;
926
927    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
928    if (result < 0) {
929        status = result;
930    } else {
931        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
932        if (ptr == MAP_FAILED) {
933            status = -errno;
934        } else {
935            if (!mutableCopy) {
936                result = ashmem_set_prot_region(fd, PROT_READ);
937            }
938            if (result < 0) {
939                status = result;
940            } else {
941                status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
942                if (!status) {
943                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
944                    if (!status) {
945                        outBlob->init(fd, ptr, len, mutableCopy);
946                        return NO_ERROR;
947                    }
948                }
949            }
950        }
951        ::munmap(ptr, len);
952    }
953    ::close(fd);
954    return status;
955}
956
957status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
958{
959    // Must match up with what's done in writeBlob.
960    if (!mAllowFds) return FDS_NOT_ALLOWED;
961    status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
962    if (status) return status;
963    return writeDupFileDescriptor(fd);
964}
965
966status_t Parcel::write(const FlattenableHelperInterface& val)
967{
968    status_t err;
969
970    // size if needed
971    const size_t len = val.getFlattenedSize();
972    const size_t fd_count = val.getFdCount();
973
974    if ((len > INT32_MAX) || (fd_count > INT32_MAX)) {
975        // don't accept size_t values which may have come from an
976        // inadvertent conversion from a negative int.
977        return BAD_VALUE;
978    }
979
980    err = this->writeInt32(len);
981    if (err) return err;
982
983    err = this->writeInt32(fd_count);
984    if (err) return err;
985
986    // payload
987    void* const buf = this->writeInplace(pad_size(len));
988    if (buf == NULL)
989        return BAD_VALUE;
990
991    int* fds = NULL;
992    if (fd_count) {
993        fds = new int[fd_count];
994    }
995
996    err = val.flatten(buf, len, fds, fd_count);
997    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
998        err = this->writeDupFileDescriptor( fds[i] );
999    }
1000
1001    if (fd_count) {
1002        delete [] fds;
1003    }
1004
1005    return err;
1006}
1007
1008status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1009{
1010    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1011    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1012    if (enoughData && enoughObjects) {
1013restart_write:
1014        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
1015
1016        // Need to write meta-data?
1017        if (nullMetaData || val.binder != 0) {
1018            mObjects[mObjectsSize] = mDataPos;
1019            acquire_object(ProcessState::self(), val, this);
1020            mObjectsSize++;
1021        }
1022
1023        // remember if it's a file descriptor
1024        if (val.type == BINDER_TYPE_FD) {
1025            if (!mAllowFds) {
1026                return FDS_NOT_ALLOWED;
1027            }
1028            mHasFds = mFdsKnown = true;
1029        }
1030
1031        return finishWrite(sizeof(flat_binder_object));
1032    }
1033
1034    if (!enoughData) {
1035        const status_t err = growData(sizeof(val));
1036        if (err != NO_ERROR) return err;
1037    }
1038    if (!enoughObjects) {
1039        size_t newSize = ((mObjectsSize+2)*3)/2;
1040        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
1041        if (objects == NULL) return NO_MEMORY;
1042        mObjects = objects;
1043        mObjectsCapacity = newSize;
1044    }
1045
1046    goto restart_write;
1047}
1048
1049status_t Parcel::writeNoException()
1050{
1051    return writeInt32(0);
1052}
1053
1054void Parcel::remove(size_t /*start*/, size_t /*amt*/)
1055{
1056    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
1057}
1058
1059status_t Parcel::read(void* outData, size_t len) const
1060{
1061    if (len > INT32_MAX) {
1062        // don't accept size_t values which may have come from an
1063        // inadvertent conversion from a negative int.
1064        return BAD_VALUE;
1065    }
1066
1067    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1068            && len <= pad_size(len)) {
1069        memcpy(outData, mData+mDataPos, len);
1070        mDataPos += pad_size(len);
1071        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1072        return NO_ERROR;
1073    }
1074    return NOT_ENOUGH_DATA;
1075}
1076
1077const void* Parcel::readInplace(size_t len) const
1078{
1079    if (len > INT32_MAX) {
1080        // don't accept size_t values which may have come from an
1081        // inadvertent conversion from a negative int.
1082        return NULL;
1083    }
1084
1085    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1086            && len <= pad_size(len)) {
1087        const void* data = mData+mDataPos;
1088        mDataPos += pad_size(len);
1089        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
1090        return data;
1091    }
1092    return NULL;
1093}
1094
1095template<class T>
1096status_t Parcel::readAligned(T *pArg) const {
1097    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
1098
1099    if ((mDataPos+sizeof(T)) <= mDataSize) {
1100        const void* data = mData+mDataPos;
1101        mDataPos += sizeof(T);
1102        *pArg =  *reinterpret_cast<const T*>(data);
1103        return NO_ERROR;
1104    } else {
1105        return NOT_ENOUGH_DATA;
1106    }
1107}
1108
1109template<class T>
1110T Parcel::readAligned() const {
1111    T result;
1112    if (readAligned(&result) != NO_ERROR) {
1113        result = 0;
1114    }
1115
1116    return result;
1117}
1118
1119template<class T>
1120status_t Parcel::writeAligned(T val) {
1121    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
1122
1123    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1124restart_write:
1125        *reinterpret_cast<T*>(mData+mDataPos) = val;
1126        return finishWrite(sizeof(val));
1127    }
1128
1129    status_t err = growData(sizeof(val));
1130    if (err == NO_ERROR) goto restart_write;
1131    return err;
1132}
1133
1134status_t Parcel::readInt32(int32_t *pArg) const
1135{
1136    return readAligned(pArg);
1137}
1138
1139int32_t Parcel::readInt32() const
1140{
1141    return readAligned<int32_t>();
1142}
1143
1144status_t Parcel::readUint32(uint32_t *pArg) const
1145{
1146    return readAligned(pArg);
1147}
1148
1149uint32_t Parcel::readUint32() const
1150{
1151    return readAligned<uint32_t>();
1152}
1153
1154status_t Parcel::readInt64(int64_t *pArg) const
1155{
1156    return readAligned(pArg);
1157}
1158
1159
1160int64_t Parcel::readInt64() const
1161{
1162    return readAligned<int64_t>();
1163}
1164
1165status_t Parcel::readUint64(uint64_t *pArg) const
1166{
1167    return readAligned(pArg);
1168}
1169
1170uint64_t Parcel::readUint64() const
1171{
1172    return readAligned<uint64_t>();
1173}
1174
1175status_t Parcel::readPointer(uintptr_t *pArg) const
1176{
1177    status_t ret;
1178    binder_uintptr_t ptr;
1179    ret = readAligned(&ptr);
1180    if (!ret)
1181        *pArg = ptr;
1182    return ret;
1183}
1184
1185uintptr_t Parcel::readPointer() const
1186{
1187    return readAligned<binder_uintptr_t>();
1188}
1189
1190
1191status_t Parcel::readFloat(float *pArg) const
1192{
1193    return readAligned(pArg);
1194}
1195
1196
1197float Parcel::readFloat() const
1198{
1199    return readAligned<float>();
1200}
1201
1202#if defined(__mips__) && defined(__mips_hard_float)
1203
1204status_t Parcel::readDouble(double *pArg) const
1205{
1206    union {
1207      double d;
1208      unsigned long long ll;
1209    } u;
1210    u.d = 0;
1211    status_t status;
1212    status = readAligned(&u.ll);
1213    *pArg = u.d;
1214    return status;
1215}
1216
1217double Parcel::readDouble() const
1218{
1219    union {
1220      double d;
1221      unsigned long long ll;
1222    } u;
1223    u.ll = readAligned<unsigned long long>();
1224    return u.d;
1225}
1226
1227#else
1228
1229status_t Parcel::readDouble(double *pArg) const
1230{
1231    return readAligned(pArg);
1232}
1233
1234double Parcel::readDouble() const
1235{
1236    return readAligned<double>();
1237}
1238
1239#endif
1240
1241status_t Parcel::readIntPtr(intptr_t *pArg) const
1242{
1243    return readAligned(pArg);
1244}
1245
1246
1247intptr_t Parcel::readIntPtr() const
1248{
1249    return readAligned<intptr_t>();
1250}
1251
1252
1253const char* Parcel::readCString() const
1254{
1255    const size_t avail = mDataSize-mDataPos;
1256    if (avail > 0) {
1257        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1258        // is the string's trailing NUL within the parcel's valid bounds?
1259        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1260        if (eos) {
1261            const size_t len = eos - str;
1262            mDataPos += pad_size(len+1);
1263            ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
1264            return str;
1265        }
1266    }
1267    return NULL;
1268}
1269
1270String8 Parcel::readString8() const
1271{
1272    int32_t size = readInt32();
1273    // watch for potential int overflow adding 1 for trailing NUL
1274    if (size > 0 && size < INT32_MAX) {
1275        const char* str = (const char*)readInplace(size+1);
1276        if (str) return String8(str, size);
1277    }
1278    return String8();
1279}
1280
1281String16 Parcel::readString16() const
1282{
1283    size_t len;
1284    const char16_t* str = readString16Inplace(&len);
1285    if (str) return String16(str, len);
1286    ALOGE("Reading a NULL string not supported here.");
1287    return String16();
1288}
1289
1290const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1291{
1292    int32_t size = readInt32();
1293    // watch for potential int overflow from size+1
1294    if (size >= 0 && size < INT32_MAX) {
1295        *outLen = size;
1296        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1297        if (str != NULL) {
1298            return str;
1299        }
1300    }
1301    *outLen = 0;
1302    return NULL;
1303}
1304
1305sp<IBinder> Parcel::readStrongBinder() const
1306{
1307    sp<IBinder> val;
1308    unflatten_binder(ProcessState::self(), *this, &val);
1309    return val;
1310}
1311
1312wp<IBinder> Parcel::readWeakBinder() const
1313{
1314    wp<IBinder> val;
1315    unflatten_binder(ProcessState::self(), *this, &val);
1316    return val;
1317}
1318
1319int32_t Parcel::readExceptionCode() const
1320{
1321  int32_t exception_code = readAligned<int32_t>();
1322  if (exception_code == EX_HAS_REPLY_HEADER) {
1323    int32_t header_start = dataPosition();
1324    int32_t header_size = readAligned<int32_t>();
1325    // Skip over fat responses headers.  Not used (or propagated) in
1326    // native code
1327    setDataPosition(header_start + header_size);
1328    // And fat response headers are currently only used when there are no
1329    // exceptions, so return no error:
1330    return 0;
1331  }
1332  return exception_code;
1333}
1334
1335native_handle* Parcel::readNativeHandle() const
1336{
1337    int numFds, numInts;
1338    status_t err;
1339    err = readInt32(&numFds);
1340    if (err != NO_ERROR) return 0;
1341    err = readInt32(&numInts);
1342    if (err != NO_ERROR) return 0;
1343
1344    native_handle* h = native_handle_create(numFds, numInts);
1345    if (!h) {
1346        return 0;
1347    }
1348
1349    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
1350        h->data[i] = dup(readFileDescriptor());
1351        if (h->data[i] < 0) err = BAD_VALUE;
1352    }
1353    err = read(h->data + numFds, sizeof(int)*numInts);
1354    if (err != NO_ERROR) {
1355        native_handle_close(h);
1356        native_handle_delete(h);
1357        h = 0;
1358    }
1359    return h;
1360}
1361
1362
1363int Parcel::readFileDescriptor() const
1364{
1365    const flat_binder_object* flat = readObject(true);
1366    if (flat) {
1367        switch (flat->type) {
1368            case BINDER_TYPE_FD:
1369                //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
1370                return flat->handle;
1371        }
1372    }
1373    return BAD_TYPE;
1374}
1375
1376status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
1377{
1378    int32_t blobType;
1379    status_t status = readInt32(&blobType);
1380    if (status) return status;
1381
1382    if (blobType == BLOB_INPLACE) {
1383        ALOGV("readBlob: read in place");
1384        const void* ptr = readInplace(len);
1385        if (!ptr) return BAD_VALUE;
1386
1387        outBlob->init(-1, const_cast<void*>(ptr), len, false);
1388        return NO_ERROR;
1389    }
1390
1391    ALOGV("readBlob: read from ashmem");
1392    bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
1393    int fd = readFileDescriptor();
1394    if (fd == int(BAD_TYPE)) return BAD_VALUE;
1395
1396    void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
1397            MAP_SHARED, fd, 0);
1398    if (ptr == MAP_FAILED) return NO_MEMORY;
1399
1400    outBlob->init(fd, ptr, len, isMutable);
1401    return NO_ERROR;
1402}
1403
1404status_t Parcel::read(FlattenableHelperInterface& val) const
1405{
1406    // size
1407    const size_t len = this->readInt32();
1408    const size_t fd_count = this->readInt32();
1409
1410    if (len > INT32_MAX) {
1411        // don't accept size_t values which may have come from an
1412        // inadvertent conversion from a negative int.
1413        return BAD_VALUE;
1414    }
1415
1416    // payload
1417    void const* const buf = this->readInplace(pad_size(len));
1418    if (buf == NULL)
1419        return BAD_VALUE;
1420
1421    int* fds = NULL;
1422    if (fd_count) {
1423        fds = new int[fd_count];
1424    }
1425
1426    status_t err = NO_ERROR;
1427    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1428        fds[i] = dup(this->readFileDescriptor());
1429        if (fds[i] < 0) {
1430            err = BAD_VALUE;
1431            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
1432                i, fds[i], fd_count, strerror(errno));
1433        }
1434    }
1435
1436    if (err == NO_ERROR) {
1437        err = val.unflatten(buf, len, fds, fd_count);
1438    }
1439
1440    if (fd_count) {
1441        delete [] fds;
1442    }
1443
1444    return err;
1445}
1446const flat_binder_object* Parcel::readObject(bool nullMetaData) const
1447{
1448    const size_t DPOS = mDataPos;
1449    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
1450        const flat_binder_object* obj
1451                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
1452        mDataPos = DPOS + sizeof(flat_binder_object);
1453        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
1454            // When transferring a NULL object, we don't write it into
1455            // the object list, so we don't want to check for it when
1456            // reading.
1457            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1458            return obj;
1459        }
1460
1461        // Ensure that this object is valid...
1462        binder_size_t* const OBJS = mObjects;
1463        const size_t N = mObjectsSize;
1464        size_t opos = mNextObjectHint;
1465
1466        if (N > 0) {
1467            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
1468                 this, DPOS, opos);
1469
1470            // Start at the current hint position, looking for an object at
1471            // the current data position.
1472            if (opos < N) {
1473                while (opos < (N-1) && OBJS[opos] < DPOS) {
1474                    opos++;
1475                }
1476            } else {
1477                opos = N-1;
1478            }
1479            if (OBJS[opos] == DPOS) {
1480                // Found it!
1481                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
1482                     this, DPOS, opos);
1483                mNextObjectHint = opos+1;
1484                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1485                return obj;
1486            }
1487
1488            // Look backwards for it...
1489            while (opos > 0 && OBJS[opos] > DPOS) {
1490                opos--;
1491            }
1492            if (OBJS[opos] == DPOS) {
1493                // Found it!
1494                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
1495                     this, DPOS, opos);
1496                mNextObjectHint = opos+1;
1497                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1498                return obj;
1499            }
1500        }
1501        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1502             this, DPOS);
1503    }
1504    return NULL;
1505}
1506
1507void Parcel::closeFileDescriptors()
1508{
1509    size_t i = mObjectsSize;
1510    if (i > 0) {
1511        //ALOGI("Closing file descriptors for %zu objects...", i);
1512    }
1513    while (i > 0) {
1514        i--;
1515        const flat_binder_object* flat
1516            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1517        if (flat->type == BINDER_TYPE_FD) {
1518            //ALOGI("Closing fd: %ld", flat->handle);
1519            close(flat->handle);
1520        }
1521    }
1522}
1523
1524uintptr_t Parcel::ipcData() const
1525{
1526    return reinterpret_cast<uintptr_t>(mData);
1527}
1528
1529size_t Parcel::ipcDataSize() const
1530{
1531    return (mDataSize > mDataPos ? mDataSize : mDataPos);
1532}
1533
1534uintptr_t Parcel::ipcObjects() const
1535{
1536    return reinterpret_cast<uintptr_t>(mObjects);
1537}
1538
1539size_t Parcel::ipcObjectsCount() const
1540{
1541    return mObjectsSize;
1542}
1543
1544void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
1545    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
1546{
1547    binder_size_t minOffset = 0;
1548    freeDataNoInit();
1549    mError = NO_ERROR;
1550    mData = const_cast<uint8_t*>(data);
1551    mDataSize = mDataCapacity = dataSize;
1552    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
1553    mDataPos = 0;
1554    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
1555    mObjects = const_cast<binder_size_t*>(objects);
1556    mObjectsSize = mObjectsCapacity = objectsCount;
1557    mNextObjectHint = 0;
1558    mOwner = relFunc;
1559    mOwnerCookie = relCookie;
1560    for (size_t i = 0; i < mObjectsSize; i++) {
1561        binder_size_t offset = mObjects[i];
1562        if (offset < minOffset) {
1563            ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
1564                  __func__, (uint64_t)offset, (uint64_t)minOffset);
1565            mObjectsSize = 0;
1566            break;
1567        }
1568        minOffset = offset + sizeof(flat_binder_object);
1569    }
1570    scanForFds();
1571}
1572
1573void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
1574{
1575    to << "Parcel(";
1576
1577    if (errorCheck() != NO_ERROR) {
1578        const status_t err = errorCheck();
1579        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
1580    } else if (dataSize() > 0) {
1581        const uint8_t* DATA = data();
1582        to << indent << HexDump(DATA, dataSize()) << dedent;
1583        const binder_size_t* OBJS = objects();
1584        const size_t N = objectsCount();
1585        for (size_t i=0; i<N; i++) {
1586            const flat_binder_object* flat
1587                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
1588            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
1589                << TypeCode(flat->type & 0x7f7f7f00)
1590                << " = " << flat->binder;
1591        }
1592    } else {
1593        to << "NULL";
1594    }
1595
1596    to << ")";
1597}
1598
1599void Parcel::releaseObjects()
1600{
1601    const sp<ProcessState> proc(ProcessState::self());
1602    size_t i = mObjectsSize;
1603    uint8_t* const data = mData;
1604    binder_size_t* const objects = mObjects;
1605    while (i > 0) {
1606        i--;
1607        const flat_binder_object* flat
1608            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1609        release_object(proc, *flat, this);
1610    }
1611}
1612
1613void Parcel::acquireObjects()
1614{
1615    const sp<ProcessState> proc(ProcessState::self());
1616    size_t i = mObjectsSize;
1617    uint8_t* const data = mData;
1618    binder_size_t* const objects = mObjects;
1619    while (i > 0) {
1620        i--;
1621        const flat_binder_object* flat
1622            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1623        acquire_object(proc, *flat, this);
1624    }
1625}
1626
1627void Parcel::freeData()
1628{
1629    freeDataNoInit();
1630    initState();
1631}
1632
1633void Parcel::freeDataNoInit()
1634{
1635    if (mOwner) {
1636        LOG_ALLOC("Parcel %p: freeing other owner data", this);
1637        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
1638        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1639    } else {
1640        LOG_ALLOC("Parcel %p: freeing allocated data", this);
1641        releaseObjects();
1642        if (mData) {
1643            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
1644            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
1645            gParcelGlobalAllocSize -= mDataCapacity;
1646            gParcelGlobalAllocCount--;
1647            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
1648            free(mData);
1649        }
1650        if (mObjects) free(mObjects);
1651    }
1652}
1653
1654status_t Parcel::growData(size_t len)
1655{
1656    if (len > INT32_MAX) {
1657        // don't accept size_t values which may have come from an
1658        // inadvertent conversion from a negative int.
1659        return BAD_VALUE;
1660    }
1661
1662    size_t newSize = ((mDataSize+len)*3)/2;
1663    return (newSize <= mDataSize)
1664            ? (status_t) NO_MEMORY
1665            : continueWrite(newSize);
1666}
1667
1668status_t Parcel::restartWrite(size_t desired)
1669{
1670    if (desired > INT32_MAX) {
1671        // don't accept size_t values which may have come from an
1672        // inadvertent conversion from a negative int.
1673        return BAD_VALUE;
1674    }
1675
1676    if (mOwner) {
1677        freeData();
1678        return continueWrite(desired);
1679    }
1680
1681    uint8_t* data = (uint8_t*)realloc(mData, desired);
1682    if (!data && desired > mDataCapacity) {
1683        mError = NO_MEMORY;
1684        return NO_MEMORY;
1685    }
1686
1687    releaseObjects();
1688
1689    if (data) {
1690        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
1691        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
1692        gParcelGlobalAllocSize += desired;
1693        gParcelGlobalAllocSize -= mDataCapacity;
1694        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
1695        mData = data;
1696        mDataCapacity = desired;
1697    }
1698
1699    mDataSize = mDataPos = 0;
1700    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
1701    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
1702
1703    free(mObjects);
1704    mObjects = NULL;
1705    mObjectsSize = mObjectsCapacity = 0;
1706    mNextObjectHint = 0;
1707    mHasFds = false;
1708    mFdsKnown = true;
1709    mAllowFds = true;
1710
1711    return NO_ERROR;
1712}
1713
1714status_t Parcel::continueWrite(size_t desired)
1715{
1716    if (desired > INT32_MAX) {
1717        // don't accept size_t values which may have come from an
1718        // inadvertent conversion from a negative int.
1719        return BAD_VALUE;
1720    }
1721
1722    // If shrinking, first adjust for any objects that appear
1723    // after the new data size.
1724    size_t objectsSize = mObjectsSize;
1725    if (desired < mDataSize) {
1726        if (desired == 0) {
1727            objectsSize = 0;
1728        } else {
1729            while (objectsSize > 0) {
1730                if (mObjects[objectsSize-1] < desired)
1731                    break;
1732                objectsSize--;
1733            }
1734        }
1735    }
1736
1737    if (mOwner) {
1738        // If the size is going to zero, just release the owner's data.
1739        if (desired == 0) {
1740            freeData();
1741            return NO_ERROR;
1742        }
1743
1744        // If there is a different owner, we need to take
1745        // posession.
1746        uint8_t* data = (uint8_t*)malloc(desired);
1747        if (!data) {
1748            mError = NO_MEMORY;
1749            return NO_MEMORY;
1750        }
1751        binder_size_t* objects = NULL;
1752
1753        if (objectsSize) {
1754            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
1755            if (!objects) {
1756                free(data);
1757
1758                mError = NO_MEMORY;
1759                return NO_MEMORY;
1760            }
1761
1762            // Little hack to only acquire references on objects
1763            // we will be keeping.
1764            size_t oldObjectsSize = mObjectsSize;
1765            mObjectsSize = objectsSize;
1766            acquireObjects();
1767            mObjectsSize = oldObjectsSize;
1768        }
1769
1770        if (mData) {
1771            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
1772        }
1773        if (objects && mObjects) {
1774            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
1775        }
1776        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
1777        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1778        mOwner = NULL;
1779
1780        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
1781        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
1782        gParcelGlobalAllocSize += desired;
1783        gParcelGlobalAllocCount++;
1784        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
1785
1786        mData = data;
1787        mObjects = objects;
1788        mDataSize = (mDataSize < desired) ? mDataSize : desired;
1789        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1790        mDataCapacity = desired;
1791        mObjectsSize = mObjectsCapacity = objectsSize;
1792        mNextObjectHint = 0;
1793
1794    } else if (mData) {
1795        if (objectsSize < mObjectsSize) {
1796            // Need to release refs on any objects we are dropping.
1797            const sp<ProcessState> proc(ProcessState::self());
1798            for (size_t i=objectsSize; i<mObjectsSize; i++) {
1799                const flat_binder_object* flat
1800                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1801                if (flat->type == BINDER_TYPE_FD) {
1802                    // will need to rescan because we may have lopped off the only FDs
1803                    mFdsKnown = false;
1804                }
1805                release_object(proc, *flat, this);
1806            }
1807            binder_size_t* objects =
1808                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
1809            if (objects) {
1810                mObjects = objects;
1811            }
1812            mObjectsSize = objectsSize;
1813            mNextObjectHint = 0;
1814        }
1815
1816        // We own the data, so we can just do a realloc().
1817        if (desired > mDataCapacity) {
1818            uint8_t* data = (uint8_t*)realloc(mData, desired);
1819            if (data) {
1820                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
1821                        desired);
1822                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
1823                gParcelGlobalAllocSize += desired;
1824                gParcelGlobalAllocSize -= mDataCapacity;
1825                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
1826                mData = data;
1827                mDataCapacity = desired;
1828            } else if (desired > mDataCapacity) {
1829                mError = NO_MEMORY;
1830                return NO_MEMORY;
1831            }
1832        } else {
1833            if (mDataSize > desired) {
1834                mDataSize = desired;
1835                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1836            }
1837            if (mDataPos > desired) {
1838                mDataPos = desired;
1839                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
1840            }
1841        }
1842
1843    } else {
1844        // This is the first data.  Easy!
1845        uint8_t* data = (uint8_t*)malloc(desired);
1846        if (!data) {
1847            mError = NO_MEMORY;
1848            return NO_MEMORY;
1849        }
1850
1851        if(!(mDataCapacity == 0 && mObjects == NULL
1852             && mObjectsCapacity == 0)) {
1853            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
1854        }
1855
1856        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
1857        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
1858        gParcelGlobalAllocSize += desired;
1859        gParcelGlobalAllocCount++;
1860        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
1861
1862        mData = data;
1863        mDataSize = mDataPos = 0;
1864        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1865        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
1866        mDataCapacity = desired;
1867    }
1868
1869    return NO_ERROR;
1870}
1871
1872void Parcel::initState()
1873{
1874    LOG_ALLOC("Parcel %p: initState", this);
1875    mError = NO_ERROR;
1876    mData = 0;
1877    mDataSize = 0;
1878    mDataCapacity = 0;
1879    mDataPos = 0;
1880    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
1881    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
1882    mObjects = NULL;
1883    mObjectsSize = 0;
1884    mObjectsCapacity = 0;
1885    mNextObjectHint = 0;
1886    mHasFds = false;
1887    mFdsKnown = true;
1888    mAllowFds = true;
1889    mOwner = NULL;
1890    mBlobAshmemSize = 0;
1891}
1892
1893void Parcel::scanForFds() const
1894{
1895    bool hasFds = false;
1896    for (size_t i=0; i<mObjectsSize; i++) {
1897        const flat_binder_object* flat
1898            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
1899        if (flat->type == BINDER_TYPE_FD) {
1900            hasFds = true;
1901            break;
1902        }
1903    }
1904    mHasFds = hasFds;
1905    mFdsKnown = true;
1906}
1907
1908size_t Parcel::getBlobAshmemSize() const
1909{
1910    return mBlobAshmemSize;
1911}
1912
1913// --- Parcel::Blob ---
1914
1915Parcel::Blob::Blob() :
1916        mFd(-1), mData(NULL), mSize(0), mMutable(false) {
1917}
1918
1919Parcel::Blob::~Blob() {
1920    release();
1921}
1922
1923void Parcel::Blob::release() {
1924    if (mFd != -1 && mData) {
1925        ::munmap(mData, mSize);
1926    }
1927    clear();
1928}
1929
1930void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
1931    mFd = fd;
1932    mData = data;
1933    mSize = size;
1934    mMutable = isMutable;
1935}
1936
1937void Parcel::Blob::clear() {
1938    mFd = -1;
1939    mData = NULL;
1940    mSize = 0;
1941    mMutable = false;
1942}
1943
1944}; // namespace android
1945