vendor <--> system 透过 HIDL 进程间传递 shared fd, 访问ion 共享内存
官网有介绍:
https://source.android.com/devices/architecture/hidl-cpp/types
HIDL service处理
handle
类型由 C++ 形式的 hidl_handle
结构表示,该结构是一个简单的封装容器,用于封装指向 const native_handle_t
对象的指针
typedef struct native_handle { int version; /* sizeof(native_handle_t) */ int numFds; /* number of file descriptors at &data[0] */ int numInts; /* number of ints at &data[numFds] */ int data[0]; /* numFds + numInts ints */ } native_handle_t;
Server端封装
handle bufferHandle; native_handle_t* const nativeHandle = native_handle_create(1, 0); nativeHandle->data[0] = buf->GetShareFd(); bufferHandle.setTo(nativeHandle, true); // bufferHandle 是一个hidl_handle 对象
Client 处理
从hidl_handle 中获取native_handle_t,得到shred fd ,mmap后得到虚拟地址
const native_handle_t* bufferHandle = bufferInfo.bufferHandle.getNativeHandle(); int shareFd = dup(bufferHandle->data[0]); char *srcAddr = NULL; srcAddr = (char*)mmap(NULL, bufferInfo.size, PROT_READ | PROT_WRITE, MAP_SHARED, shareFd, 0);
默认情况下,hidl_handle
对它所封装的 native_handle_t
指针并不具备所有权。它的存在只是为了安全地存储指向 native_handle_t
的指针,以使其在 32 位和 64 位进程中均可使用。
在以下情况下,hidl_handle
会拥有它所封装的文件描述符:
setTo(native_handle_t* handle, bool
shouldOwn)
方法(将 shouldOwn
参数设为 true
)后hidl_handle
对象是通过复制其他 hidl_handle
对象的结构创建而成时hidl_handle
对象的赋值是从其他 hidl_handle
对象复制而来时hidl_handle
可提供与 native_handle_t*
对象来回的隐式和显式转换。HIDL 中 handle
类型的主要用途是通过 HIDL 接口传递文件描述符。因此,单个文件描述符由没有 int
的 native_handle_t
和单个 fd
表示。如果客户端和服务器在不同的进程中运行,RPC 实现将自动处理文件描述符,以确保这两个进程可对同一个文件执行操作。
尽管由某个进程在 hidl_handle
中接收的文件描述符在该进程中有效,但它在超出接收函数范围后不会持续存在(它将在该函数返回后关闭)。想要持续访问文件描述符,进程必须对封装的文件描述符执行 dup()
操作,或复制整个 hidl_handle
对象。