Documentation
¶
Overview ¶
Package hwparcel implements the HIDL HwParcel wire format for hwbinder transactions. Unlike AIDL parcels that use inline data, HIDL uses scatter-gather serialization with binder_buffer_object entries (BINDER_TYPE_PTR) that reference external data buffers.
The HIDL wire format is:
- Interface token: null-terminated C string in the data buffer
- Structured data: binder_buffer_object entries in the data buffer, each pointing to a separate buffer in process memory. The kernel copies these buffers to the target process.
- hidl_string: 16-byte struct (8-byte pointer + 4-byte size + 4-byte pad) with string data as a child buffer
- hidl_vec<T>: 16-byte struct (8-byte pointer + 4-byte size + 4-byte pad) with element data as a child buffer
Index ¶
- func KeepBuffersAlive(buffers [][]byte)
- type HwParcel
- func (p *HwParcel) BufferCount() int
- func (p *HwParcel) DataBytes() []byte
- func (p *HwParcel) DumpBufferObjects() []string
- func (p *HwParcel) ObjectOffsets() []uint64
- func (p *HwParcel) ToParcel() (*parcel.Parcel, [][]byte)
- func (p *HwParcel) WriteBool(v bool)
- func (p *HwParcel) WriteBuffer(buf []byte) int
- func (p *HwParcel) WriteEmbeddedBuffer(buf []byte, parentHandle int, parentOffset uint64) int
- func (p *HwParcel) WriteEmbeddedNativeHandle(fds []int32, ints []int32, parentHandle int, parentOffset uint64)
- func (p *HwParcel) WriteFdArrayObject(numFds int, bufferHandle int, parentOffset uint64)
- func (p *HwParcel) WriteHidlString(s string)
- func (p *HwParcel) WriteHidlVecBytes(data []byte)
- func (p *HwParcel) WriteHidlVecUint32(values []uint32)
- func (p *HwParcel) WriteInt32(v int32)
- func (p *HwParcel) WriteInterfaceToken(descriptor string)
- func (p *HwParcel) WriteLocalBinder(binderPtr uintptr, cookie uintptr)
- func (p *HwParcel) WriteNullBinder()
- func (p *HwParcel) WriteNullNativeHandle()
- func (p *HwParcel) WriteUint32(v uint32)
- func (p *HwParcel) WriteUint64(v uint64)
- type ResponseParcel
- func (r *ResponseParcel) DataLen() int
- func (r *ResponseParcel) Position() int
- func (r *ResponseParcel) ReadInt32() (int32, error)
- func (r *ResponseParcel) ReadNativeHandle() (fds []int32, ints []int32, err error)
- func (r *ResponseParcel) ReadRawBytes(n int) ([]byte, error)
- func (r *ResponseParcel) ReadStrongBinder() (uint32, error)
- func (r *ResponseParcel) ReadUint32() (uint32, error)
- func (r *ResponseParcel) Remaining() int
- func (r *ResponseParcel) SkipBytes(n int) error
- func (r *ResponseParcel) Underlying() *parcel.Parcel
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func KeepBuffersAlive ¶
func KeepBuffersAlive(buffers [][]byte)
KeepBuffersAlive calls runtime.KeepAlive on all buffer slices. Must be called after the binder ioctl completes.
Types ¶
type HwParcel ¶
type HwParcel struct {
// contains filtered or unexported fields
}
HwParcel builds a HIDL HwParcel for hwbinder transactions. It produces data and objects arrays compatible with the kernel binder scatter-gather protocol.
func (*HwParcel) BufferCount ¶
BufferCount returns the number of scatter-gather buffer objects.
func (*HwParcel) DumpBufferObjects ¶
DumpBufferObjects returns a debug description of all buffer objects in the parcel (type, flags, length, parent, parent_offset).
func (*HwParcel) ObjectOffsets ¶
ObjectOffsets returns the objects array (byte offsets of binder objects).
func (*HwParcel) ToParcel ¶
ToParcel converts this HwParcel into a standard parcel.Parcel. It patches the buffer pointers in each binder_buffer_object to point to the actual buffer data in memory. The returned keepAlive slice must be kept alive (via runtime.KeepAlive) until the transaction completes.
func (*HwParcel) WriteBool ¶
WriteBool writes a boolean as a uint8 into the inline data buffer, padded to 4-byte alignment.
func (*HwParcel) WriteBuffer ¶
WriteBuffer writes a top-level scatter-gather buffer object. Returns the handle (index) for parent references.
func (*HwParcel) WriteEmbeddedBuffer ¶
WriteEmbeddedBuffer writes a child scatter-gather buffer embedded within a parent buffer. parentOffset is the byte offset within the parent buffer where the pointer to this child buffer lives (typically 0 for hidl_string and hidl_vec, since the pointer is the first field).
func (*HwParcel) WriteEmbeddedNativeHandle ¶
func (p *HwParcel) WriteEmbeddedNativeHandle( fds []int32, ints []int32, parentHandle int, parentOffset uint64, )
WriteEmbeddedNativeHandle writes a non-null native_handle_t as an embedded child buffer, plus a binder_fd_array_object so the kernel can translate the file descriptors.
Wire format:
uint64 native_handle_size (inline) binder_buffer_object pointing to native_handle_t data (child of parent) binder_fd_array_object referencing the FDs in the buffer
The native_handle_t buffer contains:
int32 version (= 12 = sizeof(native_handle_t)) int32 numFds int32 numInts int32[numFds] fds int32[numInts] ints
func (*HwParcel) WriteFdArrayObject ¶
WriteFdArrayObject writes a binder_fd_array_object into the data buffer and records its offset in the objects array. This tells the kernel that the buffer at bufferHandle contains file descriptors starting at parentOffset (typically offsetof(native_handle_t, data) = 12).
binder_fd_array_object layout (32 bytes):
[0:4] uint32 type (BINDER_TYPE_FDA = 0x66646185) [4:8] uint32 pad [8:16] uint64 num_fds [16:24] uint64 parent (buffer handle index) [24:32] uint64 parent_offset (offset of FD array within parent buffer)
func (*HwParcel) WriteHidlString ¶
WriteHidlString writes a hidl_string value. Creates two buffer objects:
- The hidl_string struct (16 bytes)
- The string data (child of #1, linked at the pointer field offset 0)
func (*HwParcel) WriteHidlVecBytes ¶
WriteHidlVecBytes writes a hidl_vec<uint8_t>. Creates two buffer objects:
- The hidl_vec header (16 bytes)
- The byte array data (child of #1)
func (*HwParcel) WriteHidlVecUint32 ¶
WriteHidlVecUint32 writes a hidl_vec<uint32_t>. Creates two buffer objects:
- The hidl_vec header (16 bytes)
- The uint32 array data (child of #1)
func (*HwParcel) WriteInt32 ¶
WriteInt32 writes an int32 directly into the inline data buffer.
func (*HwParcel) WriteInterfaceToken ¶
WriteInterfaceToken writes the HIDL interface descriptor as a null-terminated C string in the data buffer.
func (*HwParcel) WriteLocalBinder ¶
WriteLocalBinder writes a local HIDL binder reference (BINDER_TYPE_BINDER) into the inline data with a real binder/cookie pair. The kernel will create a binder_node for this object and translate it to a BINDER_TYPE_HANDLE in the receiving process.
Unlike AIDL, HIDL does NOT write a stability level after the flat_binder_object. The offset IS recorded in the objects array so the kernel processes it.
func (*HwParcel) WriteNullBinder ¶
func (p *HwParcel) WriteNullBinder()
WriteNullBinder writes a null HIDL binder reference into the inline data. HIDL null binders use flat_binder_object with BINDER_TYPE_BINDER and binder=0, cookie=0. Unlike AIDL, HIDL does NOT append a stability level. The offset is NOT recorded in the objects array (matching AOSP behavior where null binder objects are inert data).
func (*HwParcel) WriteNullNativeHandle ¶
func (p *HwParcel) WriteNullNativeHandle()
WriteNullNativeHandle writes the HIDL serialization for a null native_handle (hidl_handle with mHandle == nullptr).
Wire format: uint64(0) inline.
func (*HwParcel) WriteUint32 ¶
WriteUint32 writes a uint32 directly into the inline data buffer (not as a scatter-gather buffer object). Used for simple scalar arguments that follow buffer objects.
func (*HwParcel) WriteUint64 ¶
WriteUint64 writes a uint64 directly into the inline data buffer.
type ResponseParcel ¶
type ResponseParcel struct {
// contains filtered or unexported fields
}
ResponseParcel wraps a reply parcel.Parcel from a HIDL transaction and provides methods to read HIDL-formatted response data. HIDL replies don't use scatter-gather -- the kernel copies all buffer data into the target's mmap region, and the driver copies it into the reply parcel data buffer inline.
func NewResponseParcel ¶
func NewResponseParcel(p *parcel.Parcel) *ResponseParcel
NewResponseParcel wraps a standard parcel for HIDL response reading.
func (*ResponseParcel) DataLen ¶
func (r *ResponseParcel) DataLen() int
DataLen returns the total data length.
func (*ResponseParcel) Position ¶
func (r *ResponseParcel) Position() int
Position returns the current read position.
func (*ResponseParcel) ReadInt32 ¶
func (r *ResponseParcel) ReadInt32() (int32, error)
ReadInt32 reads an int32 from the response.
func (*ResponseParcel) ReadNativeHandle ¶
func (r *ResponseParcel) ReadNativeHandle() (fds []int32, ints []int32, err error)
ReadNativeHandle reads a native_handle_t from the HIDL response. Wire format: int32 numFds, int32 numInts, then flat_binder_object entries for each FD, then int32 entries for each int.
func (*ResponseParcel) ReadRawBytes ¶
func (r *ResponseParcel) ReadRawBytes(n int) ([]byte, error)
ReadRawBytes reads n raw bytes.
func (*ResponseParcel) ReadStrongBinder ¶
func (r *ResponseParcel) ReadStrongBinder() (uint32, error)
ReadStrongBinder reads a binder handle from the HIDL response. HIDL does NOT write a stability level after the flat_binder_object (unlike AIDL).
func (*ResponseParcel) ReadUint32 ¶
func (r *ResponseParcel) ReadUint32() (uint32, error)
ReadUint32 reads a uint32 from the response.
func (*ResponseParcel) Remaining ¶
func (r *ResponseParcel) Remaining() int
Remaining returns the number of unread bytes.
func (*ResponseParcel) SkipBytes ¶
func (r *ResponseParcel) SkipBytes(n int) error
SkipBytes advances the read position by n bytes (4-byte aligned).
func (*ResponseParcel) Underlying ¶
func (r *ResponseParcel) Underlying() *parcel.Parcel
Underlying returns the wrapped parcel for low-level access.