/*
* 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.
*/
#ifndef ANDROID_HARDWARE_PARCEL_H
#define ANDROID_HARDWARE_PARCEL_H
#include <string>
#include <vector>
#include <cutils/native_handle.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/String16.h>
#include <linux/android/binder.h>
#include <hwbinder/IInterface.h>
struct binder_buffer_object;
// ---------------------------------------------------------------------------
namespace android {
namespace hardware {
class IBinder;
class IPCThreadState;
class ProcessState;
class TextOutput;
class Parcel {
friend class IPCThreadState;
public:
Parcel();
~Parcel();
const uint8_t* data() const;
size_t dataSize() const;
size_t dataAvail() const;
size_t dataPosition() const;
size_t dataCapacity() const;
status_t setDataSize(size_t size);
void setDataPosition(size_t pos) const;
status_t setDataCapacity(size_t size);
status_t setData(const uint8_t* buffer, size_t len);
// Writes the RPC header.
status_t writeInterfaceToken(const char* interface);
// Parses the RPC header, returning true if the interface name
// in the header matches the expected interface from the caller.
bool enforceInterface(const char* interface) const;
bool checkInterface(IBinder*) const;
void freeData();
private:
const binder_size_t* objects() const;
public:
size_t objectsCount() const;
status_t errorCheck() const;
void setError(status_t err);
status_t write(const void* data, size_t len);
void* writeInplace(size_t len);
status_t writeUnpadded(const void* data, size_t len);
status_t writeInt8(int8_t val);
status_t writeUint8(uint8_t val);
status_t writeInt16(int16_t val);
status_t writeUint16(uint16_t val);
status_t writeInt32(int32_t val);
status_t writeUint32(uint32_t val);
status_t writeInt64(int64_t val);
status_t writeUint64(uint64_t val);
status_t writeFloat(float val);
status_t writeDouble(double val);
status_t writeCString(const char* str);
status_t writeString16(const String16& str);
status_t writeString16(const std::unique_ptr<String16>& str);
status_t writeString16(const char16_t* str, size_t len);
status_t writeStrongBinder(const sp<IBinder>& val);
status_t writeWeakBinder(const wp<IBinder>& val);
status_t writeBool(bool val);
template<typename T>
status_t writeObject(const T& val);
status_t writeBuffer(const void *buffer, size_t length, size_t *handle);
status_t writeEmbeddedBuffer(const void *buffer, size_t length, size_t *handle,
size_t parent_buffer_handle, size_t parent_offset);
public:
status_t writeReference(size_t *handle,
size_t child_buffer_handle, size_t child_offset);
status_t writeEmbeddedReference(size_t *handle,
size_t child_buffer_handle, size_t child_offset,
size_t parent_buffer_handle, size_t parent_offset);
status_t writeNullReference(size_t *handle);
status_t writeEmbeddedNullReference(size_t *handle,
size_t parent_buffer_handle, size_t parent_offset);
status_t writeEmbeddedNativeHandle(const native_handle_t *handle,
size_t parent_buffer_handle, size_t parent_offset);
status_t writeNativeHandleNoDup(const native_handle* handle, bool embedded,
size_t parent_buffer_handle = 0,
size_t parent_offset = 0);
status_t writeNativeHandleNoDup(const native_handle* handle);
void remove(size_t start, size_t amt);
status_t read(void* outData, size_t len) const;
const void* readInplace(size_t len) const;
status_t readInt8(int8_t *pArg) const;
status_t readUint8(uint8_t *pArg) const;
status_t readInt16(int16_t *pArg) const;
status_t readUint16(uint16_t *pArg) const;
int32_t readInt32() const;
status_t readInt32(int32_t *pArg) const;
uint32_t readUint32() const;
status_t readUint32(uint32_t *pArg) const;
int64_t readInt64() const;
status_t readInt64(int64_t *pArg) const;
uint64_t readUint64() const;
status_t readUint64(uint64_t *pArg) const;
float readFloat() const;
status_t readFloat(float *pArg) const;
double readDouble() const;
status_t readDouble(double *pArg) const;
bool readBool() const;
status_t readBool(bool *pArg) const;
const char* readCString() const;
String16 readString16() const;
status_t readString16(String16* pArg) const;
status_t readString16(std::unique_ptr<String16>* pArg) const;
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
status_t readStrongBinder(sp<IBinder>* val) const;
status_t readNullableStrongBinder(sp<IBinder>* val) const;
wp<IBinder> readWeakBinder() const;
template<typename T>
const T* readObject(size_t *objects_offset = nullptr) const;
status_t readBuffer(size_t buffer_size, size_t *buffer_handle,
const void **buffer_out) const;
status_t readNullableBuffer(size_t buffer_size, size_t *buffer_handle,
const void **buffer_out) const;
status_t 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 readNullableEmbeddedBuffer(size_t buffer_size,
size_t *buffer_handle,
size_t parent_buffer_handle,
size_t parent_offset,
const void **buffer_out) const;
status_t readReference(void const* *bufptr,
size_t *buffer_handle, bool *isRef) const;
status_t readEmbeddedReference(void const* *bufptr, size_t *buffer_handle,
size_t parent_buffer_handle, size_t parent_offset,
bool *isRef) const;
status_t readEmbeddedNativeHandle(size_t parent_buffer_handle,
size_t parent_offset, const native_handle_t **handle) const;
status_t readNullableEmbeddedNativeHandle(size_t parent_buffer_handle,
size_t parent_offset, const native_handle_t **handle) const;
status_t readNativeHandleNoDup(const native_handle_t **handle) const;
status_t readNullableNativeHandleNoDup(const native_handle_t **handle) const;
// Explicitly close all file descriptors in the parcel.
void closeFileDescriptors();
// Debugging: get metrics on current allocations.
static size_t getGlobalAllocSize();
static size_t getGlobalAllocCount();
private:
// Below is a cache that records some information about all actual buffers
// in this parcel.
struct BufferInfo {
size_t index;
binder_uintptr_t buffer;
binder_uintptr_t bufend; // buffer + length
};
// value of mObjectSize when mBufCache is last updated.
mutable size_t mBufCachePos;
mutable std::vector<BufferInfo> mBufCache;
// clear mBufCachePos and mBufCache.
void clearCache() const;
// update mBufCache for all objects between mBufCachePos and mObjectsSize
void updateCache() const;
bool verifyBufferObject(const binder_buffer_object *buffer_obj,
size_t size, uint32_t flags, size_t parent,
size_t parentOffset) const;
status_t readBuffer(size_t buffer_size, size_t *buffer_handle,
uint32_t flags, size_t parent, size_t parentOffset,
const void **buffer_out) const;
status_t readNullableNativeHandleNoDup(const native_handle_t **handle,
bool embedded,
size_t parent_buffer_handle = 0,
size_t parent_offset = 0) const;
public:
// The following two methods attempt to find if a chunk of memory ("buffer")
// is written / read before (by (read|write)(Embedded)?Buffer methods. )
// 1. Call findBuffer if the chunk of memory could be a small part of a larger
// buffer written before (for example, an element of a hidl_vec). The
// method will also ensure that the end address (ptr + length) is also
// within the buffer.
// 2. Call quickFindBuffer if the buffer could only be written previously
// by itself (for example, the mBuffer field of a hidl_vec). No lengths
// are checked.
status_t findBuffer(const void *ptr,
size_t length,
bool *found,
size_t *handle,
size_t *offset // valid if found
) const;
status_t quickFindBuffer(const void *ptr,
size_t *handle // valid if found
) const;
private:
status_t incrementNumReferences();
bool validateBufferChild(size_t child_buffer_handle,
size_t child_offset) const;
bool validateBufferParent(size_t parent_buffer_handle,
size_t parent_offset) const;
private:
typedef void (*release_func)(Parcel* parcel,
const uint8_t* data, size_t dataSize,
const binder_size_t* objects, size_t objectsSize,
void* cookie);
uintptr_t ipcData() const;
size_t ipcDataSize() const;
uintptr_t ipcObjects() const;
size_t ipcObjectsCount() const;
size_t ipcBufferSize() const;
void ipcSetDataReference(const uint8_t* data, size_t dataSize,
const binder_size_t* objects, size_t objectsCount,
release_func relFunc, void* relCookie);
public:
void print(TextOutput& to, uint32_t flags = 0) const;
private:
Parcel(const Parcel& o);
Parcel& operator=(const Parcel& o);
status_t finishWrite(size_t len);
void releaseObjects();
void acquireObjects();
status_t growData(size_t len);
status_t restartWrite(size_t desired);
status_t continueWrite(size_t desired);
status_t writePointer(uintptr_t val);
status_t readPointer(uintptr_t *pArg) const;
uintptr_t readPointer() const;
void freeDataNoInit();
void initState();
void scanForFds() const;
template<class T>
status_t readAligned(T *pArg) const;
template<class T> T readAligned() const;
template<class T>
status_t writeAligned(T val);
status_t mError;
uint8_t* mData;
size_t mDataSize;
size_t mDataCapacity;
mutable size_t mDataPos;
binder_size_t* mObjects;
size_t mObjectsSize;
size_t mObjectsCapacity;
mutable size_t mNextObjectHint;
size_t mNumRef;
mutable bool mFdsKnown;
mutable bool mHasFds;
bool mAllowFds;
release_func mOwner;
void* mOwnerCookie;
};
// ---------------------------------------------------------------------------
inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
{
parcel.print(to);
return to;
}
// ---------------------------------------------------------------------------
// Generic acquire and release of objects.
void acquire_object(const sp<ProcessState>& proc,
const flat_binder_object& obj, const void* who);
void release_object(const sp<ProcessState>& proc,
const flat_binder_object& obj, const void* who);
void flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, flat_binder_object* out);
void flatten_binder(const sp<ProcessState>& proc,
const wp<IBinder>& binder, flat_binder_object* out);
status_t unflatten_binder(const sp<ProcessState>& proc,
const flat_binder_object& flat, sp<IBinder>* out);
status_t unflatten_binder(const sp<ProcessState>& proc,
const flat_binder_object& flat, wp<IBinder>* out);
}; // namespace hardware
}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_HARDWARE_PARCEL_H