communication_ipc 模块
1. 模块概述
https://gitee.com/openharmony/communication_ipc
1.1 功能与目标
communication_ipc 是 OpenHarmony 操作系统的**进程间通信(IPC)与远程过程调用(RPC)**基础框架组件,属于 foundation/communication/ipc 子系统。
主要功能:
| 功能维度 | 描述 |
|---|---|
| 本地 IPC(Binder) | 基于 Linux Binder 驱动实现同设备进程间高效通信,支持同步/异步调用 |
| 跨设备 RPC(DSoftBus) | 基于分布式软总线(DSoftBus)实现跨网络设备的远程过程调用 |
| 序列化与反序列化 | 提供 MessageParcel/IpcIo 数据包,支持基础类型、远程对象、文件描述符、共享内存等 |
| 服务注册与发现 | 与 System Ability Manager(SAMgr)集成,支持系统服务的注册、发现和代理获取 |
| 死亡通知 | 监控远端对象的存活状态,在对象销毁时通知注册的 DeathRecipient |
| 多语言绑定 | 为 C++(native)、C(轻量/小型系统)、JS/ArkTS(NAPI)、CJ/FFI、Rust 提供统一 IPC 能力 |
| 大数据传输 | 通过共享内存(Ashmem)支持最大 128MB 的大数据块传输 |
| DFX 诊断 | 内置 IPC 调用统计、HiTrace 分布式链路追踪、冻结管理等诊断能力 |
使用场景:
- 应用层与系统服务(SA)之间的通信
- 多个系统服务之间的相互调用
- 分布式应用在多设备间的 RPC 通信
- NDK 应用通过 C API 访问 IPC 能力
1.2 系统位置
┌─────────────────────────────────────────────────────────┐
│ 应用层 / JS层 │
│ @ohos.rpc | ArkTS ANI | CJ FFI | Rust Bindings │
└────────────────────────┬────────────────────────────────┘
│ Public API
┌────────────────────────▼────────────────────────────────┐
│ communication_ipc (本文档模块) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ interfaces/innerkits/ipc_core (C++ 公共接口层) │ │
│ ├──────────────────────────────────────────────────┤ │
│ │ ipc/native/src/core (核心实现层) │ │
│ │ ├── framework/ (骨架、对象、Parcel、线程) │ │
│ │ ├── invoker/ (Binder驱动交互层) │ │
│ │ └── dbinder/ (Databus 传输适配层) │ │
│ ├──────────────────────────────────────────────────┤ │
│ │ dbinder/dbinder_service (跨设备协商服务) │ │
│ └──────────────────────────────────────────────────┘ │
└────────────┬──────────────────────┬─────────────────────┘
│ │
┌───────▼──────┐ ┌─────────▼──────────┐
│ Linux Binder │ │ DSoftBus (RPC) │
│ /dev/binder │ │ 分布式软总线组件 │
└──────────────┘ └────────────────────┘
│ │
┌───────▼──────────────────────▼──────────┐
│ 系统内核 / 硬件网络层 │
└─────────────────────────────────────────┘
模块属性: 核心基础设施模块
依赖关系:
- 上层依赖方: 所有系统服务(SA)、应用进程、HiChain、DM(设备管理)等
- 下层依赖项:
c_utils(RefBase/Parcel)、hilog、access_token、hitrace、samgr、DSoftBus
1.3 设计思路与模式
设计思路:
-
抽象传输层(Strategy 模式): 以
IRemoteInvoker作为传输策略接口,将 Binder(本地)与 Databus(跨设备)两条传输路径统一屏蔽,上层调用者无需感知底层机制。 -
代理/存根分离(Proxy-Stub 模式): 客户端持有
IRemoteProxy<T>,服务端实现IRemoteStub<T>,二者共同实现IRemoteBroker接口,保证类型安全的双端对称设计。 -
静态注册(Registry/Delegator 模式): 通过
BrokerDelegator<T>在编译期将代理工厂函数注册到BrokerRegistration单例,避免运行时反射开销。 -
线程隔离(Thread-Local Storage): 每个线程通过
IPCThreadSkeleton持有独立的 Invoker 实例,消除跨线程锁竞争。 -
延迟协商(Lazy Protocol Negotiation): 代理对象默认采用 Binder 协议,首次跨设备调用时触发异步协商,切换到 Databus 传输,避免对本地通信的性能影响。
设计模式一览:
| 设计模式 | 应用位置 | 目的 |
|---|---|---|
| Proxy-Stub | IRemoteProxy<T> / IRemoteStub<T> |
解耦客户端与服务端实现 |
| Strategy | IRemoteInvoker → BinderInvoker / DBinderDatabusInvoker |
可插拔传输策略 |
| Singleton | ProcessSkeleton, IPCProcessSkeleton, DBinderService |
唯一进程级状态管理 |
| Abstract Factory | InvokerFactory + InvokerDelegator<T> |
按协议类型创建 Invoker |
| Registry | BrokerRegistration (descriptor → 工厂函数) |
接口描述符到代理工厂的映射 |
| Template Method | DBinderBaseInvoker<T> |
统一 RPC 发送/接收框架 |
| Observer | IRemoteObject::DeathRecipient |
远端对象死亡通知 |
| Object Pool | IPCWorkThreadPool |
可复用 IPC 工作线程 |
| Facade | IPCSkeleton |
简化线程/Invoker 内部接口 |
| RAII | CrashObjDumper |
DFX 崩溃上下文自动清理 |
1.4 系统框图
┌──────────────────────────────────────────────────────────────────────┐
│ 外部调用者层 │
│ ┌────────────┐ ┌────────────┐ ┌──────────┐ ┌─────────────────┐ │
│ │ System SA │ │ JS NAPI │ │ NDK C │ │ CJ/Rust Bind. │ │
│ │ (C++ App) │ │ @ohos.rpc │ │ ipc_capi │ │ │ │
│ └─────┬──────┘ └─────┬──────┘ └────┬─────┘ └────────┬────────┘ │
└────────┼───────────────┼──────────────┼─────────────────┼───────────┘
│ │ │ │
└───────────────┴──────────────┴──────────────────┘
│
┌──────────────▼──────────────────┐
│ interfaces/innerkits/ipc_core │
│ IRemoteObject / IRemoteBroker │
│ IRemoteProxy<T> / IRemoteStub<T> │
│ MessageParcel / MessageOption │
│ IPCSkeleton │
└──────────────┬──────────────────┘
│
┌─────────────────────────┼──────────────────────┐
│ │ │
┌──────────▼──────────┐ ┌───────────▼──────────┐ ┌───────▼─────────┐
│ framework/ │ │ invoker/ │ │ dbinder/ │
│ ProcessSkeleton │ │ IRemoteInvoker │ │ DBinderBase │
│ IPCProcessSkeleton │ │ BinderInvoker │ │ Invoker<T> │
│ IPCObjectStub │ │ BinderConnector │ │ DBinderDatabus │
│ IPCObjectProxy │ │ InvokerFactory │ │ Invoker │
│ IPCWorkThreadPool │ │ InvokerRawData │ │ DBinderSession │
└──────────────────────┘ └───────────┬───────────┘ └───────┬─────────┘
│ │
┌──────────▼──────┐ ┌──────────▼──────────┐
│ Linux Binder │ │ dbinder_service/ │
│ /dev/binder │ │ DBinderService │
│ (ioctl BINDER_ │ │ DBinderRemote │
│ WRITE_READ) │ │ Listener │
└─────────────────┘ └──────────┬──────────┘
│
┌──────────▼──────────┐
│ DSoftBus / 分布式 │
│ 软总线网络层 │
└─────────────────────┘
2. 模块结构
2.1 源文件与头文件
公共接口层 --- interfaces/innerkits/ipc_core/include/
| 文件 | 类型 | 功能描述 |
|---|---|---|
iremote_object.h |
头文件 | 定义 IRemoteObject 基类,包含 DeathRecipient、协议枚举、SendRequest 虚接口 |
iremote_broker.h |
头文件 | 定义 IRemoteBroker 接口和 BrokerDelegator<T> 静态注册机制,提供 iface_cast<>() 模板函数 |
iremote_stub.h |
头文件 | 定义 IRemoteStub<T> 模板类,服务端实现基类 |
iremote_proxy.h |
头文件 | 定义 IRemoteProxy<T> 模板类,客户端代理基类 |
message_parcel.h |
头文件 | 定义 MessageParcel 序列化容器,支持基本类型、FD、Ashmem、原始数据 |
message_option.h |
头文件 | 定义 MessageOption,控制同步/异步/等待时间等传输标志 |
ipc_skeleton.h |
头文件 | 定义 IPCSkeleton facade,暴露线程池管理、调用方身份查询等静态接口 |
ipc_types.h |
头文件 | 定义所有事务码、错误码宏和枚举 |
ipc_object_stub.h |
头文件 | 定义 IPCObjectStub(服务端核心),处理 DBinder 内部事务 |
ipc_object_proxy.h |
头文件 | 定义 IPCObjectProxy(客户端核心),管理协议协商和死亡通知 |
peer_holder.h |
头文件 | 定义 PeerHolder,带魔数校验的代理对象持有者 |
ipc_file_descriptor.h |
头文件 | 定义 IPCFileDescriptor,FD 的 Parcelable 封装 |
ipc_payload_statistics.h |
头文件 | 定义 IPCPayloadStatistics,IPC 调用 DFX 统计接口 |
核心框架层 --- ipc/native/src/core/framework/
| 文件 | 类型 | 功能描述 |
|---|---|---|
process_skeleton.h/cpp |
头/源 | 进程级单例:对象注册表、代理限额、Invoker 进程信息 |
ipc_process_skeleton.h/cpp |
头/源 | 完整进程状态管理:对象映射、会话、身份验证、原始数据、线程池状态 |
ipc_thread_skeleton.h/cpp |
头/源 | 线程本地 Invoker 数组、线程状态(TLS)管理 |
ipc_thread_pool.h/cpp |
头/源 | 工作线程池:线程命名、空闲跟踪、按需生成/销毁 |
ipc_workthread.h/cpp |
头/源 | 工作线程入口,进入 binder/databus 的 JoinThread 循环 |
ipc_object_stub.cpp |
源 | 核心分发枢纽 :按事务码路由内部操作与用户 OnRemoteRequest |
ipc_object_proxy.cpp |
源 | 代理端 SendRequest、协议协商(UpdateProto)、死亡接收者管理 |
message_parcel.cpp |
源 | 完整序列化实现:远端对象、FD、Ashmem(128MB)、接口令牌 |
ipc_skeleton.cpp |
源 | 委托到 IPCThreadSkeleton/BinderInvoker 的 facade 实现 |
ipc_payload_statistics_impl.h/cpp |
头/源 | IPC 调用计数/计时统计实现 |
sys_binder.h |
头文件 | Linux Binder UAPI 完整定义:flat_binder_object、binder_transaction_data、ioctl 命令 |
buffer_object.h/cpp |
头/源 | 事务缓冲区生命周期管理 |
comm_auth_info.h/cpp |
头/源 | 跨设备身份验证元数据记录 |
Invoker 层 --- ipc/native/src/core/invoker/
| 文件 | 类型 | 功能描述 |
|---|---|---|
iremote_invoker.h |
头文件 | IRemoteInvoker 抽象接口:传输策略的统一抽象 |
binder_invoker.h/cpp |
头/源 | Binder 主状态机 :TransactWithDriver → HandleCommands → OnTransaction/OnReply |
binder_connector.h/cpp |
头/源 | 打开 /dev/binder,封装 ioctl(BINDER_WRITE_READ) 底层循环 |
invoker_factory.h/cpp |
头/源 | 协议类型 → Invoker 实例工厂(注册 Binder 和 Databus Invoker) |
invoker_rawdata.h/cpp |
头/源 | 大载荷原始数据带外传输(用于 RPC socket 大包) |
hitrace_invoker.h/cpp |
头/源 | HiTrace 分布式追踪链路在 IPC/RPC 跨进程间的传播 |
DBinder 传输层 --- ipc/native/src/core/dbinder/
| 文件 | 类型 | 功能描述 |
|---|---|---|
dbinder_databus_invoker.h/cpp |
头/源 | DBinderDatabusInvoker:基于 SoftBus Socket 的发送/接收实现 |
dbinder_base_invoker_interface.h |
头文件 | DBinderBaseInvoker<T> 模板:统一 RPC 发送/接收算法骨架 |
dbinder_session_object.h/cpp |
头/源 | 每个会话的状态:socket fd、序列号、缓冲区 |
dbinder_softbus_client.h/cpp |
头/源 | SoftBus CreateSessionServer/OpenSession/QoS 配置 |
databus_socket_listener.h/cpp |
头/源 | Socket accept/read 回调,将字节流派发到 Invoker |
dbinder_callback_stub.h/cpp |
头/源 | 反向 RPC 通知的回调存根 |
DBinder 服务层 --- dbinder/dbinder_service/
| 文件 | 类型 | 功能描述 |
|---|---|---|
dbinder_service.h/cpp |
头/源 | 单例服务:MakeRemoteBinder、代理注册、异步消息队列、SA 加载回调、设备/服务死亡通知 |
dbinder_service_stub.h/cpp |
头/源 | 每个远端存根的协商状态机,ProcessProto,序列化 |
dbinder_remote_listener.h/cpp |
头/源 | SoftBus socket 服务端/客户端,SendDataToRemote,每设备锁 |
dbinder_death_recipient.h/cpp |
头/源 | 死亡通知转发 |
dbinder_sa_death_recipient.h/cpp |
头/源 | SA 专用死亡处理 |
C 轻量层 --- ipc/native/c/ + interfaces/innerkits/c/
| 文件/目录 | 描述 |
|---|---|
manager/src/ipc_skeleton.c |
C 版骨架:JoinWorkThread、SendRequest |
manager/src/serializer.c |
IpcIo 序列化器(镜像 C++ Parcel) |
rpc/src/dbinder_invoker.c |
C 版 DBinder Invoker |
rpc/src/rpc_softbus_trans.c |
SoftBus 传输适配器(C 层) |
ipc/src/linux/ipc_invoker.c |
Linux Binder Invoker(C 层) |
ipc/src/liteos_*/ipc_invoker.c |
LiteOS-A/M IPC Invoker 变体 |
2.2 类与结构体
继承体系
RefBase (c_utils)
└── IRemoteObject (iremote_object.h)
├── IPCObjectStub (ipc_object_stub.h) ← 服务端对象
│ └── IRemoteStub<T> ← 具体服务实现
└── IPCObjectProxy (ipc_object_proxy.h) ← 客户端代理对象
IRemoteBroker (iremote_broker.h) ← 业务接口定义
├── IRemoteProxy<T> (同时继承 PeerHolder) ← 客户端实现
└── IRemoteStub<T> (同时继承 IPCObjectStub) ← 服务端实现
IRemoteInvoker (iremote_invoker.h) ← 传输策略接口
├── BinderInvoker ← Binder 传输
└── DBinderDatabusInvoker ← Databus 传输
└── DBinderBaseInvoker<T> ← 模板基类
核心类详细描述
IRemoteObject
cpp
class IRemoteObject : public Parcelable, public RefBase {
// 核心虚接口
virtual int SendRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) = 0;
virtual bool AddDeathRecipient(const sptr<DeathRecipient> &recipient) = 0;
virtual bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient) = 0;
virtual bool IsProxyObject() const = 0;
// 成员
std::u16string descriptor_; // 接口描述符(唯一标识)
};
IPCObjectStub --- 服务端核心分发器
cpp
class IPCObjectStub : public IRemoteObject {
// 内部事务码路由(DBinder Ping, Session, Inc/Dec Refs, Auth, Dump)
int OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option);
// 串行化调用锁(防止并发覆盖)
std::mutex serialInvokeMutex_;
// 死亡接收者列表
std::vector<sptr<IRemoteObject::DeathRecipient>> deathRecipients_;
};
IPCObjectProxy --- 客户端代理核心
cpp
class IPCObjectProxy : public IRemoteObject {
// 发送请求(自动选择本地 Binder 或 Databus 路径)
int SendRequest(uint32_t code, ...);
// 协议协商:默认 Binder → 切换 Databus
void UpdateProto(int32_t proto);
// 会话名查询(通过 Binder 内部事务获取 Databus 会话名)
std::string GetSessionName() const;
// 当前协议
int32_t proto_; // IF_PROT_BINDER 或 IF_PROT_DATABUS
};
ProcessSkeleton --- 进程级单例
cpp
class ProcessSkeleton {
static ProcessSkeleton* GetInstance();
// 对象注册表:handle → IRemoteObject*
std::unordered_map<uint32_t, IRemoteObject*> objects_;
// 代理数量限额(防止代理泄漏)
uint32_t maxWorkThread_ = 16;
std::mutex mutex_;
};
BinderInvoker --- Binder 驱动状态机
cpp
class BinderInvoker : public IRemoteInvoker {
// 主循环:ioctl BINDER_WRITE_READ
void StartWorkLoop();
// 事务分发
int HandleCommands(uint32_t cmd);
int OnTransaction(const uint8_t *buffer, ...);
int OnReply(const uint8_t *buffer, ...);
// 底层驱动连接
BinderConnector *binderConnector_;
};
DBinderService --- 跨设备协商单例
cpp
class DBinderService {
static sptr<DBinderService> GetInstance();
// 创建远端 Binder 代理
sptr<DBinderServiceStub> MakeRemoteBinder(
const std::u16string &serviceName,
const std::string &deviceId,
int32_t binderObject, uint64_t tokenId);
// 协商异步消息队列
std::queue<std::shared_ptr<struct DHandleEntryTxRx>> threadMsgQueue_;
};
关键结构体
| 结构体 | 所在文件 | 描述 |
|---|---|---|
flat_binder_object |
sys_binder.h |
Binder 对象在内核传输中的扁平化表示 |
binder_transaction_data |
sys_binder.h |
事务数据帧:缓冲区指针、大小、目标句柄、代码、flags |
DHandleEntryTxRx |
dbinder_service.h |
DBinder 跨设备协商报文(握手/应答/死亡通知) |
SessionInfo |
dbinder_service.h |
跨设备会话的完整描述:设备ID、服务名、socket句柄 |
ThreadMessageInfo |
ipc_process_skeleton.h |
线程同步等待结构体(条件变量 + 消息指针) |
AppAuthInfo |
ipc_process_skeleton.h |
跨设备调用的应用身份验证信息 |
InvokerProcInfo |
process_skeleton.h |
Invoker 进程信息:PID、UID、Token |
FlatDBinderSession |
dbinder_session_object.h |
DBinder 会话的扁平化可序列化描述 |
DBinderNegotiationData |
ipc_object_proxy.h |
代理协商数据:设备ID、服务名、版本 |
IpcIo |
serializer.h |
C 层序列化上下文(轻量系统使用) |
2.3 类图
┌─────────────────────────────────────────────────────────────────────┐
│ 公共接口层 │
│ │
│ ┌──────────────────┐ ┌────────────────────────────────────┐ │
│ │ <<interface>> │ │ IRemoteObject │ │
│ │ IRemoteBroker │ │ + SendRequest() = 0 │ │
│ │ + AsObject()=0 │ │ + AddDeathRecipient() = 0 │ │
│ └────────┬─────────┘ │ + IsProxyObject() = 0 │ │
│ │ implements │ + descriptor_: u16string │ │
│ ┌────────▼─────────────────────────────────────────────────┐ │ │
│ │ INTERFACE (用户定义接口 T) │ │ │
│ └────────────┬──────────────────────────────┬──────────────┘ │ │
│ │ extends │ extends │ │
│ ┌────────────▼──────────┐ ┌───────────────▼─────────────┐ │ │
│ │ IRemoteProxy<T> │ │ IRemoteStub<T> │ │ │
│ │ + AsObject() │ │ + AsObject() │ │ │
│ │ ───────────────── │ │ + AsInterface() │ │ │
│ │ IPCObjectProxy │ │ ───────────────── │ │ │
│ │ + SendRequest() │ │ IPCObjectStub │ │ │
│ │ + UpdateProto() │ │ + OnRemoteRequest() │ │ │
│ │ + proto_: int32_t │ │ + deathRecipients_ │ │ │
│ └───────────────────────┘ └──────────────────────────────┘ │ │
└─────────────────────────────────────────────────────────────────┘ │
│
┌───────────────────────────────────────────────────────────────────────┤
│ 传输 Invoker 层 │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ IRemoteInvoker (抽象接口) │ │
│ │ + SendRequest() + OnTransaction() + JoinThread() │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ ↑ extends ↑ extends │
│ ┌────────┴──────────────┐ ┌────────────┴────────────────────┐ │
│ │ BinderInvoker │ │ DBinderDatabusInvoker │ │
│ │ + StartWorkLoop() │ │ extends DBinderBaseInvoker<T> │ │
│ │ + HandleCommands() │ │ + OnTransaction() │ │
│ │ + OnReply() │ │ + FindOrNewSession() │ │
│ │ * BinderConnector │ │ * DBinderSoftbusClient │ │
│ └───────────────────────┘ └──────────────────────────────────┘ │
│ |使用 |使用 │
│ ┌────────▼──────────────┐ ┌────────▼──────────────────────┐ │
│ │ BinderConnector │ │ DBinderSoftbusClient │ │
│ │ + OpenDriver() │ │ + OpenSoftbusSession() │ │
│ │ + ioctl(BINDER_*) │ │ + SendBytes() │ │
│ └───────────────────────┘ └───────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
2.4 模块内部依赖框图
interfaces/innerkits/ipc_core (公共API)
│ 依赖
▼
ipc/native/src/core/framework (框架层)
├── ProcessSkeleton ← 单例,提供对象注册表
├── IPCProcessSkeleton ← 单例,进程完整状态
├── IPCThreadSkeleton ← 每线程 TLS 状态
├── IPCWorkThreadPool ← 线程池管理
├── IPCObjectStub ← 依赖 ProcessSkeleton
├── IPCObjectProxy ← 依赖 ProcessSkeleton + Invoker
└── MessageParcel ← 依赖 c_utils::Parcel
│ 依赖
▼
ipc/native/src/core/invoker (传输策略)
├── IRemoteInvoker (接口)
├── BinderInvoker ──────────── 依赖 BinderConnector
├── BinderConnector ─────────── 直接访问 /dev/binder
├── InvokerFactory (注册表)
└── HitraceInvoker (装饰器)
│ 依赖(跨设备时)
▼
ipc/native/src/core/dbinder (DBinder传输)
├── DBinderBaseInvoker<T>
├── DBinderDatabusInvoker ─── 依赖 DBinderSoftbusClient
├── DBinderSessionObject ──── 依赖 DSoftBus session API
├── DatabusSocketListener ─── 依赖 DSoftBus socket API
└── DBinderCallbackStub
│ 依赖
▼
dbinder/dbinder_service (跨设备协商)
├── DBinderService (单例) ─── 依赖 SAMgr
├── DBinderServiceStub ────── 依赖 DBinderService
└── DBinderRemoteListener ─── 依赖 DSoftBus socket API
3. 模块间交互
3.1 交互描述
与 System Ability Manager (SAMgr) 的交互
IPC 模块通过 RpcSystemAbilityCallback 接口与 SAMgr 集成。当跨设备 RPC 请求到达时,DBinderService 调用 SAMgr 加载目标系统服务(SA),获取到本地 stub 的句柄后,将其封装为可跨设备访问的 DBinder 代理返回给请求方。
远端设备 ──[DSoftBus]──► DBinderService::MakeRemoteBinder()
│
├──► SAMgr::LoadSystemAbility() (加载目标SA)
│ │
│ ▼
│ 目标 SA 进程启动
│ │
└──► DBinderServiceStub 注册 (绑定本地binder)
与 DSoftBus 的交互
跨设备 RPC 通过 dl_deps/dsoftbus_interface.h 声明的 SoftBus API 进行交互(运行时动态链接,避免编译期硬依赖):
Socket()/Bind()/Listen()--- 建立 SoftBus socket 连接SendBytes()--- 发送序列化数据帧SetFirstCallerTokenID()--- 传递调用方 Token 用于鉴权QosTV--- 配置服务质量(时延、带宽、可靠性)OnBytesReceived/OnShutdown/OnError--- 接收回调
与 Linux Binder 驱动的交互
c
// BinderConnector 底层交互示意
fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
mmap(NULL, MMAP_MAX_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); // 映射共享缓冲区
// 事务循环
while (running) {
binder_write_read bwr = { ... }; // 填充读写缓冲区
ioctl(fd, BINDER_WRITE_READ, &bwr);
// 处理返回命令:BR_TRANSACTION / BR_REPLY / BR_DEAD_BINDER / ...
}
异步处理与事件驱动机制
| 机制 | 描述 |
|---|---|
| TF_ASYNC flag | MessageOption 中设置 TF_ASYNC,请求方无需等待回复,Stub 端异步处理 |
| DBinder 异步消息队列 | DBinderService 内部维护 threadMsgQueue_,单独线程处理跨设备协商消息 |
| 死亡通知 | BR_DEAD_BINDER 命令由 Binder 驱动异步投递,DeathRecipient::OnRemoteDied() 在工作线程回调 |
| Socket 数据回调 | DatabusSocketListener::OnBytesReceived 在 SoftBus IO 线程触发,派发到 IPC 数据处理线程 |
| FFRT 可选集成 | 通过 resourceschedule_ffrt_support 特性标志,可将 IPC 工作线程调度委托给 FFRT 协程框架 |
多线程处理方式
主线程/App线程
│
├─── IPCWorkThreadPool (默认最多16个Binder工作线程)
│ 每线程: BinderInvoker::StartWorkLoop()
│ ioctl(BINDER_WRITE_READ) 阻塞等待内核派发
│
├─── Socket IO 线程 (DSoftBus callback线程)
│ DatabusSocketListener 回调
│ → 投递到数据处理线程队列
│
├─── 数据处理线程 (RPC 消息分发)
│ DBinderBaseInvoker::OnTransaction
│ → 调用目标 Stub 的 OnRemoteRequest
│
├─── DBinder 协商线程 (DBinderService内部)
│ 处理 DHandleEntryTxRx 异步消息
│
└─── 每线程 TLS: IPCThreadSkeleton
invokers_[2]: { BinderInvoker, DBinderDatabusInvoker }
同步原语:
| 类型 | 用途 |
|---|---|
std::mutex |
对象注册表、会话映射、死亡接收者列表的保护 |
std::shared_mutex |
高读低写场景的读写锁(如代理句柄映射) |
std::condition_variable |
同步 IPC 调用等待回复(ThreadMessageInfo) |
pthread_mutex_t/cond_t |
C 层对应原语 |
3.2 外部依赖框图
┌─────────────────────────────────────────────────────────────────┐
│ communication_ipc │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 核心 C++ 层 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │ │ │ │ │
└───────┼─────────────┼────────────┼────────────┼────────┼────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────┐ ┌──────────┐
│ c_utils │ │ hilog │ │hitrace │ │samgr │ │ napi │
│ RefBase │ │ HiLog │ │HiTrace │ │SAMgr │ │ NAPI │
│ Parcel │ │ Logging │ │Tracing │ │SA注册│ │ JS绑定 │
└──────────┘ └──────────┘ └─────────┘ └──────┘ └──────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌─────────────────────────────────┐
│ access_ │ │ ffrt │ │ DSoftBus (动态链接) │
│ token │ │ FFRT │ │ dl_deps/dsoftbus_interface.h │
│ Token鉴权│ │ 协程调度 │ │ Socket/Session/BusCenter API │
└──────────┘ └──────────┘ └─────────────────────────────────┘
│
┌──────────────────────────────────▼──────────────────┐
│ 操作系统/内核层 │
│ /dev/binder (Linux) /dev/lite_ipc (LiteOS-A) │
│ 网络协议栈 pthread mmap ioctl │
└─────────────────────────────────────────────────────┘
4. 状态机转换图
4.1 Binder 驱动命令状态机
这是 IPC 框架的核心状态机,运行在 BinderInvoker 的每个工作线程中。
状态机树图(层次结构):
Binder工作线程状态机
├── IDLE (空闲等待)
│ 条件: ioctl 阻塞,等待内核唤醒
│
├── READING (读取内核命令)
│ 条件: ioctl 返回,解析 BR_* 命令
│ ├── BR_TRANSACTION (收到事务请求)
│ │ └── DISPATCHING (分发请求)
│ │ ├── INVOKING_USER (调用用户 OnRemoteRequest)
│ │ │ └── SENDING_REPLY (发送 BC_REPLY)
│ │ └── INVOKING_INTERNAL (处理 DBinder 内部事务)
│ │ └── SENDING_REPLY
│ ├── BR_REPLY (收到同步回复)
│ │ └── WAKING_CALLER (唤醒等待的调用线程)
│ ├── BR_DEAD_BINDER (远端对象死亡通知)
│ │ └── NOTIFYING_DEATH (调用 DeathRecipient::OnRemoteDied)
│ ├── BR_SPAWN_LOOPER (内核请求新增工作线程)
│ │ └── SPAWNING_THREAD (创建新 IPC 工作线程)
│ ├── BR_FAILED_REPLY / BR_DEAD_REPLY (事务失败)
│ │ └── RETURNING_ERROR (向调用方返回错误码)
│ └── BR_FINISHED (线程退出信号)
│ └── TERMINATED
│
└── WRITING (向内核写入命令)
├── BC_TRANSACTION (发起事务)
├── BC_REPLY (回复事务)
├── BC_ACQUIRE / BC_RELEASE (引用计数操作)
└── BC_REGISTER_LOOPER / BC_ENTER_LOOPER
状态机转换图:
┌──────────────────────────────────────────┐
│ IDLE(ioctl阻塞) │
└──────────────────────┬───────────────────┘
│ 内核唤醒
┌──────────────────────▼───────────────────┐
│ READING(解析BR_*命令) │
└──┬────────────┬────────────┬─────────────┘
│ │ │
BR_TRANSACTION BR_REPLY BR_DEAD_BINDER
│ │ │
┌──────────▼──┐ ┌──────▼──┐ ┌─────▼──────────┐
│ DISPATCHING │ │ UNBLOCK │ │ DEATH_NOTIFY │
│ 分发请求 │ │ 唤醒调用 │ │ 触发DeathRecip.│
└──────┬──────┘ └─────────┘ └────────────────┘
│
┌──────────┴───────────┐
用户请求 内部请求
│ │
┌───────▼──────────┐ ┌───────▼──────────┐
│ INVOKING_USER │ │ INVOKING_INTERNAL │
│ OnRemoteRequest │ │ DBinder ping/ │
│ (用户实现) │ │ session/ref等 │
└───────┬──────────┘ └───────┬──────────┘
│ │
└──────────┬───────────┘
│
┌─────────▼─────────┐
│ SENDING_REPLY │
│ BC_REPLY写内核 │
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ IDLE │◄── 循环回到空闲
└───────────────────┘
4.2 DBinder 协商状态机
负责跨设备 RPC 代理的建立过程,位于 DBinderServiceStub 中。
状态机树图:
DBinder 协商状态机
├── NEGO_INIT (初始未协商)
│ 触发条件: MakeRemoteBinder() 被调用
│
├── NEGO_DOING (协商进行中)
│ 触发条件: 收到 DBINDER_ADD_COMMAUTH 报文
│ 子状态:
│ ├── SENDING_AUTH (发送身份验证数据)
│ ├── WAITING_SESSION (等待 SoftBus Session 建立)
│ └── REGISTERING_SA (请求 SAMgr 加载目标SA)
│
└── NEGO_FINISHED (协商完成)
触发条件: Session 成功建立,SA 加载完成
后续: DBinderServiceStub 可正常转发 RPC 请求
状态机转换图:
┌──────────────────────────────────────────────────────────────┐
│ NEGO_INIT │
│ (未协商,初始状态) │
└───────────────────────┬──────────────────────────────────────┘
│ MakeRemoteBinder() + 收到协商请求报文
│ [条件: 有效的 deviceId + serviceName]
┌───────────────────────▼──────────────────────────────────────┐
│ NEGO_DOING │
│ (协商进行中) │
│ │
│ SENDING_AUTH ──► WAITING_SESSION ──► REGISTERING_SA │
└───────────────────────┬──────────────────────────────────────┘
│ Session建立成功 + SA加载完成
│ [条件: SoftBus OnSessionOpened 回调]
┌───────────────────────▼──────────────────────────────────────┐
│ NEGO_FINISHED │
│ (协商完成,可正常转发) │
└──────────────────────────────────────────────────────────────┘
│ 设备断线/SA死亡
▼
┌───────────────────┐
│ NEGO_INIT │ (回到初始状态,需重新协商)
└───────────────────┘
4.3 代理协议选择状态机
IPCObjectProxy 中的传输协议选择状态机:
┌─────────────────────────────┐
│ IF_PROT_BINDER (默认) │
│ 本地 Binder 传输 │
└─────────────┬───────────────┘
│ 检测到目标在远端设备
│ [条件: IsObjectDead() +
│ GetSessionName()返回非空]
┌─────────────▼───────────────┐
│ IF_PROT_DATABUS │
│ SoftBus Socket 传输 │
└─────────────┬───────────────┘
│ 会话断开/设备离线
▼
┌─────────────────────────────┐
│ IF_PROT_ERROR │
│ 连接失败,返回错误 │
└─────────────────────────────┘
4.4 线程调用状态机
IPCThreadSkeleton 中的线程调用状态:
┌──────────────────────────────────┐
│ STATUS_INIT (线程初始状态) │
└──────────────┬───────────────────┘
│ 首次收到 SendRequest
┌──────────────▼───────────────────┐
│ STATUS_FIRST_INVOKE (首次调用) │
│ 允许进入可重入 IPC 调用 │
└──────────────┬───────────────────┘
│ 调用返回后继续接收请求
┌──────────────▼───────────────────┐
│ STATUS_NOT_FIRST_INVOKE (非首次) │
│ 已在 IPC 调用栈中,允许嵌套 │
└──────────────────────────────────┘
5. 接口设计
5.1 公共接口
IRemoteObject::SendRequest --- 发起IPC请求
cpp
/**
* @brief 向远端对象发送事务请求
* @param code 事务码(由业务接口定义,uint32_t)
* @param data 请求数据(序列化的 MessageParcel)
* @param reply 响应数据(由 Stub 填充,同步模式下有效)
* @param option 传输选项(同步/异步/等待时间等)
* @return ERR_NONE(0) 表示成功;负值表示错误码
* ERR_DEAD_OBJECT: 远端对象已销毁
* ERR_INVALID_DATA: 数据序列化失败
* IPC_STUB_ERR: Stub 侧处理错误
* @note 同步调用时,调用线程阻塞直到 Stub 回复或超时(默认等待时间由TF_WAIT_TIME控制)
*/
virtual int SendRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) = 0;
IPCSkeleton --- 进程/线程管理接口
cpp
class IPCSkeleton {
public:
// 加入工作线程池(当前线程成为 IPC 服务线程)
static bool JoinWorkThread();
// 停止工作线程
static bool StopWorkThread();
// 设置最大工作线程数(默认16)
static bool SetMaxWorkThreadNum(int maxThreadNum);
// 获取调用方信息(在 OnRemoteRequest 中调用有效)
static pid_t GetCallingPid(); // 调用方进程ID
static pid_t GetCallingUid(); // 调用方用户ID
static uint64_t GetCallingTokenID();// 调用方访问令牌
static std::string GetCallingDeviceID(); // 调用方设备ID(跨设备RPC)
// 获取/设置本地上下文对象
static sptr<IRemoteObject> GetContextObject();
static bool SetContextObject(sptr<IRemoteObject> &object);
// 在当前线程执行一次 Binder 命令循环(非阻塞)
static bool FlushCommands(IRemoteObject *object);
};
MessageParcel --- 序列化接口
cpp
class MessageParcel : public Parcel {
public:
// 写入远端对象(自动进行 Binder/DBinder 句柄转换)
bool WriteRemoteObject(const sptr<IRemoteObject> &object);
sptr<IRemoteObject> ReadRemoteObject();
// 写入接口令牌(用于 Stub 侧验证调用者接口)
bool WriteInterfaceToken(std::u16string name);
std::u16string ReadInterfaceToken();
// 写入文件描述符(跨进程传递FD)
bool WriteFileDescriptor(int fd);
int ReadFileDescriptor();
// 写入共享内存对象(用于大数据传输)
bool WriteAshmem(sptr<Ashmem> ashmem);
sptr<Ashmem> ReadAshmem();
// 写入大块原始数据(内核映射,最大128MB)
bool WriteRawData(const void *data, size_t size);
const void *ReadRawData(size_t size);
// 追加另一个 MessageParcel 的数据
bool Append(MessageParcel &data);
static constexpr size_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // 128MB
};
IRemoteObject::DeathRecipient --- 死亡通知接口
cpp
class IRemoteObject::DeathRecipient : public RefBase {
public:
// 当持有的远端对象销毁时,在工作线程中回调
virtual void OnRemoteDied(const wptr<IRemoteObject> &object) = 0;
};
// 注册示例:
bool AddDeathRecipient(const sptr<DeathRecipient> &recipient);
bool RemoveDeathRecipient(const sptr<DeathRecipient> &recipient);
NDK C API --- ipc_cremote_object.h
c
// 创建 Stub 对象(C API)
OHIPCRemoteStub *OH_IPCRemoteStub_Create(
const char *descriptor,
OH_OnRemoteRequestCallback requestCallback,
OH_OnRemoteDestroyCallback destroyCallback,
void *userData);
// 销毁 Stub 对象
void OH_IPCRemoteStub_Destroy(OHIPCRemoteStub *stub);
// 通过 Proxy 发送请求
int OH_IPCRemoteProxy_SendRequest(
const OHIPCRemoteProxy *proxy,
uint32_t code,
const OHIPCParcel *data,
OHIPCParcel *reply,
const OH_IPC_MessageOption *option);
// 注册死亡通知
int OH_IPCRemoteProxy_AddDeathRecipient(
OHIPCRemoteProxy *proxy,
OHIPCDeathRecipient *recipient);
5.2 数据交换接口
业务接口定义规范
cpp
// 定义业务接口(继承 IRemoteBroker)
class IFooService : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.foo.IFooService");
enum {
CMD_FOO = FIRST_CALL_TRANSACTION,
CMD_BAR,
};
virtual int Foo(const std::string &input, std::string &output) = 0;
virtual int Bar(int value) = 0;
};
// Proxy 实现(客户端)
class FooServiceProxy : public IRemoteProxy<IFooService> {
public:
int Foo(const std::string &input, std::string &output) override {
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteString(input);
int ret = Remote()->SendRequest(CMD_FOO, data, reply, option);
if (ret == ERR_NONE) output = reply.ReadString();
return ret;
}
private:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.foo.IFooService");
};
// Stub 实现(服务端)
class FooServiceStub : public IRemoteStub<IFooService> {
public:
int OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) override {
if (data.ReadInterfaceToken() != GetDescriptor())
return ERR_INVALID_DATA;
switch (code) {
case CMD_FOO: {
std::string output;
int ret = Foo(data.ReadString(), output);
reply.WriteString(output);
return ret;
}
default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
};
DBinder 跨设备协商数据协议
DHandleEntryTxRx 报文格式(跨设备协商):
┌──────────────────────────────────────────────────────┐
│ DHandleEntryHead │
│ ├── len: uint32_t (报文总长度) │
│ ├── version: uint32_t (协议版本) │
│ ├── dBinderCode: uint32_t (DBINDER_ADD_COMMAUTH 等) │
│ └── fromPort/toPort: uint16_t │
│ │
│ DHandleEntryTxRx (扩展头) │
│ ├── transType: uint32_t (事务类型) │
│ ├── stubIndex: uint64_t (目标 Stub 索引) │
│ ├── binderObject: uint64_t (本地 Binder 句柄) │
│ ├── deviceIdInfo: DeviceIdInfo (设备ID信息) │
│ ├── sessionName: char[65] (DSoftBus 会话名) │
│ └── serviceName: char[256] (SA 服务名) │
└──────────────────────────────────────────────────────┘
5.3 接口调用时序图
时序1:本地 IPC 同步调用(Binder)
Client进程 IPC框架(Client侧) Binder驱动 IPC框架(Server侧) Server进程
│ │ │ │ │
│ proxy->SendRequest(code,..) │ │ │ │
│─────────────────────────────►│ │ │ │
│ │ BinderInvoker::SendRequest│ │ │
│ │ 序列化 data 到 Parcel │ │ │
│ │ BC_TRANSACTION ioctl │ │ │
│ │──────────────────────────►│ │ │
│ │ │ 内核唤醒Server工作线程 │ │
│ │ │─────────────────────────►│ │
│ │ [阻塞等待 BR_REPLY] │ │ BR_TRANSACTION │
│ │ │ │──────────────────────────►│
│ │ │ │ │ OnRemoteRequest()
│ │ │ │◄──────────────────────────│
│ │ │ │ BC_REPLY ioctl │
│ │ │◄─────────────────────────│ │
│ │ BR_REPLY 唤醒 │ │ │
│ │◄──────────────────────────│ │ │
│ 返回 ERR_NONE + reply │ │ │ │
│◄─────────────────────────────│ │ │ │
时序2:跨设备 RPC 初始化(DBinder 协商)
Client设备 DBinderService(Client) DSoftBus网络 DBinderService(Server) Server SA进程
│ │ │ │ │
│ iface_cast<IRemote>(proxy) │ │ │ │
│ proxy->SendRequest(...) │ │ │ │
│─────────────────────────────►│ │ │ │
│ │ MakeRemoteBinder() │ │ │
│ │ 触发 DBinder 协商 │ │ │
│ │ SendDataToRemote │ │ │
│ │────────────────────────►│ │ │
│ │ │ DHandleEntryTxRx包 │ │
│ │ │──────────────────────►│ │
│ │ │ │ LoadSystemAbility(SA) │
│ │ │ │────────────────────────►│
│ │ │ │◄────────────────────────│
│ │ │ │ 注册 DBinder Stub │
│ │ │ 协商完成报文 │ │
│ │◄────────────────────────│◄──────────────────────│ │
│ │ UpdateProto(DATABUS) │ │ │
│ 协商完成,后续请求走 SoftBus │ │ │ │
│◄─────────────────────────────│ │ │ │
│ │ │ │ │
│ proxy->SendRequest(...) │ │ │ │
│─────────────────────────────►│ DBinder Socket发送 │ │ │
│ │────────────────────────►│──────────────────────►│ OnTransaction() │
│ │ │ │────────────────────────►│
│ │ │ │◄────────────────────────│
│ │◄────────────────────────│◄──────────────────────│ │
│◄─────────────────────────────│ │ │ │
时序3:死亡通知
Client进程 IPCObjectProxy Binder驱动 DeathRecipient(用户实现)
│ │ │ │
│ AddDeathRecipient(recipient) │ │ │
│─────────────────────────────►│ │ │
│ │ BC_REQUEST_DEATH_NOTIFY│ │
│ │────────────────────────►│ │
│ │ │ │
│ ...Server进程崩溃... │ │ │
│ │ │ BR_DEAD_BINDER │
│ │◄────────────────────────│ │
│ │ 遍历 deathRecipients_ │ │
│ │ (在IPC工作线程中) │ │
│ │──────────────────────────────────────────────────►│
│ │ │ OnRemoteDied(object) │
│ │ │ │ 执行清理逻辑
│ │ │ │
附录
A. 错误码速查
| 错误码 | 值 | 含义 |
|---|---|---|
ERR_NONE |
0 | 成功 |
ERR_DEAD_OBJECT |
-ERR_DEAD_OBJECT | 远端对象已销毁 |
ERR_INVALID_DATA |
-ERR_INVALID_DATA | 数据无效/反序列化失败 |
IPC_STUB_ERR |
负值 | Stub 侧处理错误 |
IPC_INVOKER_ERR |
负值 | Invoker 传输错误 |
RPC_BASE_JITTER_ERR |
负值 | RPC 基础错误 |
DBINDER_SERVICE_PROCESS_PROTO_ERR |
负值 | DBinder 协议错误 |
B. 关键事务码
| 事务码 | 值 | 用途 |
|---|---|---|
PING_TRANSACTION |
'_','P','N','G' |
Binder Ping(探活) |
DUMP_TRANSACTION |
'_','D','M','P' |
转储调试信息 |
INTERFACE_TRANSACTION |
'_','N','T','F' |
查询接口描述符 |
DBINDER_INCREFS_TRANSACTION |
内部码 | DBinder 增加引用计数 |
DBINDER_DECREFS_TRANSACTION |
内部码 | DBinder 减少引用计数 |
DBINDER_ADD_COMMAUTH |
内部码 | 添加跨设备通信鉴权 |
GET_PROTO_INFO |
内部码 | 获取传输协议信息 |
INVOKE_LISTEN_THREAD |
内部码 | 触发监听线程 |
C. 约束与限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 单次事务数据上限 | ~1MB | Binder 内核缓冲区限制 |
| 大数据传输 | 最大 128MB | 通过 Ashmem 共享内存或 WriteRawData |
| 最大工作线程数 | 16(默认) | 可通过 SetMaxWorkThreadNum 调整 |
| RPC 跨设备限制 | 不支持代理对象回传 | 跨设备代理不可再作为参数传递回源设备 |
| 最大 DBinder 句柄 | 基于 0x29000000 |
IPCProcessSkeleton 中的动态分配基址 |