Help us shape the future of Go! Take the 2026 Go Developer Survey

hwparcel

package
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: CC0-1.0 Imports: 5 Imported by: 0

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

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 New

func New() *HwParcel

New creates a new empty HwParcel.

func (*HwParcel) BufferCount

func (p *HwParcel) BufferCount() int

BufferCount returns the number of scatter-gather buffer objects.

func (*HwParcel) DataBytes

func (p *HwParcel) DataBytes() []byte

DataBytes returns the raw inline data bytes.

func (*HwParcel) DumpBufferObjects

func (p *HwParcel) DumpBufferObjects() []string

DumpBufferObjects returns a debug description of all buffer objects in the parcel (type, flags, length, parent, parent_offset).

func (*HwParcel) ObjectOffsets

func (p *HwParcel) ObjectOffsets() []uint64

ObjectOffsets returns the objects array (byte offsets of binder objects).

func (*HwParcel) ToParcel

func (p *HwParcel) ToParcel() (*parcel.Parcel, [][]byte)

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

func (p *HwParcel) WriteBool(v bool)

WriteBool writes a boolean as a uint8 into the inline data buffer, padded to 4-byte alignment.

func (*HwParcel) WriteBuffer

func (p *HwParcel) WriteBuffer(buf []byte) int

WriteBuffer writes a top-level scatter-gather buffer object. Returns the handle (index) for parent references.

func (*HwParcel) WriteEmbeddedBuffer

func (p *HwParcel) WriteEmbeddedBuffer(
	buf []byte,
	parentHandle int,
	parentOffset uint64,
) int

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

func (p *HwParcel) WriteFdArrayObject(
	numFds int,
	bufferHandle int,
	parentOffset uint64,
)

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

func (p *HwParcel) WriteHidlString(s string)

WriteHidlString writes a hidl_string value. Creates two buffer objects:

  1. The hidl_string struct (16 bytes)
  2. The string data (child of #1, linked at the pointer field offset 0)

func (*HwParcel) WriteHidlVecBytes

func (p *HwParcel) WriteHidlVecBytes(data []byte)

WriteHidlVecBytes writes a hidl_vec<uint8_t>. Creates two buffer objects:

  1. The hidl_vec header (16 bytes)
  2. The byte array data (child of #1)

func (*HwParcel) WriteHidlVecUint32

func (p *HwParcel) WriteHidlVecUint32(values []uint32)

WriteHidlVecUint32 writes a hidl_vec<uint32_t>. Creates two buffer objects:

  1. The hidl_vec header (16 bytes)
  2. The uint32 array data (child of #1)

func (*HwParcel) WriteInt32

func (p *HwParcel) WriteInt32(v int32)

WriteInt32 writes an int32 directly into the inline data buffer.

func (*HwParcel) WriteInterfaceToken

func (p *HwParcel) WriteInterfaceToken(descriptor string)

WriteInterfaceToken writes the HIDL interface descriptor as a null-terminated C string in the data buffer.

func (*HwParcel) WriteLocalBinder

func (p *HwParcel) WriteLocalBinder(
	binderPtr uintptr,
	cookie uintptr,
)

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

func (p *HwParcel) WriteUint32(v uint32)

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

func (p *HwParcel) WriteUint64(v uint64)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL