/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "hw-Parcel"
//#define LOG_NDEBUG 0

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>

#include <hwbinder/Binder.h>
#include <hwbinder/BpHwBinder.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/Parcel.h>
#include <hwbinder/ProcessState.h>
#include <hwbinder/TextOutput.h>
#include <hwbinder/binder_kernel.h>

#include <cutils/ashmem.h>
#include <utils/Debug.h>
#include <utils/Log.h>
#include <utils/misc.h>
#include <utils/String8.h>
#include <utils/String16.h>

#include <private/binder/binder_module.h>
#include <hwbinder/Static.h>

#ifndef INT32_MAX
#define INT32_MAX ((int32_t)(2147483647))
#endif

#define LOG_REFS(...)
//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOG_ALLOC(...)
//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOG_BUFFER(...)
// #define LOG_BUFFER(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)

// ---------------------------------------------------------------------------

// This macro should never be used at runtime, as a too large value
// of s could cause an integer overflow. Instead, you should always
// use the wrapper function pad_size()
#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)

static size_t pad_size(size_t s) {
    if (s > (SIZE_T_MAX - 3)) {
        abort();
    }
    return PAD_SIZE_UNSAFE(s);
}

// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)

// XXX This can be made public if we want to provide
// support for typed data.
struct small_flat_data
{
    uint32_t type;
    uint32_t data;
};

namespace android {
namespace hardware {

static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
static size_t gParcelGlobalAllocSize = 0;
static size_t gParcelGlobalAllocCount = 0;

static size_t gMaxFds = 0;

static const size_t PARCEL_REF_CAP = 1024;

void acquire_binder_object(const sp<ProcessState>& proc,
    const flat_binder_object& obj, const void* who)
{
    switch (obj.hdr.type) {
        case BINDER_TYPE_BINDER:
            if (obj.binder) {
                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
                reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
            }
            return;
        case BINDER_TYPE_WEAK_BINDER:
            if (obj.binder)
                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
            return;
        case BINDER_TYPE_HANDLE: {
            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
            if (b != NULL) {
                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
                b->incStrong(who);
            }
            return;
        }
        case BINDER_TYPE_WEAK_HANDLE: {
            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
            if (b != NULL) b.get_refs()->incWeak(who);
            return;
        }
    }

    ALOGD("Invalid object type 0x%08x", obj.hdr.type);
}

void acquire_object(const sp<ProcessState>& proc, const binder_object_header& obj,
        const void *who) {
    switch (obj.type) {
        case BINDER_TYPE_BINDER:
        case BINDER_TYPE_WEAK_BINDER:
        case BINDER_TYPE_HANDLE:
        case BINDER_TYPE_WEAK_HANDLE: {
            const flat_binder_object& fbo = reinterpret_cast<const flat_binder_object&>(obj);
            acquire_binder_object(proc, fbo, who);
            break;
        }
    }
}

void release_object(const sp<ProcessState>& proc,
    const flat_binder_object& obj, const void* who)
{
    switch (obj.hdr.type) {
        case BINDER_TYPE_BINDER:
            if (obj.binder) {
                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
                reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
            }
            return;
        case BINDER_TYPE_WEAK_BINDER:
            if (obj.binder)
                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
            return;
        case BINDER_TYPE_HANDLE: {
            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
            if (b != NULL) {
                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
                b->decStrong(who);
            }
            return;
        }
        case BINDER_TYPE_WEAK_HANDLE: {
            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
            if (b != NULL) b.get_refs()->decWeak(who);
            return;
        }
        case BINDER_TYPE_FD: {
            if (obj.cookie != 0) { // owned
                close(obj.handle);
            }
            return;
        }
        case BINDER_TYPE_PTR: {
            // The relevant buffer is part of the transaction buffer and will be freed that way
            return;
        }
        case BINDER_TYPE_FDA: {
            // The enclosed file descriptors are closed in the kernel
            return;
        }
    }

    ALOGE("Invalid object type 0x%08x", obj.hdr.type);
}

inline static status_t finish_flatten_binder(
    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
    return out->writeObject(flat);
}

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;

    if (binder != NULL) {
        BHwBinder *local = binder->localBinder();
        if (!local) {
            BpHwBinder *proxy = binder->remoteBinder();
            if (proxy == NULL) {
                ALOGE("null proxy");
            }
            const int32_t handle = proxy ? proxy->handle() : 0;
            obj.hdr.type = BINDER_TYPE_HANDLE;
            obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
            obj.handle = handle;
            obj.cookie = 0;
        } else {
            // Get policy and convert it
            int policy = local->getMinSchedulingPolicy();
            int priority = local->getMinSchedulingPriority();

            obj.flags = priority & FLAT_BINDER_FLAG_PRIORITY_MASK;
            obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | FLAT_BINDER_FLAG_INHERIT_RT;
            obj.flags |= (policy & 3) << FLAT_BINDER_FLAG_SCHEDPOLICY_SHIFT;
            if (local->isRequestingSid()) {
                obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
            }
            obj.hdr.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    } else {
        obj.hdr.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
    }

    return finish_flatten_binder(binder, obj, out);
}

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const wp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;

    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if (binder != NULL) {
        sp<IBinder> real = binder.promote();
        if (real != NULL) {
            IBinder *local = real->localBinder();
            if (!local) {
                BpHwBinder *proxy = real->remoteBinder();
                if (proxy == NULL) {
                    ALOGE("null proxy");
                }
                const int32_t handle = proxy ? proxy->handle() : 0;
                obj.hdr.type = BINDER_TYPE_WEAK_HANDLE;
                obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
                obj.handle = handle;
                obj.cookie = 0;
            } else {
                obj.hdr.type = BINDER_TYPE_WEAK_BINDER;
                obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
                obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
            }
            return finish_flatten_binder(real, obj, out);
        }

        // XXX How to deal?  In order to flatten the given binder,
        // we need to probe it for information, which requires a primary
        // reference...  but we don't have one.
        //
        // The OpenBinder implementation uses a dynamic_cast<> here,
        // but we can't do that with the different reference counting
        // implementation we are using.
        ALOGE("Unable to unflatten Binder weak reference!");
        obj.hdr.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
        return finish_flatten_binder(NULL, obj, out);

    } else {
        obj.hdr.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
        return finish_flatten_binder(NULL, obj, out);
    }
}

inline static status_t finish_unflatten_binder(
    BpHwBinder* /*proxy*/, const flat_binder_object& /*flat*/,
    const Parcel& /*in*/)
{
    return NO_ERROR;
}

status_t unflatten_binder(const sp<ProcessState>& proc,
    const Parcel& in, sp<IBinder>* out)
{
    const flat_binder_object* flat = in.readObject<flat_binder_object>();

    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast<IBinder*>(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast<BpHwBinder*>(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

status_t unflatten_binder(const sp<ProcessState>& proc,
    const Parcel& in, wp<IBinder>* out)
{
    const flat_binder_object* flat = in.readObject<flat_binder_object>();

    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast<IBinder*>(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_WEAK_BINDER:
                if (flat->binder != 0) {
                    out->set_object_and_refs(
                        reinterpret_cast<IBinder*>(flat->cookie),
                        reinterpret_cast<RefBase::weakref_type*>(flat->binder));
                } else {
                    *out = NULL;
                }
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_HANDLE:
            case BINDER_TYPE_WEAK_HANDLE:
                *out = proc->getWeakProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast<BpHwBinder*>(out->unsafe_get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

/*
 * Return true iff:
 * 1. obj is indeed a binder_buffer_object (type is BINDER_TYPE_PTR), and
 * 2. obj does NOT have the flag BINDER_BUFFER_FLAG_REF (it is not a reference, but
 *    an actual buffer.)
 */
static inline bool isBuffer(const binder_buffer_object& obj) {
    return obj.hdr.type == BINDER_TYPE_PTR
        && (obj.flags & BINDER_BUFFER_FLAG_REF) == 0;
}

// ---------------------------------------------------------------------------

Parcel::Parcel()
{
    LOG_ALLOC("Parcel %p: constructing", this);
    initState();
}

Parcel::~Parcel()
{
    freeDataNoInit();
    LOG_ALLOC("Parcel %p: destroyed", this);
}

size_t Parcel::getGlobalAllocSize() {
    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
    size_t size = gParcelGlobalAllocSize;
    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
    return size;
}

size_t Parcel::getGlobalAllocCount() {
    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
    size_t count = gParcelGlobalAllocCount;
    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
    return count;
}

const uint8_t* Parcel::data() const
{
    return mData;
}

size_t Parcel::dataSize() const
{
    return (mDataSize > mDataPos ? mDataSize : mDataPos);
}

size_t Parcel::dataAvail() const
{
    size_t result = dataSize() - dataPosition();
    if (result > INT32_MAX) {
        abort();
    }
    return result;
}

size_t Parcel::dataPosition() const
{
    return mDataPos;
}

size_t Parcel::dataCapacity() const
{
    return mDataCapacity;
}

status_t Parcel::setDataSize(size_t size)
{
    if (size > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    status_t err;
    err = continueWrite(size);
    if (err == NO_ERROR) {
        mDataSize = size;
        ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
    }
    return err;
}

void Parcel::setDataPosition(size_t pos) const
{
    if (pos > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        abort();
    }

    mDataPos = pos;
    mNextObjectHint = 0;
}

status_t Parcel::setDataCapacity(size_t size)
{
    if (size > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    if (size > mDataCapacity) return continueWrite(size);
    return NO_ERROR;
}

status_t Parcel::setData(const uint8_t* buffer, size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    status_t err = restartWrite(len);
    if (err == NO_ERROR) {
        memcpy(const_cast<uint8_t*>(data()), buffer, len);
        mDataSize = len;
        mFdsKnown = false;
    }
    return err;
}

// Write RPC headers.  (previously just the interface token)
status_t Parcel::writeInterfaceToken(const char* interface)
{
    // currently the interface identification token is just its name as a string
    return writeCString(interface);
}

bool Parcel::enforceInterface(const char* interface) const
{
    const char* str = readCString();
    if (strcmp(str, interface) == 0) {
        return true;
    } else {
        ALOGW("**** enforceInterface() expected '%s' but read '%s'",
                String8(interface).string(), String8(str).string());
        return false;
    }
}

const binder_size_t* Parcel::objects() const
{
    return mObjects;
}

size_t Parcel::objectsCount() const
{
    return mObjectsSize;
}

status_t Parcel::errorCheck() const
{
    return mError;
}

void Parcel::setError(status_t err)
{
    mError = err;
}

status_t Parcel::finishWrite(size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    //printf("Finish write of %d\n", len);
    mDataPos += len;
    ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
    if (mDataPos > mDataSize) {
        mDataSize = mDataPos;
        ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
    }
    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
    return NO_ERROR;
}

status_t Parcel::writeUnpadded(const void* data, size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    size_t end = mDataPos + len;
    if (end < mDataPos) {
        // integer overflow
        return BAD_VALUE;
    }

    if (end <= mDataCapacity) {
restart_write:
        memcpy(mData+mDataPos, data, len);
        return finishWrite(len);
    }

    status_t err = growData(len);
    if (err == NO_ERROR) goto restart_write;
    return err;
}

status_t Parcel::write(const void* data, size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    void* const d = writeInplace(len);
    if (d) {
        memcpy(d, data, len);
        return NO_ERROR;
    }
    return mError;
}

void* Parcel::writeInplace(size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return NULL;
    }

    const size_t padded = pad_size(len);

    // sanity check for integer overflow
    if (mDataPos+padded < mDataPos) {
        return NULL;
    }

    if ((mDataPos+padded) <= mDataCapacity) {
restart_write:
        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
        uint8_t* const data = mData+mDataPos;

        // Need to pad at end?
        if (padded != len) {
#if BYTE_ORDER == BIG_ENDIAN
            static const uint32_t mask[4] = {
                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
            };
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
            static const uint32_t mask[4] = {
                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
            };
#endif
            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
            //    *reinterpret_cast<void**>(data+padded-4));
            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
        }

        finishWrite(padded);
        return data;
    }

    status_t err = growData(padded);
    if (err == NO_ERROR) goto restart_write;
    return NULL;
}

status_t Parcel::writeInt8(int8_t val)
{
    return write(&val, sizeof(val));
}

status_t Parcel::writeUint8(uint8_t val)
{
    return write(&val, sizeof(val));
}

status_t Parcel::writeInt16(int16_t val)
{
    return write(&val, sizeof(val));
}

status_t Parcel::writeUint16(uint16_t val)
{
    return write(&val, sizeof(val));
}

status_t Parcel::writeInt32(int32_t val)
{
    return writeAligned(val);
}

status_t Parcel::writeUint32(uint32_t val)
{
    return writeAligned(val);
}

status_t Parcel::writeBool(bool val)
{
    return writeInt8(int8_t(val));
}
status_t Parcel::writeInt64(int64_t val)
{
    return writeAligned(val);
}

status_t Parcel::writeUint64(uint64_t val)
{
    return writeAligned(val);
}

status_t Parcel::writePointer(uintptr_t val)
{
    return writeAligned<binder_uintptr_t>(val);
}

status_t Parcel::writeFloat(float val)
{
    return writeAligned(val);
}

#if defined(__mips__) && defined(__mips_hard_float)

status_t Parcel::writeDouble(double val)
{
    union {
        double d;
        unsigned long long ll;
    } u;
    u.d = val;
    return writeAligned(u.ll);
}

#else

status_t Parcel::writeDouble(double val)
{
    return writeAligned(val);
}

#endif

status_t Parcel::writeCString(const char* str)
{
    return write(str, strlen(str)+1);
}
status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
{
    if (!str) {
        return writeInt32(-1);
    }

    return writeString16(*str);
}

status_t Parcel::writeString16(const String16& str)
{
    return writeString16(str.string(), str.size());
}

status_t Parcel::writeString16(const char16_t* str, size_t len)
{
    if (str == NULL) return writeInt32(-1);

    status_t err = writeInt32(len);
    if (err == NO_ERROR) {
        len *= sizeof(char16_t);
        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
        if (data) {
            memcpy(data, str, len);
            *reinterpret_cast<char16_t*>(data+len) = 0;
            return NO_ERROR;
        }
        err = mError;
    }
    return err;
}
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

template <typename T>
status_t Parcel::writeObject(const T& val)
{
    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
    if (enoughData && enoughObjects) {
restart_write:
        *reinterpret_cast<T*>(mData+mDataPos) = val;

        const binder_object_header* hdr = reinterpret_cast<binder_object_header*>(mData+mDataPos);
        switch (hdr->type) {
            case BINDER_TYPE_BINDER:
            case BINDER_TYPE_WEAK_BINDER:
            case BINDER_TYPE_HANDLE:
            case BINDER_TYPE_WEAK_HANDLE: {
                const flat_binder_object *fbo = reinterpret_cast<const flat_binder_object*>(hdr);
                if (fbo->binder != 0) {
                    mObjects[mObjectsSize++] = mDataPos;
                    acquire_binder_object(ProcessState::self(), *fbo, this);
                }
                break;
            }
            case BINDER_TYPE_FD: {
                // remember if it's a file descriptor
                if (!mAllowFds) {
                    // fail before modifying our object index
                    return FDS_NOT_ALLOWED;
                }
                mHasFds = mFdsKnown = true;
                mObjects[mObjectsSize++] = mDataPos;
                break;
            }
            case BINDER_TYPE_FDA:
                mObjects[mObjectsSize++] = mDataPos;
                break;
            case BINDER_TYPE_PTR: {
                const binder_buffer_object *buffer_obj = reinterpret_cast<
                    const binder_buffer_object*>(hdr);
                if ((void *)buffer_obj->buffer != nullptr) {
                    mObjects[mObjectsSize++] = mDataPos;
                }
                break;
            }
            default: {
                ALOGE("writeObject: unknown type %d", hdr->type);
                break;
            }
        }
        return finishWrite(sizeof(val));
    }

    if (!enoughData) {
        const status_t err = growData(sizeof(val));
        if (err != NO_ERROR) return err;
    }
    if (!enoughObjects) {
        size_t newSize = ((mObjectsSize+2)*3)/2;
        if (newSize * sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY;   // overflow
        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
        if (objects == NULL) return NO_MEMORY;
        mObjects = objects;
        mObjectsCapacity = newSize;
    }

    goto restart_write;
}

template status_t Parcel::writeObject<flat_binder_object>(const flat_binder_object& val);
template status_t Parcel::writeObject<binder_fd_object>(const binder_fd_object& val);
template status_t Parcel::writeObject<binder_buffer_object>(const binder_buffer_object& val);
template status_t Parcel::writeObject<binder_fd_array_object>(const binder_fd_array_object& val);


// TODO merge duplicated code in writeEmbeddedBuffer, writeEmbeddedReference, and writeEmbeddedNullReference
// TODO merge duplicated code in writeBuffer, writeReference, and writeNullReference

bool Parcel::validateBufferChild(size_t child_buffer_handle,
                                 size_t child_offset) const {
    if (child_buffer_handle >= mObjectsSize)
        return false;
    binder_buffer_object *child = reinterpret_cast<binder_buffer_object*>
            (mData + mObjects[child_buffer_handle]);
    if (!isBuffer(*child) || child_offset > child->length) {
        // Parent object not a buffer, or not large enough
        LOG_BUFFER("writeEmbeddedReference found wierd child. "
                   "child_offset = %zu, child->length = %zu",
                   child_offset, (size_t)child->length);
        return false;
    }
    return true;
}

bool Parcel::validateBufferParent(size_t parent_buffer_handle,
                                  size_t parent_offset) const {
    if (parent_buffer_handle >= mObjectsSize)
        return false;
    binder_buffer_object *parent = reinterpret_cast<binder_buffer_object*>
            (mData + mObjects[parent_buffer_handle]);
    if (!isBuffer(*parent) ||
            sizeof(binder_uintptr_t) > parent->length ||
            parent_offset > parent->length - sizeof(binder_uintptr_t)) {
        // Parent object not a buffer, or not large enough
        return false;
    }
    return true;
}
status_t Parcel::writeEmbeddedBuffer(
        const void *buffer, size_t length, size_t *handle,
        size_t parent_buffer_handle, size_t parent_offset) {
    LOG_BUFFER("writeEmbeddedBuffer(%p, %zu, parent = (%zu, %zu)) -> %zu",
        buffer, length, parent_buffer_handle,
         parent_offset, mObjectsSize);
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.buffer = reinterpret_cast<binder_uintptr_t>(buffer);
    obj.length = length;
    obj.flags = BINDER_BUFFER_FLAG_HAS_PARENT;
    if(!validateBufferParent(parent_buffer_handle, parent_offset))
        return BAD_VALUE;
    obj.parent = parent_buffer_handle;
    obj.parent_offset = parent_offset;
    if (handle != nullptr) {
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    }
    return writeObject(obj);
}

status_t Parcel::writeBuffer(const void *buffer, size_t length, size_t *handle)
{
    LOG_BUFFER("writeBuffer(%p, %zu) -> %zu",
        buffer, length, mObjectsSize);
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.buffer = reinterpret_cast<binder_uintptr_t>(buffer);
    obj.length = length;
    obj.flags = 0;
    if (handle != nullptr) {
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    }
    return writeObject(obj);
}

status_t Parcel::incrementNumReferences() {
    ++mNumRef;
    LOG_BUFFER("incrementNumReferences: %zu", mNumRef);
    return mNumRef <= PARCEL_REF_CAP ? OK : NO_MEMORY;
}

status_t Parcel::writeReference(size_t *handle,
        size_t child_buffer_handle, size_t child_offset) {
    LOG_BUFFER("writeReference(child = (%zu, %zu)) -> %zu",
        child_buffer_handle, child_offset,
        mObjectsSize);
    status_t status = incrementNumReferences();
    if (status != OK)
        return status;
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.flags = BINDER_BUFFER_FLAG_REF;
    if (!validateBufferChild(child_buffer_handle, child_offset))
        return BAD_VALUE;
    // The current binder.h does not have child and child_offset names yet.
    // Use the buffer and length parameters.
    obj.buffer = child_buffer_handle;
    obj.length = child_offset;
    if (handle != nullptr)
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    return writeObject(obj);
}

/* Write an object that describes a pointer from parent to child.
 * Output the handle of that object in the size_t *handle variable. */
status_t Parcel::writeEmbeddedReference(size_t *handle,
    size_t child_buffer_handle, size_t child_offset,
    size_t parent_buffer_handle, size_t parent_offset) {
    LOG_BUFFER("writeEmbeddedReference(child = (%zu, %zu), parent = (%zu, %zu)) -> %zu",
        child_buffer_handle, child_offset,
        parent_buffer_handle, parent_offset,
        mObjectsSize);
    status_t status = incrementNumReferences();
    if (status != OK)
        return status;
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.flags = BINDER_BUFFER_FLAG_REF | BINDER_BUFFER_FLAG_HAS_PARENT;
    if (!validateBufferChild(child_buffer_handle, child_offset))
        return BAD_VALUE;
    // The current binder.h does not have child and child_offset names yet.
    // Use the buffer and length parameters.
    obj.buffer = child_buffer_handle;
    obj.length = child_offset;
    if(!validateBufferParent(parent_buffer_handle, parent_offset))
        return BAD_VALUE;
    obj.parent = parent_buffer_handle;
    obj.parent_offset = parent_offset;
    if (handle != nullptr) {
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    }
    return writeObject(obj);
}

status_t Parcel::writeNullReference(size_t * handle) {
    LOG_BUFFER("writeNullReference -> %zu", mObjectsSize);
    status_t status = incrementNumReferences();
    if (status != OK)
        return status;
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.flags = BINDER_BUFFER_FLAG_REF;
    if (handle != nullptr)
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    return writeObject(obj);
}

status_t Parcel::writeEmbeddedNullReference(size_t * handle,
        size_t parent_buffer_handle, size_t parent_offset) {
    LOG_BUFFER("writeEmbeddedNullReference(parent = (%zu, %zu)) -> %zu",
        parent_buffer_handle,
        parent_offset,
        mObjectsSize);
    status_t status = incrementNumReferences();
    if (status != OK)
        return status;
    binder_buffer_object obj;
    obj.hdr.type = BINDER_TYPE_PTR;
    obj.flags = BINDER_BUFFER_FLAG_REF | BINDER_BUFFER_FLAG_HAS_PARENT;
    // parent_buffer_handle and parent_offset needs to be checked.
    if(!validateBufferParent(parent_buffer_handle, parent_offset))
        return BAD_VALUE;
    obj.parent = parent_buffer_handle;
    obj.parent_offset = parent_offset;
    if (handle != nullptr) {
        // We use an index into mObjects as a handle
        *handle = mObjectsSize;
    }
    return writeObject(obj);
}

void Parcel::clearCache() const {
    LOG_BUFFER("clearing cache.");
    mBufCachePos = 0;
    mBufCache.clear();
}

void Parcel::updateCache() const {
    if(mBufCachePos == mObjectsSize)
        return;
    LOG_BUFFER("updating cache from %zu to %zu", mBufCachePos, mObjectsSize);
    for(size_t i = mBufCachePos; i < mObjectsSize; i++) {
        binder_size_t dataPos = mObjects[i];
        binder_buffer_object *obj =
            reinterpret_cast<binder_buffer_object*>(mData+dataPos);
        if(!isBuffer(*obj))
            continue;
        BufferInfo ifo;
        ifo.index = i;
        ifo.buffer = obj->buffer;
        ifo.bufend = obj->buffer + obj->length;
        mBufCache.push_back(ifo);
    }
    mBufCachePos = mObjectsSize;
}

/* O(n) (n=#buffers) to find a buffer that contains the given addr */
status_t Parcel::findBuffer(const void *ptr, size_t length, bool *found,
                        size_t *handle, size_t *offset) const {
    if(found == nullptr)
        return UNKNOWN_ERROR;
    updateCache();
    binder_uintptr_t ptrVal = reinterpret_cast<binder_uintptr_t>(ptr);
    // true if the pointer is in some buffer, but the length is too big
    // so that ptr + length doesn't fit into the buffer.
    bool suspectRejectBadPointer = false;
    LOG_BUFFER("findBuffer examining %zu objects.", mObjectsSize);
    for(auto entry = mBufCache.rbegin(); entry != mBufCache.rend(); ++entry ) {
        if(entry->buffer <= ptrVal && ptrVal < entry->bufend) {
            // might have found it.
            if(ptrVal + length <= entry->bufend) {
                *found = true;
                if(handle != nullptr) *handle = entry->index;
                if(offset != nullptr) *offset = ptrVal - entry->buffer;
                LOG_BUFFER("    findBuffer has a match at %zu!", entry->index);
                return OK;
            } else {
                suspectRejectBadPointer = true;
            }
        }
    }
    LOG_BUFFER("findBuffer did not find for ptr = %p.", ptr);
    *found = false;
    return suspectRejectBadPointer ? BAD_VALUE : OK;
}

/* findBuffer with the assumption that ptr = .buffer (so it points to top
 * of the buffer, aka offset 0).
 *  */
status_t Parcel::quickFindBuffer(const void *ptr, size_t *handle) const {
    updateCache();
    binder_uintptr_t ptrVal = reinterpret_cast<binder_uintptr_t>(ptr);
    LOG_BUFFER("quickFindBuffer examining %zu objects.", mObjectsSize);
    for(auto entry = mBufCache.rbegin(); entry != mBufCache.rend(); ++entry ) {
        if(entry->buffer == ptrVal) {
            if(handle != nullptr) *handle = entry->index;
            return OK;
        }
    }
    LOG_BUFFER("quickFindBuffer did not find for ptr = %p.", ptr);
    return NO_INIT;
}

status_t Parcel::writeNativeHandleNoDup(const native_handle_t *handle,
                                        bool embedded,
                                        size_t parent_buffer_handle,
                                        size_t parent_offset)
{
    struct binder_fd_array_object fd_array;
    size_t buffer_handle;
    status_t status = OK;

    if (handle == nullptr) {
        status = writeUint64(0);
        return status;
    }

    size_t native_handle_size = sizeof(native_handle_t)
                + handle->numFds * sizeof(int) + handle->numInts * sizeof(int);
    writeUint64(native_handle_size);

    if (embedded) {
        status = writeEmbeddedBuffer((void*) handle,
                native_handle_size, &buffer_handle,
                parent_buffer_handle, parent_offset);
    } else {
        status = writeBuffer((void*) handle, native_handle_size, &buffer_handle);
    }

    if (status != OK) {
        return status;
    }

    fd_array.hdr.type = BINDER_TYPE_FDA;
    fd_array.num_fds = handle->numFds;
    fd_array.parent = buffer_handle;
    fd_array.parent_offset = offsetof(native_handle_t, data);

    return writeObject(fd_array);
}

status_t Parcel::writeNativeHandleNoDup(const native_handle_t *handle)
{
    return writeNativeHandleNoDup(handle, false /* embedded */);
}

status_t Parcel::writeEmbeddedNativeHandle(const native_handle_t *handle,
                                           size_t parent_buffer_handle,
                                           size_t parent_offset)
{
    return writeNativeHandleNoDup(handle, true /* embedded */,
                                  parent_buffer_handle, parent_offset);
}

void Parcel::remove(size_t /*start*/, size_t /*amt*/)
{
    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
}

status_t Parcel::read(void* outData, size_t len) const
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
            && len <= pad_size(len)) {
        memcpy(outData, mData+mDataPos, len);
        mDataPos += pad_size(len);
        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
        return NO_ERROR;
    }
    return NOT_ENOUGH_DATA;
}

const void* Parcel::readInplace(size_t len) const
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return NULL;
    }

    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
            && len <= pad_size(len)) {
        const void* data = mData+mDataPos;
        mDataPos += pad_size(len);
        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
        return data;
    }
    return NULL;
}

template<class T>
status_t Parcel::readAligned(T *pArg) const {
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));

    if ((mDataPos+sizeof(T)) <= mDataSize) {
        const void* data = mData+mDataPos;
        mDataPos += sizeof(T);
        *pArg =  *reinterpret_cast<const T*>(data);
        return NO_ERROR;
    } else {
        return NOT_ENOUGH_DATA;
    }
}

template<class T>
T Parcel::readAligned() const {
    T result;
    if (readAligned(&result) != NO_ERROR) {
        result = 0;
    }

    return result;
}

template<class T>
status_t Parcel::writeAligned(T val) {
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));

    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
        *reinterpret_cast<T*>(mData+mDataPos) = val;
        return finishWrite(sizeof(val));
    }

    status_t err = growData(sizeof(val));
    if (err == NO_ERROR) goto restart_write;
    return err;
}

