/*
 * 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 "Parcel"
//#define LOG_NDEBUG 0

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/sched.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 <binder/Binder.h>
#include <binder/BpBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/Stability.h>
#include <binder/Status.h>
#include <binder/TextOutput.h>

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

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

#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__)

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

// 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 > (std::numeric_limits<size_t>::max() - 3)) {
        LOG_ALWAYS_FATAL("pad size too big %zu", s);
    }
    return PAD_SIZE_UNSAFE(s);
}

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

namespace android {

// many things compile this into prebuilts on the stack
static_assert(sizeof(Parcel) == 60 || sizeof(Parcel) == 120);

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

static size_t gMaxFds = 0;

// Maximum size of a blob to transfer in-place.
static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;

enum {
    BLOB_INPLACE = 0,
    BLOB_ASHMEM_IMMUTABLE = 1,
    BLOB_ASHMEM_MUTABLE = 2,
};

static void acquire_object(const sp<ProcessState>& proc,
    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{
    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_HANDLE: {
            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
            if (b != nullptr) {
                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
                b->incStrong(who);
            }
            return;
        }
        case BINDER_TYPE_FD: {
            if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
                // If we own an ashmem fd, keep track of how much memory it refers to.
                int size = ashmem_get_size_region(obj.handle);
                if (size > 0) {
                    *outAshmemSize += size;
                }
            }
            return;
        }
    }

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

static void release_object(const sp<ProcessState>& proc,
    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{
    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_HANDLE: {
            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
            if (b != nullptr) {
                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
                b->decStrong(who);
            }
            return;
        }
        case BINDER_TYPE_FD: {
            if (obj.cookie != 0) { // owned
                if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
                    int size = ashmem_get_size_region(obj.handle);
                    if (size > 0) {
                        // ashmem size might have changed since last time it was accounted for, e.g.
                        // in acquire_object(). Value of *outAshmemSize is not critical since we are
                        // releasing the object anyway. Check for integer overflow condition.
                        *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
                    }
                }

                close(obj.handle);
            }
            return;
        }
    }

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

status_t Parcel::finishFlattenBinder(
    const sp<IBinder>& binder, const flat_binder_object& flat)
{
    status_t status = writeObject(flat, false);
    if (status != OK) return status;

    internal::Stability::tryMarkCompilationUnit(binder.get());
    return writeInt32(internal::Stability::get(binder.get()));
}

status_t Parcel::finishUnflattenBinder(
    const sp<IBinder>& binder, sp<IBinder>* out) const
{
    int32_t stability;
    status_t status = readInt32(&stability);
    if (status != OK) return status;

    status = internal::Stability::set(binder.get(), stability, true /*log*/);
    if (status != OK) return status;

    *out = binder;
    return OK;
}

static constexpr inline int schedPolicyMask(int policy, int priority) {
    return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
}

status_t Parcel::flattenBinder(const sp<IBinder>& binder)
{
    flat_binder_object obj;
    obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;

    int schedBits = 0;
    if (!IPCThreadState::self()->backgroundSchedulingDisabled()) {
        schedBits = schedPolicyMask(SCHED_NORMAL, 19);
    }

    if (binder != nullptr) {
        BBinder *local = binder->localBinder();
        if (!local) {
            BpBinder *proxy = binder->remoteBinder();
            if (proxy == nullptr) {
                ALOGE("null proxy");
            }
            const int32_t handle = proxy ? proxy->handle() : 0;
            obj.hdr.type = BINDER_TYPE_HANDLE;
            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
            obj.handle = handle;
            obj.cookie = 0;
        } else {
            int policy = local->getMinSchedulerPolicy();
            int priority = local->getMinSchedulerPriority();

            if (policy != 0 || priority != 0) {
                // override value, since it is set explicitly
                schedBits = schedPolicyMask(policy, priority);
            }
            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;
    }

    obj.flags |= schedBits;

    return finishFlattenBinder(binder, obj);
}

status_t Parcel::unflattenBinder(sp<IBinder>* out) const
{
    const flat_binder_object* flat = readObject(false);

    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER: {
                sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
                return finishUnflattenBinder(binder, out);
            }
            case BINDER_TYPE_HANDLE: {
                sp<IBinder> binder =
                    ProcessState::self()->getStrongProxyForHandle(flat->handle);
                return finishUnflattenBinder(binder, out);
            }
        }
    }
    return BAD_TYPE;
}

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

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) {
        LOG_ALWAYS_FATAL("result too big: %zu", result);
    }
    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.
        LOG_ALWAYS_FATAL("pos too big: %zu", pos);
    }

    mDataPos = pos;
    mNextObjectHint = 0;
    mObjectsSorted = false;
}

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;
}

