【OpenHarmony】communication_ipc模块

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)、hilogaccess_tokenhitracesamgr、DSoftBus

1.3 设计思路与模式

设计思路:

  1. 抽象传输层(Strategy 模式):IRemoteInvoker 作为传输策略接口,将 Binder(本地)与 Databus(跨设备)两条传输路径统一屏蔽,上层调用者无需感知底层机制。

  2. 代理/存根分离(Proxy-Stub 模式): 客户端持有 IRemoteProxy<T>,服务端实现 IRemoteStub<T>,二者共同实现 IRemoteBroker 接口,保证类型安全的双端对称设计。

  3. 静态注册(Registry/Delegator 模式): 通过 BrokerDelegator<T> 在编译期将代理工厂函数注册到 BrokerRegistration 单例,避免运行时反射开销。

  4. 线程隔离(Thread-Local Storage): 每个线程通过 IPCThreadSkeleton 持有独立的 Invoker 实例,消除跨线程锁竞争。

  5. 延迟协商(Lazy Protocol Negotiation): 代理对象默认采用 Binder 协议,首次跨设备调用时触发异步协商,切换到 Databus 传输,避免对本地通信的性能影响。

设计模式一览:

设计模式 应用位置 目的
Proxy-Stub IRemoteProxy<T> / IRemoteStub<T> 解耦客户端与服务端实现
Strategy IRemoteInvokerBinderInvoker / 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_objectbinder_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 版骨架:JoinWorkThreadSendRequest
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 中的动态分配基址
相关推荐
Coisinier4 小时前
RHCE中shell脚本基础(磁盘剩余空间监控,Web 服务状态检查,curl 访问 Web 服务并返回状态)
linux·运维·服务器·前端·nginx·操作系统
小宇子2B1 天前
free 完再 malloc 同样大小,为什么常拿回刚还回去的那块?
操作系统
触底反弹3 天前
拷个 .exe 到新电脑就跑不起来?你缺的不是文件,是对链接的理解
c++·windows·操作系统
杊页3 天前
第一板块:Android 系统基石与运行原理 | 第二篇:Android 编译、打包与安装机制
android·操作系统
壮Sir不壮3 天前
GO语言——GMP调度模型
linux·开发语言·golang·go·操作系统·线程·协程
Surest3 天前
OpenHarmony 技术拆解(二):从 capability 看懂分布式软总线与任务迁移
操作系统
OpenAnolis小助手4 天前
如何利用 AI Agent 实现热补丁的自动化生成
人工智能·安全·ai·操作系统·agent·龙蜥
小宇子2B5 天前
缺页中断不是“出错”,是内核最忙的一条正常路径
操作系统
小宇子2B5 天前
内存不够时,内核怎么把"冷"页踢出去——swap 与页面回收
操作系统