status_t Parcel::readInt8(int8_t *pArg) const
{
    return read(pArg, sizeof(*pArg));
}

status_t Parcel::readUint8(uint8_t *pArg) const
{
    return read(pArg, sizeof(*pArg));
}

status_t Parcel::readInt16(int16_t *pArg) const
{
    return read(pArg, sizeof(*pArg));
}

status_t Parcel::readUint16(uint16_t *pArg) const
{
    return read(pArg, sizeof(*pArg));
}

status_t Parcel::readInt32(int32_t *pArg) const
{
    return readAligned(pArg);
}

int32_t Parcel::readInt32() const
{
    return readAligned<int32_t>();
}

status_t Parcel::readUint32(uint32_t *pArg) const
{
    return readAligned(pArg);
}

uint32_t Parcel::readUint32() const
{
    return readAligned<uint32_t>();
}

status_t Parcel::readInt64(int64_t *pArg) const
{
    return readAligned(pArg);
}

int64_t Parcel::readInt64() const
{
    return readAligned<int64_t>();
}

status_t Parcel::readUint64(uint64_t *pArg) const
{
    return readAligned(pArg);
}

uint64_t Parcel::readUint64() const
{
    return readAligned<uint64_t>();
}

status_t Parcel::readPointer(uintptr_t *pArg) const
{
    status_t ret;
    binder_uintptr_t ptr;
    ret = readAligned(&ptr);
    if (!ret)
        *pArg = ptr;
    return ret;
}

uintptr_t Parcel::readPointer() const
{
    return readAligned<binder_uintptr_t>();
}


status_t Parcel::readFloat(float *pArg) const
{
    return readAligned(pArg);
}


float Parcel::readFloat() const
{
    return readAligned<float>();
}

#if defined(__mips__) && defined(__mips_hard_float)

status_t Parcel::readDouble(double *pArg) const
{
    union {
      double d;
      unsigned long long ll;
    } u;
    u.d = 0;
    status_t status;
    status = readAligned(&u.ll);
    *pArg = u.d;
    return status;
}

double Parcel::readDouble() const
{
    union {
      double d;
      unsigned long long ll;
    } u;
    u.ll = readAligned<unsigned long long>();
    return u.d;
}

#else

status_t Parcel::readDouble(double *pArg) const
{
    return readAligned(pArg);
}

double Parcel::readDouble() const
{
    return readAligned<double>();
}

#endif

status_t Parcel::readBool(bool *pArg) const
{
    int8_t tmp;
    status_t ret = readInt8(&tmp);
    *pArg = (tmp != 0);
    return ret;
}

bool Parcel::readBool() const
{
    int8_t tmp;
    status_t err = readInt8(&tmp);

    if (err != OK) {
        return 0;
    }

    return tmp != 0;
}