status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
{
    status_t err;
    const uint8_t *data = parcel->mData;
    const binder_size_t *objects = parcel->mObjects;
    size_t size = parcel->mObjectsSize;
    int startPos = mDataPos;
    int firstIndex = -1, lastIndex = -2;

    if (len == 0) {
        return NO_ERROR;
    }

    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;
    }

    // range checks against the source parcel size
    if ((offset > parcel->mDataSize)
            || (len > parcel->mDataSize)
            || (offset + len > parcel->mDataSize)) {
        return BAD_VALUE;
    }

    // Count objects in range
    for (int i = 0; i < (int) size; i++) {
        size_t off = objects[i];
        if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
            if (firstIndex == -1) {
                firstIndex = i;
            }
            lastIndex = i;
        }
    }
    int numObjects = lastIndex - firstIndex + 1;

    if ((mDataSize+len) > mDataCapacity) {
        // grow data
        err = growData(len);
        if (err != NO_ERROR) {
            return err;
        }
    }

    // append data
    memcpy(mData + mDataPos, data + offset, len);
    mDataPos += len;
    mDataSize += len;

    err = NO_ERROR;

    if (numObjects > 0) {
        const sp<ProcessState> proc(ProcessState::self());
        // grow objects
        if (mObjectsCapacity < mObjectsSize + numObjects) {
            if ((size_t) numObjects > SIZE_MAX - mObjectsSize) return NO_MEMORY; // overflow
            if (mObjectsSize + numObjects > SIZE_MAX / 3) return NO_MEMORY; // overflow
            size_t newSize = ((mObjectsSize + numObjects)*3)/2;
            if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
            binder_size_t *objects =
                (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
            if (objects == (binder_size_t*)nullptr) {
                return NO_MEMORY;
            }
            mObjects = objects;
            mObjectsCapacity = newSize;
        }

        // append and acquire objects
        int idx = mObjectsSize;
        for (int i = firstIndex; i <= lastIndex; i++) {
            size_t off = objects[i] - offset + startPos;
            mObjects[idx++] = off;
            mObjectsSize++;

            flat_binder_object* flat
                = reinterpret_cast<flat_binder_object*>(mData + off);
            acquire_object(proc, *flat, this, &mOpenAshmemSize);

            if (flat->hdr.type == BINDER_TYPE_FD) {
                // If this is a file descriptor, we need to dup it so the
                // new Parcel now owns its own fd, and can declare that we
                // officially know we have fds.
                flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
                flat->cookie = 1;
                mHasFds = mFdsKnown = true;
                if (!mAllowFds) {
                    err = FDS_NOT_ALLOWED;
                }
            }
        }
    }

    return err;
}

int Parcel::compareData(const Parcel& other) {
    size_t size = dataSize();
    if (size != other.dataSize()) {
        return size < other.dataSize() ? -1 : 1;
    }
    return memcmp(data(), other.data(), size);
}

bool Parcel::allowFds() const
{
    return mAllowFds;
}

bool Parcel::pushAllowFds(bool allowFds)
{
    const bool origValue = mAllowFds;
    if (!allowFds) {
        mAllowFds = false;
    }
    return origValue;
}

void Parcel::restoreAllowFds(bool lastValue)
{
    mAllowFds = lastValue;
}

bool Parcel::hasFileDescriptors() const
{
    if (!mFdsKnown) {
        scanForFds();
    }
    return mHasFds;
}

void Parcel::updateWorkSourceRequestHeaderPosition() const {
    // Only update the request headers once. We only want to point
    // to the first headers read/written.
    if (!mRequestHeaderPresent) {
        mWorkSourceRequestHeaderPosition = dataPosition();
        mRequestHeaderPresent = true;
    }
}

#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
#else
constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
#endif

// Write RPC headers.  (previously just the interface token)
status_t Parcel::writeInterfaceToken(const String16& interface)
{
    const IPCThreadState* threadState = IPCThreadState::self();
    writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
    updateWorkSourceRequestHeaderPosition();
    writeInt32(threadState->shouldPropagateWorkSource() ?
            threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
    writeInt32(kHeader);
    // currently the interface identification token is just its name as a string
    return writeString16(interface);
}

bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
{
    if (!mRequestHeaderPresent) {
        return false;
    }

    const size_t initialPosition = dataPosition();
    setDataPosition(mWorkSourceRequestHeaderPosition);
    status_t err = writeInt32(uid);
    setDataPosition(initialPosition);
    return err == NO_ERROR;
}

uid_t Parcel::readCallingWorkSourceUid() const
{
    if (!mRequestHeaderPresent) {
        return IPCThreadState::kUnsetWorkSource;
    }

    const size_t initialPosition = dataPosition();
    setDataPosition(mWorkSourceRequestHeaderPosition);
    uid_t uid = readInt32();
    setDataPosition(initialPosition);
    return uid;
}

bool Parcel::checkInterface(IBinder* binder) const
{
    return enforceInterface(binder->getInterfaceDescriptor());
}

bool Parcel::enforceInterface(const String16& interface,
                              IPCThreadState* threadState) const
{
    return enforceInterface(interface.string(), interface.size(), threadState);
}

bool Parcel::enforceInterface(const char16_t* interface,
                              size_t len,
                              IPCThreadState* threadState) const
{
    // StrictModePolicy.
    int32_t strictPolicy = readInt32();
    if (threadState == nullptr) {
        threadState = IPCThreadState::self();
    }
    if ((threadState->getLastTransactionBinderFlags() &
         IBinder::FLAG_ONEWAY) != 0) {
      // For one-way calls, the callee is running entirely
      // disconnected from the caller, so disable StrictMode entirely.
      // Not only does disk/network usage not impact the caller, but
      // there's no way to commuicate back any violations anyway.
      threadState->setStrictModePolicy(0);
    } else {
      threadState->setStrictModePolicy(strictPolicy);
    }
    // WorkSource.
    updateWorkSourceRequestHeaderPosition();
    int32_t workSource = readInt32();
    threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
    // vendor header
    int32_t header = readInt32();
    if (header != kHeader) {
        ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
        return false;
    }
    // Interface descriptor.
    size_t parcel_interface_len;
    const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
    if (len == parcel_interface_len &&
            (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
        return true;
    } else {
        ALOGW("**** enforceInterface() expected '%s' but read '%s'",
              String8(interface, len).string(),
              String8(parcel_interface, parcel_interface_len).string());
        return false;
    }
}

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 nullptr;
    }

    const size_t padded = pad_size(len);

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

    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 nullptr;
}

status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
    const uint8_t* strData = (uint8_t*)str.data();
    const size_t strLen= str.length();
    const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
    if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
        return BAD_VALUE;
    }

    status_t err = writeInt32(utf16Len);
    if (err) {
        return err;
    }

    // Allocate enough bytes to hold our converted string and its terminating NULL.
    void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
    if (!dst) {
        return NO_MEMORY;
    }

    utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);

    return NO_ERROR;
}

status_t Parcel::writeUtf8AsUtf16(const std::optional<std::string>& str) {
  if (!str) {
    return writeInt32(-1);
  }
  return writeUtf8AsUtf16(*str);
}

status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
  if (!str) {
    return writeInt32(-1);
  }
  return writeUtf8AsUtf16(*str);
}

status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) {
    if (size > std::numeric_limits<int32_t>::max()) {
        return BAD_VALUE;
    }

    status_t status = writeInt32(size);
    if (status != OK) {
        return status;
    }

    return write(data, size);
}

status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
    return writeByteVectorInternal(val.data(), val.size());
}

status_t Parcel::writeByteVector(const std::optional<std::vector<int8_t>>& val)
{
    if (!val) return writeInt32(-1);
    return writeByteVectorInternal(val->data(), val->size());
}

status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
{
    if (!val) return writeInt32(-1);
    return writeByteVectorInternal(val->data(), val->size());
}

status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
    return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
}

status_t Parcel::writeByteVector(const std::optional<std::vector<uint8_t>>& val)
{
    if (!val) return writeInt32(-1);
    return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
}

status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
{
    if (!val) return writeInt32(-1);
    return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
}

status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
{
    return writeTypedVector(val, &Parcel::writeInt32);
}

status_t Parcel::writeInt32Vector(const std::optional<std::vector<int32_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeInt32);
}

status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeInt32);
}

status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
{
    return writeTypedVector(val, &Parcel::writeInt64);
}

status_t Parcel::writeInt64Vector(const std::optional<std::vector<int64_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeInt64);
}

status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeInt64);
}

status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
{
    return writeTypedVector(val, &Parcel::writeUint64);
}

status_t Parcel::writeUint64Vector(const std::optional<std::vector<uint64_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeUint64);
}

status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeUint64);
}

status_t Parcel::writeFloatVector(const std::vector<float>& val)
{
    return writeTypedVector(val, &Parcel::writeFloat);
}

status_t Parcel::writeFloatVector(const std::optional<std::vector<float>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeFloat);
}

status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeFloat);
}

status_t Parcel::writeDoubleVector(const std::vector<double>& val)
{
    return writeTypedVector(val, &Parcel::writeDouble);
}

status_t Parcel::writeDoubleVector(const std::optional<std::vector<double>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeDouble);
}

status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeDouble);
}

status_t Parcel::writeBoolVector(const std::vector<bool>& val)
{
    return writeTypedVector(val, &Parcel::writeBool);
}

status_t Parcel::writeBoolVector(const std::optional<std::vector<bool>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeBool);
}

status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeBool);
}

status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
{
    return writeTypedVector(val, &Parcel::writeChar);
}

status_t Parcel::writeCharVector(const std::optional<std::vector<char16_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeChar);
}

status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeChar);
}

status_t Parcel::writeString16Vector(const std::vector<String16>& val)
{
    return writeTypedVector(val, &Parcel::writeString16);
}

status_t Parcel::writeString16Vector(
        const std::optional<std::vector<std::optional<String16>>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeString16);
}

status_t Parcel::writeString16Vector(
        const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeString16);
}

status_t Parcel::writeUtf8VectorAsUtf16Vector(
                        const std::optional<std::vector<std::optional<std::string>>>& val) {
    return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
}

status_t Parcel::writeUtf8VectorAsUtf16Vector(
                        const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
    return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
}

status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
    return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
}

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

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

status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
    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 (!val) {
        return writeInt32(-1);
    }
    status_t ret = writeInt32(static_cast<uint32_t>(len));
    if (ret == NO_ERROR) {
        ret = write(val, len * sizeof(*val));
    }
    return ret;
}
status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
    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 (!val) {
        return writeInt32(-1);
    }
    status_t ret = writeInt32(static_cast<uint32_t>(len));
    if (ret == NO_ERROR) {
        ret = write(val, len * sizeof(*val));
    }
    return ret;
}

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

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

status_t Parcel::writeByte(int8_t val)
{
    return writeInt32(int32_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::writeString8(const String8& str)
{
    return writeString8(str.string(), str.size());
}

status_t Parcel::writeString8(const char* str, size_t len)
{
    if (str == nullptr) return writeInt32(-1);

    status_t err = writeInt32(len);
    if (err == NO_ERROR) {
        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
        if (data) {
            memcpy(data, str, len);
            *reinterpret_cast<char*>(data+len) = 0;
            return NO_ERROR;
        }
        err = mError;
    }
    return err;
}

status_t Parcel::writeString16(const std::optional<String16>& str)
{
    if (!str) {
        return writeInt32(-1);
    }

    return writeString16(*str);
}

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 == nullptr) 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 flattenBinder(val);
}

status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
{
    return writeTypedVector(val, &Parcel::writeStrongBinder);
}

status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
}

status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
{
    return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
}

status_t Parcel::readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
}

status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
}

status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
    return readTypedVector(val, &Parcel::readStrongBinder);
}

status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
    if (!parcelable) {
        return writeInt32(0);
    }

    return writeParcelable(*parcelable);
}

status_t Parcel::writeParcelable(const Parcelable& parcelable) {
    status_t status = writeInt32(1);  // parcelable is not null.
    if (status != OK) {
        return status;
    }
    return parcelable.writeToParcel(this);
}

status_t Parcel::writeNativeHandle(const native_handle* handle)
{
    if (!handle || handle->version != sizeof(native_handle))
        return BAD_TYPE;

    status_t err;
    err = writeInt32(handle->numFds);
    if (err != NO_ERROR) return err;

    err = writeInt32(handle->numInts);
    if (err != NO_ERROR) return err;

    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
        err = writeDupFileDescriptor(handle->data[i]);

    if (err != NO_ERROR) {
        ALOGD("write native handle, write dup fd failed");
        return err;
    }
    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
    return err;
}

status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
{
    flat_binder_object obj;
    obj.hdr.type = BINDER_TYPE_FD;
    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
    obj.handle = fd;
    obj.cookie = takeOwnership ? 1 : 0;
    return writeObject(obj, true);
}

status_t Parcel::writeDupFileDescriptor(int fd)
{
    int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
    if (dupFd < 0) {
        return -errno;
    }
    status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
    if (err != OK) {
        close(dupFd);
    }
    return err;
}

status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
{
    writeInt32(0);
    return writeFileDescriptor(fd, takeOwnership);
}

status_t Parcel::writeDupParcelFileDescriptor(int fd)
{
    int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
    if (dupFd < 0) {
        return -errno;
    }
    status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
    if (err != OK) {
        close(dupFd);
    }
    return err;
}

status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
    return writeDupFileDescriptor(fd.get());
}

status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
    return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}

status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<base::unique_fd>>& val) {
    return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}

status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
    return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}

status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
{
    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 status;
    if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
        ALOGV("writeBlob: write in place");
        status = writeInt32(BLOB_INPLACE);
        if (status) return status;

        void* ptr = writeInplace(len);
        if (!ptr) return NO_MEMORY;

        outBlob->init(-1, ptr, len, false);
        return NO_ERROR;
    }

    ALOGV("writeBlob: write to ashmem");
    int fd = ashmem_create_region("Parcel Blob", len);
    if (fd < 0) return NO_MEMORY;

    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
    if (result < 0) {
        status = result;
    } else {
        void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (ptr == MAP_FAILED) {
            status = -errno;
        } else {
            if (!mutableCopy) {
                result = ashmem_set_prot_region(fd, PROT_READ);
            }
            if (result < 0) {
                status = result;
            } else {
                status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
                if (!status) {
                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
                    if (!status) {
                        outBlob->init(fd, ptr, len, mutableCopy);
                        return NO_ERROR;
                    }
                }
            }
        }
        ::munmap(ptr, len);
    }
    ::close(fd);
    return status;
}

status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
{
    // Must match up with what's done in writeBlob.
    if (!mAllowFds) return FDS_NOT_ALLOWED;
    status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
    if (status) return status;
    return writeDupFileDescriptor(fd);
}

status_t Parcel::write(const FlattenableHelperInterface& val)
{
    status_t err;

    // size if needed
    const size_t len = val.getFlattenedSize();
    const size_t fd_count = val.getFdCount();

    if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    err = this->writeInt32(len);
    if (err) return err;

    err = this->writeInt32(fd_count);
    if (err) return err;

    // payload
    void* const buf = this->writeInplace(len);
    if (buf == nullptr)
        return BAD_VALUE;

    int* fds = nullptr;
    if (fd_count) {
        fds = new (std::nothrow) int[fd_count];
        if (fds == nullptr) {
            ALOGE("write: failed to allocate requested %zu fds", fd_count);
            return BAD_VALUE;
        }
    }

    err = val.flatten(buf, len, fds, fd_count);
    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
        err = this->writeDupFileDescriptor( fds[i] );
    }

    if (fd_count) {
        delete [] fds;
    }

    return err;
}

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

        // remember if it's a file descriptor
        if (val.hdr.type == BINDER_TYPE_FD) {
            if (!mAllowFds) {
                // fail before modifying our object index
                return FDS_NOT_ALLOWED;
            }
            mHasFds = mFdsKnown = true;
        }

        // Need to write meta-data?
        if (nullMetaData || val.binder != 0) {
            mObjects[mObjectsSize] = mDataPos;
            acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
            mObjectsSize++;
        }

        return finishWrite(sizeof(flat_binder_object));
    }

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

    goto restart_write;
}

status_t Parcel::writeNoException()
{
    binder::Status status;
    return status.writeToParcel(this);
}

status_t Parcel::validateReadData(size_t upperBound) const
{
    // Don't allow non-object reads on object data
    if (mObjectsSorted || mObjectsSize <= 1) {
data_sorted:
        // Expect to check only against the next object
        if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
            // For some reason the current read position is greater than the next object
            // hint. Iterate until we find the right object
            size_t nextObject = mNextObjectHint;
            do {
                if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
                    // Requested info overlaps with an object
                    ALOGE("Attempt to read from protected data in Parcel %p", this);
                    return PERMISSION_DENIED;
                }
                nextObject++;
            } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
            mNextObjectHint = nextObject;
        }
        return NO_ERROR;
    }
    // Quickly determine if mObjects is sorted.
    binder_size_t* currObj = mObjects + mObjectsSize - 1;
    binder_size_t* prevObj = currObj;
    while (currObj > mObjects) {
        prevObj--;
        if(*prevObj > *currObj) {
            goto data_unsorted;
        }
        currObj--;
    }
    mObjectsSorted = true;
    goto data_sorted;

data_unsorted:
    // Insertion Sort mObjects
    // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
    // switch to std::sort(mObjects, mObjects + mObjectsSize);
    for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
        binder_size_t temp = *iter0;
        binder_size_t* iter1 = iter0 - 1;
        while (iter1 >= mObjects && *iter1 > temp) {
            *(iter1 + 1) = *iter1;
            iter1--;
        }
        *(iter1 + 1) = temp;
    }
    mNextObjectHint = 0;
    mObjectsSorted = true;
    goto data_sorted;
}

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)) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + pad_size(len));
            if(err != NO_ERROR) {
                // Still increment the data position by the expected length
                mDataPos += pad_size(len);
                ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
                return err;
            }
        }
        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 nullptr;
    }

    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
            && len <= pad_size(len)) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + pad_size(len));
            if(err != NO_ERROR) {
                // Still increment the data position by the expected length
                mDataPos += pad_size(len);
                ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
                return nullptr;
            }
        }

        const void* data = mData+mDataPos;
        mDataPos += pad_size(len);
        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
        return data;
    }
    return nullptr;
}

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

    if ((mDataPos+sizeof(T)) <= mDataSize) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + sizeof(T));
            if(err != NO_ERROR) {
                // Still increment the data position by the expected length
                mDataPos += sizeof(T);
                return err;
            }
        }

        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) {
    static_assert(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::readByteVector(std::vector<int8_t>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    return readByteVectorInternal(val, size);
}

status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    return readByteVectorInternal(val, size);
}

status_t Parcel::readByteVector(std::optional<std::vector<int8_t>>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    if (!*val) {
        // reserveOutVector does not create the out vector if size is < 0.
        // This occurs when writing a null byte vector.
        return OK;
    }
    return readByteVectorInternal(&**val, size);
}

status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    if (val->get() == nullptr) {
        // reserveOutVector does not create the out vector if size is < 0.
        // This occurs when writing a null byte vector.
        return OK;
    }
    return readByteVectorInternal(val->get(), size);
}

status_t Parcel::readByteVector(std::optional<std::vector<uint8_t>>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    if (!*val) {
        // reserveOutVector does not create the out vector if size is < 0.
        // This occurs when writing a null byte vector.
        return OK;
    }
    return readByteVectorInternal(&**val, size);
}

status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
    size_t size;
    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
    if (val->get() == nullptr) {
        // reserveOutVector does not create the out vector if size is < 0.
        // This occurs when writing a null byte vector.
        return OK;
    }
    return readByteVectorInternal(val->get(), size);
}