const char* Parcel::readCString() const
{
    const size_t avail = mDataSize-mDataPos;
    if (avail > 0) {
        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
        // is the string's trailing NUL within the parcel's valid bounds?
        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
        if (eos) {
            const size_t len = eos - str;
            mDataPos += pad_size(len+1);
            ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
            return str;
        }
    }
    return NULL;
}
String16 Parcel::readString16() const
{
    size_t len;
    const char16_t* str = readString16Inplace(&len);
    if (str) return String16(str, len);
    ALOGE("Reading a NULL string not supported here.");
    return String16();
}

status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
{
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    pArg->reset();

    if (status != OK || size < 0) {
        return status;
    }

    setDataPosition(start);
    pArg->reset(new (std::nothrow) String16());

    status = readString16(pArg->get());

    if (status != OK) {
        pArg->reset();
    }

    return status;
}

status_t Parcel::readString16(String16* pArg) const
{
    size_t len;
    const char16_t* str = readString16Inplace(&len);
    if (str) {
        pArg->setTo(str, len);
        return 0;
    } else {
        *pArg = String16();
        return UNEXPECTED_NULL;
    }
}

const char16_t* Parcel::readString16Inplace(size_t* outLen) const
{
    int32_t size = readInt32();
    // watch for potential int overflow from size+1
    if (size >= 0 && size < INT32_MAX) {
        *outLen = size;
        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
        if (str != NULL) {
            return str;
        }
    }
    *outLen = 0;
    return NULL;
}
status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
    status_t status = readNullableStrongBinder(val);
    if (status == OK && !val->get()) {
        status = UNEXPECTED_NULL;
    }
    return status;
}

status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}

sp<IBinder> Parcel::readStrongBinder() const
{
    sp<IBinder> val;
    // Note that a lot of code in Android reads binders by hand with this
    // method, and that code has historically been ok with getting nullptr
    // back (while ignoring error codes).
    readNullableStrongBinder(&val);
    return val;
}

wp<IBinder> Parcel::readWeakBinder() const
{
    wp<IBinder> val;
    unflatten_binder(ProcessState::self(), *this, &val);
    return val;
}

template<typename T>
const T* Parcel::readObject(size_t *objects_offset) const
{
    const size_t DPOS = mDataPos;
    if (objects_offset != nullptr) {
        *objects_offset = 0;
    }

    if ((DPOS+sizeof(T)) <= mDataSize) {
        const T* obj = reinterpret_cast<const T*>(mData+DPOS);
        mDataPos = DPOS + sizeof(T);
        const binder_object_header *hdr = reinterpret_cast<const binder_object_header*>(obj);
        switch (hdr->type) {
            case BINDER_TYPE_BINDER:
            case BINDER_TYPE_WEAK_BINDER:
            case BINDER_TYPE_HANDLE:
            case BINDER_TYPE_WEAK_HANDLE: {
                const flat_binder_object *flat_obj =
                    reinterpret_cast<const flat_binder_object*>(hdr);
                if (flat_obj->cookie == 0 && flat_obj->binder == 0) {
                    // When transferring a NULL binder object, we don't write it into
                    // the object list, so we don't want to check for it when
                    // reading.
                    ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                    return obj;
                }
                break;
            }
            case BINDER_TYPE_FD:
            case BINDER_TYPE_FDA:
                // fd (-arrays) must always appear in the meta-data list (eg touched by the kernel)
                break;
            case BINDER_TYPE_PTR: {
                const binder_buffer_object *buffer_obj =
                    reinterpret_cast<const binder_buffer_object*>(hdr);
                if ((void *)buffer_obj->buffer == nullptr) {
                    // null pointers can be returned directly - they're not written in the
                    // object list. All non-null buffers must appear in the objects list.
                    return obj;
                }
                break;
            }
        }
        // Ensure that this object is valid...
        binder_size_t* const OBJS = mObjects;
        const size_t N = mObjectsSize;
        size_t opos = mNextObjectHint;

        if (N > 0) {
            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
                 this, DPOS, opos);

            // Start at the current hint position, looking for an object at
            // the current data position.
            if (opos < N) {
                while (opos < (N-1) && OBJS[opos] < DPOS) {
                    opos++;
                }
            } else {
                opos = N-1;
            }
            if (OBJS[opos] == DPOS) {
                // Found it!
                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
                     this, DPOS, opos);
                mNextObjectHint = opos+1;
                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                if (objects_offset != nullptr) {
                    *objects_offset = opos;
                }
                return obj;
            }

            // Look backwards for it...
            while (opos > 0 && OBJS[opos] > DPOS) {
                opos--;
            }
            if (OBJS[opos] == DPOS) {
                // Found it!
                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
                     this, DPOS, opos);
                mNextObjectHint = opos+1;
                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                if (objects_offset != nullptr) {
                    *objects_offset = opos;
                }
                return obj;
            }
        }
        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
             this, DPOS);
    }
    return NULL;
}

template const flat_binder_object* Parcel::readObject<flat_binder_object>(size_t *objects_offset) const;

template const binder_fd_object* Parcel::readObject<binder_fd_object>(size_t *objects_offset) const;

template const binder_buffer_object* Parcel::readObject<binder_buffer_object>(size_t *objects_offset) const;

template const binder_fd_array_object* Parcel::readObject<binder_fd_array_object>(size_t *objects_offset) const;

bool Parcel::verifyBufferObject(const binder_buffer_object *buffer_obj,
                                size_t size, uint32_t flags, size_t parent,
                                size_t parentOffset) const {
    if (buffer_obj->length != size) {
        ALOGE("Buffer length %" PRIu64 " does not match expected size %zu.",
              static_cast<uint64_t>(buffer_obj->length), size);
        return false;
    }

    if (buffer_obj->flags != flags) {
        ALOGE("Buffer flags 0x%02X do not match expected flags 0x%02X.", buffer_obj->flags, flags);
        return false;
    }

    if (flags & BINDER_BUFFER_FLAG_HAS_PARENT) {
        if (buffer_obj->parent != parent) {
            ALOGE("Buffer parent %" PRIu64 " does not match expected parent %zu.",
                  static_cast<uint64_t>(buffer_obj->parent), parent);
            return false;
        }
        if (buffer_obj->parent_offset != parentOffset) {
              ALOGE("Buffer parent offset %" PRIu64 " does not match expected offset %zu.",
                  static_cast<uint64_t>(buffer_obj->parent_offset), parentOffset);
            return false;
        }
    }

    return true;
}

status_t Parcel::readBuffer(size_t buffer_size, size_t *buffer_handle,
                            uint32_t flags, size_t parent, size_t parentOffset,
                            const void **buffer_out) const {

    const binder_buffer_object* buffer_obj = readObject<binder_buffer_object>(buffer_handle);

    if (buffer_obj == nullptr || !isBuffer(*buffer_obj)) {
        return BAD_VALUE;
    }

    if (!verifyBufferObject(buffer_obj, buffer_size, flags, parent, parentOffset)) {
        return BAD_VALUE;
    }

    // in read side, always use .buffer and .length.
    *buffer_out = reinterpret_cast<void*>(buffer_obj->buffer);

    return OK;
}

status_t Parcel::readNullableBuffer(size_t buffer_size, size_t *buffer_handle,
                                    const void **buffer_out) const
{
    return readBuffer(buffer_size, buffer_handle,
                      0 /* flags */, 0 /* parent */, 0 /* parentOffset */,
                      buffer_out);
}

status_t Parcel::readBuffer(size_t buffer_size, size_t *buffer_handle,
                            const void **buffer_out) const
{
    status_t status = readNullableBuffer(buffer_size, buffer_handle, buffer_out);
    if (status == OK && *buffer_out == nullptr) {
        return UNEXPECTED_NULL;
    }
    return status;
}


status_t Parcel::readEmbeddedBuffer(size_t buffer_size,
                                    size_t *buffer_handle,
                                    size_t parent_buffer_handle,
                                    size_t parent_offset,
                                    const void **buffer_out) const
{
    status_t status = readNullableEmbeddedBuffer(buffer_size, buffer_handle,
                                                 parent_buffer_handle,
                                                 parent_offset, buffer_out);
    if (status == OK && *buffer_out == nullptr) {
        return UNEXPECTED_NULL;
    }
    return status;
}

status_t Parcel::readNullableEmbeddedBuffer(size_t buffer_size,
                                            size_t *buffer_handle,
                                            size_t parent_buffer_handle,
                                            size_t parent_offset,
                                            const void **buffer_out) const
{
    return readBuffer(buffer_size, buffer_handle, BINDER_BUFFER_FLAG_HAS_PARENT,
                      parent_buffer_handle, parent_offset, buffer_out);
}

// isRef if corresponds to a writeReference call, else corresponds to a writeBuffer call.
// see ::android::hardware::writeReferenceToParcel for details.
status_t Parcel::readReference(void const* *bufptr,
                               size_t *buffer_handle, bool *isRef) const
{
    LOG_BUFFER("readReference");
    const binder_buffer_object* buffer_obj = readObject<binder_buffer_object>();
    LOG_BUFFER("    readReference: buf = %p, len = %zu, flags = %x",
        (void*)buffer_obj->buffer, (size_t)buffer_obj->length,
        (int)buffer_obj->flags);
    // TODO need verification here
    if (buffer_obj && buffer_obj->hdr.type == BINDER_TYPE_PTR) {
        if (buffer_handle != nullptr) {
            *buffer_handle = 0; // TODO fix this, as readBuffer would do
        }
        if(isRef != nullptr) {
            *isRef = (buffer_obj->flags & BINDER_BUFFER_FLAG_REF) != 0;
            LOG_BUFFER("    readReference: isRef = %d", *isRef);
        }
        // in read side, always use .buffer and .length.
        if(bufptr != nullptr) {
            *bufptr = (void*)buffer_obj->buffer;
        }
        return OK;
    }

    return BAD_VALUE;
}

// isRef if corresponds to a writeEmbeddedReference call, else corresponds to a writeEmbeddedBuffer call.
// see ::android::hardware::writeEmbeddedReferenceToParcel for details.
status_t Parcel::readEmbeddedReference(void const* *bufptr,
                                       size_t *buffer_handle,
                                       size_t /* parent_buffer_handle */,
                                       size_t /* parent_offset */,
                                       bool *isRef) const
{
    // TODO verify parent and offset
    LOG_BUFFER("readEmbeddedReference");
    return (readReference(bufptr, buffer_handle, isRef));
}

status_t Parcel::readEmbeddedNativeHandle(size_t parent_buffer_handle,
                                          size_t parent_offset,
                                          const native_handle_t **handle) const
{
    status_t status = readNullableEmbeddedNativeHandle(parent_buffer_handle, parent_offset, handle);
    if (status == OK && *handle == nullptr) {
        return UNEXPECTED_NULL;
    }
    return status;
}