status_t Parcel::readInt32Vector(std::optional<std::vector<int32_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readInt32);
}

status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readInt32);
}

status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
    return readTypedVector(val, &Parcel::readInt32);
}

status_t Parcel::readInt64Vector(std::optional<std::vector<int64_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readInt64);
}

status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readInt64);
}

status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
    return readTypedVector(val, &Parcel::readInt64);
}

status_t Parcel::readUint64Vector(std::optional<std::vector<uint64_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUint64);
}

status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUint64);
}

status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
    return readTypedVector(val, &Parcel::readUint64);
}

status_t Parcel::readFloatVector(std::optional<std::vector<float>>* val) const {
    return readNullableTypedVector(val, &Parcel::readFloat);
}

status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
    return readNullableTypedVector(val, &Parcel::readFloat);
}

status_t Parcel::readFloatVector(std::vector<float>* val) const {
    return readTypedVector(val, &Parcel::readFloat);
}

status_t Parcel::readDoubleVector(std::optional<std::vector<double>>* val) const {
    return readNullableTypedVector(val, &Parcel::readDouble);
}

status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
    return readNullableTypedVector(val, &Parcel::readDouble);
}

status_t Parcel::readDoubleVector(std::vector<double>* val) const {
    return readTypedVector(val, &Parcel::readDouble);
}

status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* val) const {
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    val->reset();

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

    setDataPosition(start);
    val->emplace();

    status = readBoolVector(&**val);

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

    return status;
}

status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    val->reset();

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

    setDataPosition(start);
    val->reset(new (std::nothrow) std::vector<bool>());

    status = readBoolVector(val->get());

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

    return status;
}

status_t Parcel::readBoolVector(std::vector<bool>* val) const {
    int32_t size;
    status_t status = readInt32(&size);

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

    if (size < 0) {
        return UNEXPECTED_NULL;
    }

    val->resize(size);

    /* C++ bool handling means a vector of bools isn't necessarily addressable
     * (we might use individual bits)
     */
    bool data;
    for (int32_t i = 0; i < size; ++i) {
        status = readBool(&data);
        (*val)[i] = data;

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

    return OK;
}

status_t Parcel::readCharVector(std::optional<std::vector<char16_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readChar);
}

status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
    return readNullableTypedVector(val, &Parcel::readChar);
}

status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
    return readTypedVector(val, &Parcel::readChar);
}

status_t Parcel::readString16Vector(
        std::optional<std::vector<std::optional<String16>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readString16);
}

status_t Parcel::readString16Vector(
        std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readString16);
}

status_t Parcel::readString16Vector(std::vector<String16>* val) const {
    return readTypedVector(val, &Parcel::readString16);
}

status_t Parcel::readUtf8VectorFromUtf16Vector(
        std::optional<std::vector<std::optional<std::string>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
}

status_t Parcel::readUtf8VectorFromUtf16Vector(
        std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
}

status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
    return readTypedVector(val, &Parcel::readUtf8FromUtf16);
}

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::readIntPtr(intptr_t *pArg) const
{
    return readAligned(pArg);
}


intptr_t Parcel::readIntPtr() const
{
    return readAligned<intptr_t>();
}

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

bool Parcel::readBool() const
{
    return readInt32() != 0;
}

status_t Parcel::readChar(char16_t *pArg) const
{
    int32_t tmp = 0;
    status_t ret = readInt32(&tmp);
    *pArg = char16_t(tmp);
    return ret;
}

char16_t Parcel::readChar() const
{
    return char16_t(readInt32());
}

status_t Parcel::readByte(int8_t *pArg) const
{
    int32_t tmp = 0;
    status_t ret = readInt32(&tmp);
    *pArg = int8_t(tmp);
    return ret;
}

int8_t Parcel::readByte() const
{
    return int8_t(readInt32());
}

status_t Parcel::readUtf8FromUtf16(std::string* str) const {
    size_t utf16Size = 0;
    const char16_t* src = readString16Inplace(&utf16Size);
    if (!src) {
        return UNEXPECTED_NULL;
    }

    // Save ourselves the trouble, we're done.
    if (utf16Size == 0u) {
        str->clear();
       return NO_ERROR;
    }

    // Allow for closing '\0'
    ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
    if (utf8Size < 1) {
        return BAD_VALUE;
    }
    // Note that while it is probably safe to assume string::resize keeps a
    // spare byte around for the trailing null, we still pass the size including the trailing null
    str->resize(utf8Size);
    utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
    str->resize(utf8Size - 1);
    return NO_ERROR;
}

status_t Parcel::readUtf8FromUtf16(std::optional<std::string>* str) const {
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    str->reset();

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

    setDataPosition(start);
    str->emplace();
    return readUtf8FromUtf16(&**str);
}

status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    str->reset();

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

    setDataPosition(start);
    str->reset(new (std::nothrow) std::string());
    return readUtf8FromUtf16(str->get());
}

const char* Parcel::readCString() const
{
    if (mDataPos < mDataSize) {
        const size_t avail = mDataSize-mDataPos;
        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 nullptr;
}

String8 Parcel::readString8() const
{
    size_t len;
    const char* str = readString8Inplace(&len);
    if (str) return String8(str, len);
    ALOGE("Reading a NULL string not supported here.");
    return String8();
}

status_t Parcel::readString8(String8* pArg) const
{
    size_t len;
    const char* str = readString8Inplace(&len);
    if (str) {
        pArg->setTo(str, len);
        return 0;
    } else {
        *pArg = String8();
        return UNEXPECTED_NULL;
    }
}

const char* Parcel::readString8Inplace(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 char* str = (const char*)readInplace(size+1);
        if (str != nullptr) {
            return str;
        }
    }
    *outLen = 0;
    return nullptr;
}

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::optional<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->emplace();

    status = readString16(&**pArg);

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

    return status;
}

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 != nullptr) {
            return str;
        }
    }
    *outLen = 0;
    return nullptr;
}

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 unflattenBinder(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;
}

status_t Parcel::readParcelable(Parcelable* parcelable) const {
    int32_t have_parcelable = 0;
    status_t status = readInt32(&have_parcelable);
    if (status != OK) {
        return status;
    }
    if (!have_parcelable) {
        return UNEXPECTED_NULL;
    }
    return parcelable->readFromParcel(this);
}

int32_t Parcel::readExceptionCode() const
{
    binder::Status status;
    status.readFromParcel(*this);
    return status.exceptionCode();
}

native_handle* Parcel::readNativeHandle() const
{
    int numFds, numInts;
    status_t err;
    err = readInt32(&numFds);
    if (err != NO_ERROR) return nullptr;
    err = readInt32(&numInts);
    if (err != NO_ERROR) return nullptr;

    native_handle* h = native_handle_create(numFds, numInts);
    if (!h) {
        return nullptr;
    }

    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
        h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
        if (h->data[i] < 0) {
            for (int j = 0; j < i; j++) {
                close(h->data[j]);
            }
            native_handle_delete(h);
            return nullptr;
        }
    }
    err = read(h->data + numFds, sizeof(int)*numInts);
    if (err != NO_ERROR) {
        native_handle_close(h);
        native_handle_delete(h);
        h = nullptr;
    }
    return h;
}

int Parcel::readFileDescriptor() const
{
    const flat_binder_object* flat = readObject(true);

    if (flat && flat->hdr.type == BINDER_TYPE_FD) {
        return flat->handle;
    }

    return BAD_TYPE;
}

int Parcel::readParcelFileDescriptor() const
{
    int32_t hasComm = readInt32();
    int fd = readFileDescriptor();
    if (hasComm != 0) {
        // detach (owned by the binder driver)
        int comm = readFileDescriptor();

        // warning: this must be kept in sync with:
        // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
        enum ParcelFileDescriptorStatus {
            DETACHED = 2,
        };

#if BYTE_ORDER == BIG_ENDIAN
        const int32_t message = ParcelFileDescriptorStatus::DETACHED;
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
        const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
#endif

        ssize_t written = TEMP_FAILURE_RETRY(
            ::write(comm, &message, sizeof(message)));

        if (written == -1 || written != sizeof(message)) {
            ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
                written, strerror(errno));
            return BAD_TYPE;
        }
    }
    return fd;
}

status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
{
    int got = readFileDescriptor();

    if (got == BAD_TYPE) {
        return BAD_TYPE;
    }

    val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));

    if (val->get() < 0) {
        return BAD_VALUE;
    }

    return OK;
}

status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
{
    int got = readParcelFileDescriptor();

    if (got == BAD_TYPE) {
        return BAD_TYPE;
    }

    val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));

    if (val->get() < 0) {
        return BAD_VALUE;
    }

    return OK;
}

status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<base::unique_fd>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
}

status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
}

status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
    return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
}

status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
{
    int32_t blobType;
    status_t status = readInt32(&blobType);
    if (status) return status;

    if (blobType == BLOB_INPLACE) {
        ALOGV("readBlob: read in place");
        const void* ptr = readInplace(len);
        if (!ptr) return BAD_VALUE;

        outBlob->init(-1, const_cast<void*>(ptr), len, false);
        return NO_ERROR;
    }

    ALOGV("readBlob: read from ashmem");
    bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
    int fd = readFileDescriptor();
    if (fd == int(BAD_TYPE)) return BAD_VALUE;

    if (!ashmem_valid(fd)) {
        ALOGE("invalid fd");
        return BAD_VALUE;
    }
    int size = ashmem_get_size_region(fd);
    if (size < 0 || size_t(size) < len) {
        ALOGE("request size %zu does not match fd size %d", len, size);
        return BAD_VALUE;
    }
    void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
            MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED) return NO_MEMORY;

    outBlob->init(fd, ptr, len, isMutable);
    return NO_ERROR;
}