status_t Parcel::readNullableNativeHandleNoDup(const native_handle_t **handle,
                                               bool embedded,
                                               size_t parent_buffer_handle,
                                               size_t parent_offset) const
{
    status_t status;
    uint64_t nativeHandleSize;
    size_t fdaParent;

    status = readUint64(&nativeHandleSize);
    if (status != OK || nativeHandleSize == 0) {
        *handle = nullptr;
        return status;
    }

    if (nativeHandleSize < sizeof(native_handle_t)) {
        ALOGE("Received a native_handle_t size that was too small.");
        return BAD_VALUE;
    }

    if (embedded) {
        status = readNullableEmbeddedBuffer(nativeHandleSize, &fdaParent,
                                            parent_buffer_handle, parent_offset,
                                            reinterpret_cast<const void**>(handle));
    } else {
        status = readNullableBuffer(nativeHandleSize, &fdaParent,
                                    reinterpret_cast<const void**>(handle));
    }

    if (status != OK) {
        return status;
    }

    int numFds = (*handle)->numFds;
    int numInts = (*handle)->numInts;

    if (numFds < 0 || numFds > NATIVE_HANDLE_MAX_FDS) {
        ALOGE("Received native_handle with invalid number of fds.");
        return BAD_VALUE;
    }

    if (numInts < 0 || numInts > NATIVE_HANDLE_MAX_INTS) {
        ALOGE("Received native_handle with invalid number of ints.");
        return BAD_VALUE;
    }

    if (nativeHandleSize != (sizeof(native_handle_t) + ((numFds + numInts) * sizeof(int)))) {
        ALOGE("Size of native_handle doesn't match.");
        return BAD_VALUE;
    }

    const binder_fd_array_object* fd_array_obj = readObject<binder_fd_array_object>();

    if (fd_array_obj == nullptr || fd_array_obj->hdr.type != BINDER_TYPE_FDA) {
        ALOGE("Can't find file-descriptor array object.");
        return BAD_VALUE;
    }

    if (static_cast<int>(fd_array_obj->num_fds) != numFds) {
        ALOGE("Number of native handles does not match.");
        return BAD_VALUE;
    }

    if (fd_array_obj->parent != fdaParent) {
        ALOGE("Parent handle of file-descriptor array not correct.");
        return BAD_VALUE;
    }

    if (fd_array_obj->parent_offset != offsetof(native_handle_t, data)) {
        ALOGE("FD array object not properly offset in parent.");
        return BAD_VALUE;
    }

    return OK;
}

status_t Parcel::readNullableEmbeddedNativeHandle(size_t parent_buffer_handle,
                                                  size_t parent_offset,
                                                  const native_handle_t **handle) const
{
    return readNullableNativeHandleNoDup(handle, true /* embedded */, parent_buffer_handle,
                                         parent_offset);
}

status_t Parcel::readNativeHandleNoDup(const native_handle_t **handle) const
{
    status_t status = readNullableNativeHandleNoDup(handle);
    if (status == OK && *handle == nullptr) {
        return UNEXPECTED_NULL;
    }
    return status;
}

status_t Parcel::readNullableNativeHandleNoDup(const native_handle_t **handle) const
{
    return readNullableNativeHandleNoDup(handle, false /* embedded */);
}

void Parcel::closeFileDescriptors()
{
    size_t i = mObjectsSize;
    if (i > 0) {
        //ALOGI("Closing file descriptors for %zu objects...", i);
    }
    while (i > 0) {
        i--;
        const flat_binder_object* flat
            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
        if (flat->hdr.type == BINDER_TYPE_FD) {
            //ALOGI("Closing fd: %ld", flat->handle);
            close(flat->handle);
        }
    }
}

uintptr_t Parcel::ipcData() const
{
    return reinterpret_cast<uintptr_t>(mData);
}

size_t Parcel::ipcDataSize() const
{
    return mDataSize > mDataPos ? mDataSize : mDataPos;
}

uintptr_t Parcel::ipcObjects() const
{
    return reinterpret_cast<uintptr_t>(mObjects);
}

size_t Parcel::ipcObjectsCount() const
{
    return mObjectsSize;
}

#define BUFFER_ALIGNMENT_BYTES 8
size_t Parcel::ipcBufferSize() const
{
    size_t totalBuffersSize = 0;
    // Add size for BINDER_TYPE_PTR
    size_t i = mObjectsSize;
    while (i > 0) {
        i--;
        const binder_buffer_object* buffer
            = reinterpret_cast<binder_buffer_object*>(mData+mObjects[i]);
        if (isBuffer(*buffer)) {
            /* The binder kernel driver requires each buffer to be 8-byte
             * aligned */
            size_t alignedSize = (buffer->length + (BUFFER_ALIGNMENT_BYTES - 1))
                    & ~(BUFFER_ALIGNMENT_BYTES - 1);
            if (alignedSize > SIZE_MAX - totalBuffersSize) {
                ALOGE("ipcBuffersSize(): invalid buffer sizes.");
                return 0;
            }
            totalBuffersSize += alignedSize;
        }
    }
    return totalBuffersSize;
}

void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
{
    binder_size_t minOffset = 0;
    freeDataNoInit();
    mError = NO_ERROR;
    mData = const_cast<uint8_t*>(data);
    mDataSize = mDataCapacity = dataSize;
    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
    mDataPos = 0;
    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
    mObjects = const_cast<binder_size_t*>(objects);
    mObjectsSize = mObjectsCapacity = objectsCount;
    mNextObjectHint = 0;
    clearCache();
    mNumRef = 0;
    mOwner = relFunc;
    mOwnerCookie = relCookie;
    for (size_t i = 0; i < mObjectsSize; i++) {
        binder_size_t offset = mObjects[i];
        if (offset < minOffset) {
            ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
                  __func__, (uint64_t)offset, (uint64_t)minOffset);
            mObjectsSize = 0;
            break;
        }
        minOffset = offset + sizeof(flat_binder_object);
    }
    scanForFds();
}

void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
{
    to << "Parcel(";

    if (errorCheck() != NO_ERROR) {
        const status_t err = errorCheck();
        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
    } else if (dataSize() > 0) {
        const uint8_t* DATA = data();
        to << indent << HexDump(DATA, dataSize()) << dedent;
        const binder_size_t* OBJS = objects();
        const size_t N = objectsCount();
        for (size_t i=0; i<N; i++) {
            const flat_binder_object* flat
                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
            if (flat->hdr.type == BINDER_TYPE_PTR) {
                const binder_buffer_object* buffer
                    = reinterpret_cast<const binder_buffer_object*>(DATA+OBJS[i]);
                if(isBuffer(*buffer)) {
                    HexDump bufferDump((const uint8_t*)buffer->buffer, (size_t)buffer->length);
                    bufferDump.setSingleLineCutoff(0);
                    to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << " (buffer size " << buffer->length << "):";
                    to << indent << bufferDump << dedent;
                } else {
                    to << endl << "Object #" << i << " @ " << (void*)OBJS[i];
                }
            } else {
                to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
                    << TypeCode(flat->hdr.type & 0x7f7f7f00)
                    << " = " << flat->binder;
            }
        }
    } else {
        to << "NULL";
    }

    to << ")";
}

void Parcel::releaseObjects()
{
    const sp<ProcessState> proc(ProcessState::self());
    size_t i = mObjectsSize;
    uint8_t* const data = mData;
    binder_size_t* const objects = mObjects;
    while (i > 0) {
        i--;
        const flat_binder_object* flat
            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
        release_object(proc, *flat, this);
    }
}

void Parcel::acquireObjects()
{
    const sp<ProcessState> proc(ProcessState::self());
    size_t i = mObjectsSize;
    uint8_t* const data = mData;
    binder_size_t* const objects = mObjects;
    while (i > 0) {
        i--;
        const binder_object_header* flat
            = reinterpret_cast<binder_object_header*>(data+objects[i]);
        acquire_object(proc, *flat, this);
    }
}

void Parcel::freeData()
{
    freeDataNoInit();
    initState();
}

void Parcel::freeDataNoInit()
{
    if (mOwner) {
        LOG_ALLOC("Parcel %p: freeing other owner data", this);
        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
    } else {
        LOG_ALLOC("Parcel %p: freeing allocated data", this);
        releaseObjects();
        if (mData) {
            LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
            if (mDataCapacity <= gParcelGlobalAllocSize) {
              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
            } else {
              gParcelGlobalAllocSize = 0;
            }
            if (gParcelGlobalAllocCount > 0) {
              gParcelGlobalAllocCount--;
            }
            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
            free(mData);
        }
        if (mObjects) free(mObjects);
    }
}

status_t Parcel::growData(size_t len)
{
    if (len > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    size_t newSize = ((mDataSize+len)*3)/2;
    return (newSize <= mDataSize)
            ? (status_t) NO_MEMORY
            : continueWrite(newSize);
}

status_t Parcel::restartWrite(size_t desired)
{
    if (desired > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    if (mOwner) {
        freeData();
        return continueWrite(desired);
    }

    uint8_t* data = (uint8_t*)realloc(mData, desired);
    if (!data && desired > mDataCapacity) {
        mError = NO_MEMORY;
        return NO_MEMORY;
    }

    releaseObjects();

    if (data) {
        LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
        gParcelGlobalAllocSize += desired;
        gParcelGlobalAllocSize -= mDataCapacity;
        if (!mData) {
            gParcelGlobalAllocCount++;
        }
        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
        mData = data;
        mDataCapacity = desired;
    }

    mDataSize = mDataPos = 0;
    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);

    free(mObjects);
    mObjects = NULL;
    mObjectsSize = mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mHasFds = false;
    clearCache();
    mNumRef = 0;
    mFdsKnown = true;
    mAllowFds = true;

    return NO_ERROR;
}

status_t Parcel::continueWrite(size_t desired)
{
    if (desired > INT32_MAX) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    // If shrinking, first adjust for any objects that appear
    // after the new data size.
    size_t objectsSize = mObjectsSize;
    if (desired < mDataSize) {
        if (desired == 0) {
            objectsSize = 0;
        } else {
            while (objectsSize > 0) {
                if (mObjects[objectsSize-1] < desired)
                    break;
                objectsSize--;
            }
        }
    }

    if (mOwner) {
        // If the size is going to zero, just release the owner's data.
        if (desired == 0) {
            freeData();
            return NO_ERROR;
        }

        // If there is a different owner, we need to take
        // posession.
        uint8_t* data = (uint8_t*)malloc(desired);
        if (!data) {
            mError = NO_MEMORY;
            return NO_MEMORY;
        }
        binder_size_t* objects = NULL;

        if (objectsSize) {
            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
            if (!objects) {
                free(data);

                mError = NO_MEMORY;
                return NO_MEMORY;
            }

            // Little hack to only acquire references on objects
            // we will be keeping.
            size_t oldObjectsSize = mObjectsSize;
            mObjectsSize = objectsSize;
            acquireObjects();
            mObjectsSize = oldObjectsSize;
        }

        if (mData) {
            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
        }
        if (objects && mObjects) {
            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
        }
        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
        mOwner = NULL;

        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
        gParcelGlobalAllocSize += desired;
        gParcelGlobalAllocCount++;
        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);

        mData = data;
        mObjects = objects;
        mDataSize = (mDataSize < desired) ? mDataSize : desired;
        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
        mDataCapacity = desired;
        mObjectsSize = mObjectsCapacity = objectsSize;
        mNextObjectHint = 0;

        clearCache();
    } else if (mData) {
        if (objectsSize < mObjectsSize) {
            // Need to release refs on any objects we are dropping.
            const sp<ProcessState> proc(ProcessState::self());
            for (size_t i=objectsSize; i<mObjectsSize; i++) {
                const flat_binder_object* flat
                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
                if (flat->hdr.type == BINDER_TYPE_FD) {
                    // will need to rescan because we may have lopped off the only FDs
                    mFdsKnown = false;
                }
                release_object(proc, *flat, this);
            }
            binder_size_t* objects =
                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
            if (objects) {
                mObjects = objects;
            }
            mObjectsSize = objectsSize;
            mNextObjectHint = 0;

            clearCache();
        }

        // We own the data, so we can just do a realloc().
        if (desired > mDataCapacity) {
            uint8_t* data = (uint8_t*)realloc(mData, desired);
            if (data) {
                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
                        desired);
                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                gParcelGlobalAllocSize += desired;
                gParcelGlobalAllocSize -= mDataCapacity;
                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
                mData = data;
                mDataCapacity = desired;
            } else {
                mError = NO_MEMORY;
                return NO_MEMORY;
            }
        } else {
            if (mDataSize > desired) {
                mDataSize = desired;
                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
            }
            if (mDataPos > desired) {
                mDataPos = desired;
                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
            }
        }

    } else {
        // This is the first data.  Easy!
        uint8_t* data = (uint8_t*)malloc(desired);
        if (!data) {
            mError = NO_MEMORY;
            return NO_MEMORY;
        }

        if(!(mDataCapacity == 0 && mObjects == NULL
             && mObjectsCapacity == 0)) {
            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
        }

        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
        gParcelGlobalAllocSize += desired;
        gParcelGlobalAllocCount++;
        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);

        mData = data;
        mDataSize = mDataPos = 0;
        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
        mDataCapacity = desired;
    }

    return NO_ERROR;
}

void Parcel::initState()
{
    LOG_ALLOC("Parcel %p: initState", this);
    mError = NO_ERROR;
    mData = 0;
    mDataSize = 0;
    mDataCapacity = 0;
    mDataPos = 0;
    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
    mObjects = NULL;
    mObjectsSize = 0;
    mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mHasFds = false;
    mFdsKnown = true;
    mAllowFds = true;
    mOwner = NULL;
    clearCache();
    mNumRef = 0;

    // racing multiple init leads only to multiple identical write
    if (gMaxFds == 0) {
        struct rlimit result;
        if (!getrlimit(RLIMIT_NOFILE, &result)) {
            gMaxFds = (size_t)result.rlim_cur;
            //ALOGI("parcel fd limit set to %zu", gMaxFds);
        } else {
            ALOGW("Unable to getrlimit: %s", strerror(errno));
            gMaxFds = 1024;
        }
    }
}

void Parcel::scanForFds() const
{
    bool hasFds = false;
    for (size_t i=0; i<mObjectsSize; i++) {
        const flat_binder_object* flat
            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
        if (flat->hdr.type == BINDER_TYPE_FD) {
            hasFds = true;
            break;
        }
    }
    mHasFds = hasFds;
    mFdsKnown = true;
}

}; // namespace hardware
}; // namespace android