status_t Parcel::read(FlattenableHelperInterface& val) const
{
    // size
    const size_t len = this->readInt32();
    const size_t fd_count = this->readInt32();

    if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
        // don't accept size_t values which may have come from an
        // inadvertent conversion from a negative int.
        return BAD_VALUE;
    }

    // payload
    void const* const buf = this->readInplace(pad_size(len));
    if (buf == nullptr)
        return BAD_VALUE;

    int* fds = nullptr;
    if (fd_count) {
        fds = new (std::nothrow) int[fd_count];
        if (fds == nullptr) {
            ALOGE("read: failed to allocate requested %zu fds", fd_count);
            return BAD_VALUE;
        }
    }

    status_t err = NO_ERROR;
    for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
        int fd = this->readFileDescriptor();
        if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
            err = BAD_VALUE;
            ALOGE("fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
                  i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
            // Close all the file descriptors that were dup-ed.
            for (size_t j=0; j<i ;j++) {
                close(fds[j]);
            }
        }
    }

    if (err == NO_ERROR) {
        err = val.unflatten(buf, len, fds, fd_count);
    }

    if (fd_count) {
        delete [] fds;
    }

    return err;
}
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
    const size_t DPOS = mDataPos;
    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
        const flat_binder_object* obj
                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
        mDataPos = DPOS + sizeof(flat_binder_object);
        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
            // When transferring a NULL 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;
        }

        // 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);
                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);
                return obj;
            }
        }
        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
             this, DPOS);
    }
    return nullptr;
}

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;
}

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;
    mObjectsSorted = false;
    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;
        }
        const flat_binder_object* flat
            = reinterpret_cast<const flat_binder_object*>(mData + offset);
        uint32_t type = flat->hdr.type;
        if (!(type == BINDER_TYPE_BINDER || type == BINDER_TYPE_HANDLE ||
              type == BINDER_TYPE_FD)) {
            // We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
            // them in libbinder. If we do receive them, it probably means a kernel bug; try to
            // recover gracefully by clearing out the objects, and releasing the objects we do
            // know about.
            android_errorWriteLog(0x534e4554, "135930648");
            ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
                  __func__, type, (uint64_t)offset);
            releaseObjects();
            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 = mObjects;
        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]);
            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
                << TypeCode(flat->hdr.type & 0x7f7f7f00)
                << " = " << flat->binder;
        }
    } else {
        to << "NULL";
    }

    to << ")";
}

void Parcel::releaseObjects()
{
    size_t i = mObjectsSize;
    if (i == 0) {
        return;
    }
    sp<ProcessState> proc(ProcessState::self());
    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, &mOpenAshmemSize);
    }
}

void Parcel::acquireObjects()
{
    size_t i = mObjectsSize;
    if (i == 0) {
        return;
    }
    const sp<ProcessState> proc(ProcessState::self());
    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]);
        acquire_object(proc, *flat, this, &mOpenAshmemSize);
    }
}

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;
    }

    if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow
    if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow
    size_t newSize = ((mDataSize+len)*3)/2;
    return (newSize <= mDataSize)
            ? (status_t) NO_MEMORY
            : continueWrite(std::max(newSize, (size_t) 128));
}

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 = nullptr;
    mObjectsSize = mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
    mHasFds = false;
    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 = nullptr;

        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 = nullptr;

        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;
        mObjectsSorted = false;

    } 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, &mOpenAshmemSize);
            }

            if (objectsSize == 0) {
                free(mObjects);
                mObjects = nullptr;
                mObjectsCapacity = 0;
            } else {
                binder_size_t* objects =
                    (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
                if (objects) {
                    mObjects = objects;
                    mObjectsCapacity = objectsSize;
                }
            }
            mObjectsSize = objectsSize;
            mNextObjectHint = 0;
            mObjectsSorted = false;
        }

        // 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 == nullptr
             && 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 = nullptr;
    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 = nullptr;
    mObjectsSize = 0;
    mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
    mHasFds = false;
    mFdsKnown = true;
    mAllowFds = true;
    mOwner = nullptr;
    mOpenAshmemSize = 0;
    mWorkSourceRequestHeaderPosition = 0;
    mRequestHeaderPresent = false;

    // 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;
}

size_t Parcel::getBlobAshmemSize() const
{
    // This used to return the size of all blobs that were written to ashmem, now we're returning
    // the ashmem currently referenced by this Parcel, which should be equivalent.
    // TODO: Remove method once ABI can be changed.
    return mOpenAshmemSize;
}

size_t Parcel::getOpenAshmemSize() const
{
    return mOpenAshmemSize;
}

// --- Parcel::Blob ---

Parcel::Blob::Blob() :
        mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
}

Parcel::Blob::~Blob() {
    release();
}

void Parcel::Blob::release() {
    if (mFd != -1 && mData) {
        ::munmap(mData, mSize);
    }
    clear();
}

void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
    mFd = fd;
    mData = data;
    mSize = size;
    mMutable = isMutable;
}

void Parcel::Blob::clear() {
    mFd = -1;
    mData = nullptr;
    mSize = 0;
    mMutable = false;
}

} // namespace android
