#打卡不停更#OHOS标准系统的IPC和RPC代码解读--1--概述 原创 精华

liangkz_梁开祝
发布于 2022-9-24 14:06
浏览
2收藏

::: hljs-center

OHOS标准系统的IPC和RPC代码解读–1–概述

梁开祝 2022.09.24
:::

本想接着前文《OHOS标准系统的SAMGR代码解读》继续分析dmsfwk组件的实现细节,但发现涉及太多的IPC/RPC的内容了,如果对OHOS的IPC/RPC没有足够的理解,很难把dmsfwk组件理解透彻,因此我花了点时间,先整理了一下IPC/RPC相关的代码和部分流程,作为理解SAMGR相关组件的预备知识。

  IPC/RPC的代码仓库,在OHOS 3.1分支上,分为ipc和ipc_lite两个仓库,在master分支上,ipc_lite仓库已经合并到ipc仓库中,因此本文在整理ipc仓库代码目录树结构时,是以当前的master分支代码为准整理的。

但由于我当前工作主要还是在OHOS 3.1分支上,所以在后面整理相关的流程图或数据结构关系图时,还是基于3.1分支代码进行的(待930版本发布后再确认是否更新到930版本)。

1.整理代码目录树结构(基于master分支)

  在Linux命令行下进入 //foundation/communication/ipc/ 目录,通过tree命令将目录树结构打印出来并重定向到文本文件中。为减少干扰,直接去除test相关的目录和文件,再酌情微调一下部分目录和文件的位置。重点阅读剩下的几个BUILD.gn文件,结合几类系统分别整理BUILD.gn中的编译目标,尽可能地挖掘有用信息(后继在深入理解代码时也可以对该目录树结构补充新的信息)。

  目前我整理出来的信息大概如下:

# 系统类型:Lite类型系统(a-LiteM、b-LiteA、c-LiteL)、STD系统

# Lite类型系统的编译目标:
#【0】shared_library("rpc_log"),LiteM系统该文件直接编译进2.1中。
#    【Lite类型系统:LOG_DOMAIN 0xD001518,LOG_TAG "IPCRPC"】
#    【 STD类型系统:ipc_debug.h、log_tags.h】
#【1】静态或动态library("rpc_adapter")【简单:RpcGetPid()/RpcGetUid()的适配】
#    【1.1】static_library("rpc_adapter"),LiteM系统依赖该库
#    【1.2】shared_library("rpc_adapter"),LiteA+LiteL小型系统依赖该库
#【2】静态或动态library("rpc_manager")
#    【2.1】static_library("rpc_manager"),LiteM系统依赖该库
#    【2.2】shared_library("rpc_manager"),LiteA编译该库为空实际不依赖,LiteL小型系统依赖该库
#【3】静态或动态library("dbinder")
#    【3.1】static_library("dbinder"),LiteM系统依赖该库
#    【3.2】shared_library("dbinder"),LiteA小型系统不依赖该库,LiteL小型系统依赖该库
#【4】shared_library("ipc_single"),LiteM系统不依赖该库,LiteA和LiteL小型系统依赖该库

# STD系统的编译目标:
#【10】ohos_shared_library("ipc_core")  【包含本地设备内的IPC,以及与dbinder相关的基础功能】
#【11】ohos_shared_library("ipc_single")【有定义CONFIG_IPC_SINGLE,完全是本地设备内的IPC】
#【12】ohos_shared_library("libdbinder")【dbinder,与RPC相关的功能实现】
#【13】ohos_shared_library("rpc")       【rpc_js接口】

# 依赖关系:
#LiteM:依赖【  1.1+2.1+3.1  】(0-直接编译到2.1中)
#LiteA:依赖【0+1.2+        4】(2-编译为空实际不依赖,3-不依赖)
#LiteL:依赖【0+1.2+2.2+3.2+4】
#STD  :依赖【10+11+12】+【13】

# 目录树结构
//foundation/communication/ipc/
├── bundle.json
├── BUILD.gn     #定义ipc_components:STD系统依赖【10+11+12】,Lite系统依赖【interfaces/innerkits/c:rpc】
├── interfaces   #接口部分,整理编译目标和依赖关系
│   ├── innerkits
│   │   │   # Lite类型系统组件
│   │   ├── c
│   │   │   ├── BUILD.gn  #Lite系统专用的组件【lite_component("rpc")】
│   │   │   │             #LiteM:依赖【  1.1+2.1+3.1  】(0-直接编译到2.1中)
│   │   │   │             #LiteA:依赖【0+1.2+        4】(2-编译为空实际不依赖,3-不依赖)
│   │   │   │             #LiteL:依赖【0+1.2+2.2+3.2+4】
│   │   │   ├── dbinder   #distributed binder for Lite
│   │   │   │   ├── BUILD.gn  #【3.1】和【3.2】
│   │   │   │   └── include/dbinder_service.h
│   │   │   └── ipc
│   │   │       ├── BUILD.gn  #【2.1】和【2.2】
│   │   │       └── include
│   │   │           ├── ipc_skeleton.h
│   │   │           ├── rpc_errno.h
│   │   │           └── serializer.h
│   │   │
│   │   │   # STD系统专用的组件【10】【11】【12】【13】
│   │   ├── ipc_core
│   │   │   ├── BUILD.gn         #【10】ohos_shared_library("ipc_core")
│   │   │   └── include
│   │   │       ├── ipc_file_descriptor.h
│   │   │       ├── ipc_object_proxy.h
│   │   │       ├── ipc_object_stub.h
│   │   │       ├── ipc_skeleton.h
│   │   │       ├── ipc_types.h
│   │   │       ├── iremote_broker.h
│   │   │       ├── iremote_object.h
│   │   │       ├── iremote_proxy.h
│   │   │       ├── iremote_stub.h
│   │   │       ├── jni_help.h
│   │   │       ├── message_option.h
│   │   │       ├── message_parcel.h
│   │   │       └── peer_holder.h
│   │   ├── ipc_single/BUILD.gn  #【11】ohos_shared_library("ipc_single") + CONFIG_IPC_SINGLE
│   │   └── libdbinder           # distributed binder for STD
│   │       ├── BUILD.gn         #【12】ohos_shared_library("libdbinder")依赖【10】
│   │       └── include
│   │           ├── dbinder_service.h
│   │           ├── dbinder_service_stub.h
│   │           └── rpc_system_ability_callback.h
│   └── kits                  
│       ├── bundle.json          # RPC napi for js
│       └── js/napi/BUILD.gn     #【13】ohos_shared_library("rpc") 依赖【10】
│
│   #工具部分【Lite类型系统在用,STD系统不用】
├── utils
│   ├── include
│   │   ├── log_tags.h           # LOG_ID_COMMUNICATION 以及子模块的LOG_ID定义
│   │   └── rpc_session_handle.h
│   └── src/rpc_session_handle.c #【a+c】
│
│   # IPC/RPC的框架实现代码
├── ipc
│   └── native
│       │   #Lite类型系统的IPC框架代码
│       ├── c
│       │   ├── adapter
│       │   │   ├── access_token
│       │   │   │   ├── include/access_token_adapter.h
│       │   │   │   └── src/access_token_adapter.c     #【STD】【只有STD系统的[10][11]编译该文件,Lite类型系统不编译】
│       │   │   ├── BUILD.gn                     #【1】单独编译 rpc_os_adapter.c 源文件
│       │   │   ├── include
│       │   │   │   ├── rpc_bytrace.h
│       │   │   │   └── rpc_os_adapter.h
│       │   │   ├── Linux/rpc_os_adapter.c       #【1.2】【b+c】
│       │   │   └── Liteos_m/rpc_os_adapter.c    #【1.1】【a】
│       │   ├── ipc
│       │   │   ├── include
│       │   │   │   ├── ipc_invoker.h
│       │   │   │   └── ipc_types.h
│       │   │   └── src
│       │   │       ├── linux
│       │   │       │   ├── include/sys_binder.h
│       │   │       │   ├── ipc_invoker.c        #【c】
│       │   │       │   └── serializer_inner.c   #【c】
│       │   │       ├── liteos_a
│       │   │       │   ├── include/lite_ipc.h
│       │   │       │   ├── ipc_invoker.c        #【b】
│       │   │       │   └── serializer_inner.c   #【b】
│       │   │       └── liteos_m
│       │   │           ├── ipc_invoker.c        #【a】
│       │   │           └── serializer_inner.c   #【a】
│       │   ├── manager
│       │   │   ├── include
│       │   │   │   ├── ipc_process_skeleton.h
│       │   │   │   ├── ipc_skeleton_pri.h
│       │   │   │   ├── ipc_thread_pool.h
│       │   │   │   ├── iremote_invoker.h
│       │   │   │   ├── rpc_log.h
│       │   │   │   ├── rpc_types.h
│       │   │   │   └── serializer_inner.h
│       │   │   └── src
│       │   │       ├── ipc_process_skeleton.c   #【a+b+c】公共部分5个文件
│       │   │       ├── ipc_skeleton.c           #【a+b+c】公共部分5个文件
│       │   │       ├── ipc_thread_pool.c        #【a+b+c】公共部分5个文件
│       │   │       ├── iremote_invoker.c        #【a+b+c】公共部分5个文件
│       │   │       ├── serializer.c             #【a+b+c】公共部分5个文件
│       │   │       └── rpc_log.c                #【a】编译在【2.1】,【b+c】LiteA+LiteL单独编译出【0】
│       │   └── rpc
│       │       ├── include
│       │       │   ├── dbinder_invoker.h
│       │       │   ├── rpc_feature_set.h
│       │       │   ├── rpc_process_skeleton.h
│       │       │   └── rpc_trans_callback.h
│       │       ├── ipc_adapter
│       │       │   ├── include
│       │       │   │   ├── ipc_proxy_inner.h
│       │       │   │   └── ipc_stub_inner.h
│       │       │   ├── mini
│       │       │   │   ├── ipc_proxy_inner.c           #【a】
│       │       │   │   └── ipc_stub_inner.c            #【a】
│       │       │   └── small
│       │       │       ├── ipc_proxy_inner.c           #【c】
│       │       │       └── ipc_stub_inner.c            #【c】
│       │       ├── src
│       │       │   ├── dbinder_invoker.c               #【a+c】
│       │       │   ├── rpc_feature_set.c               #【STD】【只有STD系统的[10]编译该文件,Lite类型系统不编译】
│       │       │   ├── rpc_process_skeleton.c          #【a+c】
│       │       │   ├── rpc_process_skeleton_virtual.c  #【b+c】
│       │       │   └── rpc_trans_callback.c            #【a+c】
│       │       └── trans_adapter
│       │           ├── include
│       │           │   ├── rpc_softbus_trans.h
│       │           │   └── rpc_trans.h
│       │           └── src
./ipc/test/rpc/socket_trans/src/rpc_socket_trans.c  #【c】因为enable_socket_trans[true]用socket而不用softbus
│       │               ├── rpc_softbus_trans.c     #【a】如果enable_socket_trans[false],则这里【+c】用softbus而不用socket
│       │               └── rpc_trans.c             #【a+c】
│       │
│       │   # STD系统的IPC框架代码
│       └── src
│           ├── core
│           │   ├── include
│           │   │   ├── buffer_object.h
│           │   │   ├── comm_auth_info.h
│           │   │   ├── databus_session_callback.h
│           │   │   ├── dbinder_callback_stub.h
│           │   │   ├── dbinder_error_code.h
│           │   │   ├── dbinder_session_object.h
│           │   │   ├── ipc_debug.h
│           │   │   ├── ipc_process_skeleton.h
│           │   │   ├── ipc_thread_pool.h
│           │   │   ├── ipc_thread_skeleton.h
│           │   │   ├── ipc_workthread.h
│           │   │   └── stub_refcount_object.h
│           │   └── source
│           │       ├── buffer_object.cpp
│           │       ├── comm_auth_info.cpp
│           │       ├── databus_session_callback.cpp
│           │       ├── dbinder_callback_stub.cpp
│           │       ├── dbinder_session_object.cpp
│           │       ├── ipc_file_descriptor.cpp
│           │       ├── ipc_object_proxy.cpp
│           │       ├── ipc_object_stub.cpp
│           │       ├── ipc_process_skeleton.cpp
│           │       ├── ipc_skeleton.cpp
│           │       ├── ipc_thread_pool.cpp
│           │       ├── ipc_thread_skeleton.cpp
│           │       ├── ipc_workthread.cpp
│           │       ├── iremote_broker.cpp
│           │       ├── iremote_object.cpp
│           │       ├── message_option.cpp
│           │       ├── message_parcel.cpp
│           │       ├── peer_holder.cpp
│           │       └── stub_refcount_object.cpp
│           ├── mock
│           │   ├── include
│           │   │   ├── binder_connector.h
│           │   │   ├── binder_debug.h
│           │   │   ├── binder_invoker.h
│           │   │   ├── dbinder_base_invoker.h
│           │   │   ├── dbinder_databus_invoker.h
│           │   │   ├── hitrace_invoker.h
│           │   │   ├── invoker_factory.h
│           │   │   ├── invoker_rawdata.h
│           │   │   ├── iremote_invoker.h
│           │   │   └── sys_binder.h
│           │   └── source
│           │       ├── binder_connector.cpp
│           │       ├── binder_debug.cpp
│           │       ├── binder_invoker.cpp
│           │       ├── hitrace_invoker.cpp
│           │       ├── invoker_factory.cpp
│           │       ├── nvoker_rawdata.cpp
│           │       └── idbinder_databus_invoker.cpp  
│           ├── jni
│           │   ├── include
│           │   │   ├── jni_helper.h
│           │   │   ├── jni_remote_object.h
│           │   │   ├── ohos_rpc_message_option.h
│           │   │   ├── ohos_rpc_message_parcel.h
│           │   │   └── ohos_rpc_remote_object.h
│           │   └── source
│           │       ├── jni_helper.cpp
│           │       ├── ohos_rpc_message_option.cpp
│           │       ├── ohos_rpc_message_parcel.cpp
│           │       └── ohos_rpc_remote_object.cpp
│           └── napi
│               ├── include
│               │   ├── napi_ashmem.h
│               │   ├── napi_message_option.h
│               │   ├── napi_message_parcel.h
│               │   └── napi_remote_object.h
│               └── src
│                   ├── napi_ashmem.cpp
│                   ├── napi_message_option.cpp
│                   ├── napi_message_parcel.cpp
│                   ├── napi_remote_object.cpp
│                   └── napi_rpc_native_module.cpp
│
│   # dbinder服务的实现代码【又分Lite类型系统和STD系统】
└── services
    └── dbinder
        │   # Lite类型系统的dbinder服务的实现代码【LiteA系统不走dbinder】
        ├── c
        │   ├── include
        │   │   ├── dbinder_service_inner.h
        │   │   ├── dbinder_stub.h
        │   │   ├── dbinder_trans_callback.h
        │   │   └── dbinder_types.h
        │   ├── ipc_adapter
        │   │   ├── include/dbinder_ipc_adapter.h
        │   │   ├── mini/dbinder_ipc_adapter.c   #【a】
        │   │   └── small/dbinder_ipc_adapter.c  #【c】
        │   └── src
        │       ├── dbinder_service.c            #【a+c】
        │       ├── dbinder_stub.c               #【a+c】
        │       └── dbinder_trans_callback.c     #【a+c】
        │ 
        │   # STD系统的dbinder服务的实现代码
        └── dbinder_service  #【12】ohos_shared_library("libdbinder")
            ├── include
            │   ├── dbinder_death_recipient.h
            │   ├── dbinder_log.h
            │   ├── dbinder_remote_listener.h
            │   └── dbinder_sa_death_recipient.h
            └── src
                ├── dbinder_death_recipient.cpp
                ├── dbinder_sa_death_recipient.cpp
                ├── dbinder_service.cpp
                ├── dbinder_service_stub.cpp
                └── socket/dbinder_remote_listener.cpp

  从上面的整理可以看出,Lite类型系统和STD系统,各有一套自己的IPC/RPC的实现代码。因为当前目标是要研究标准系统的dmsfwk组件(和samgr等其他组件),所以我们当前的重点是上文中的编译目标【10】【11】【12】。

  通过对比【10-ipc_core】和【11-ipc_single】两个编译目标的BUILD.gn文件,可以认为【11】是【10】的子集,因为:

  1. 目标【10】没有定义CONFIG_IPC_SINGLE,目标【11】是有定义的。在部分共用的源代码文件中,有使用 #ifndef CONFIG_IPC_SINGLE 控制的代码,是目标【10】专用的。
  2. 目标【10】比目标【11】多编译几个文件,是与DBinder、DataBus相关的,用于RPC。

  目前还没有非常确定【10】【11】各自的应用场景有多大的差别,但我的理解偏向于Stub/Server端多依赖【10】,而Proxy/Client端多依赖【11】,或者分布式SA多依赖【10】,普通SA多依赖【11】(有待后面有更多的理解后确认)。

  不管怎样,【10】和【11】两个目标的代码是共用的,都属于IPC范畴,可以一并阅读理解。【12】则属于RPC范围,再单独阅读理解。至于Lite类型系统的编译目标,待以后有空研究的时候再补充相关总结。

2.基于Binder驱动的IPC(基于3.1 Release分支)

  ipc组件根目录下的README.md文件中有提到:

IPC(Inter-Process Communication)与RPC(Remote Procedure Call)机制用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,而后者使用软总线驱动,用于跨设备跨进程通信。IPC和RPC通常采用客户端-服务器(Client-Server)模型,服务请求方(Client)可获取提供服务提供方(Server)的代理 (Proxy),并通过此代理读写数据来实现进程间的数据通信。通常,系统能力(System Ability)Server侧会先注册到系统能力管理者(System Ability Manager,缩写SAMgr)中,SAMgr负责管理这些SA并向Client提供相关的接口。Client要和某个具体的SA通信,必须先从SAMgr中获取该SA的代理,然后使用代理和SA通信。

  熟悉Android系统或者做过OHOS系统移植的小伙伴,即使没有非常深入理解过Binder,但估计也会经常听到基于Binder驱动的IPC机制。

  内核态的Binder驱动实现代码,在 //kernel/linux/linux-5.10/drivers/android/ 目录下。在编译Linux内核时,通过 //kernel/linux/config/linux-5.10/arch/arm(arm64)/configs/ 目录下的 xxxx_defconfig 文件中的如下配置,将Binder驱动模块编译进内核:

#
# Android
#
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
# CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set
# CONFIG_DAX is not set
CONFIG_NVMEM=y

  Binder驱动在内核向用户态进程提供服务;用户态进程通过 open(“/dev/binder”) 和 ioctl() 来使用Binder服务实现IPC。

  这中间其实要经历一些非常复杂的过程,建议小伙伴们自行搜索和理解Binder在内核中实现IPC的原理和细节,我现在还无法保证未来会做这方面的总结。

  但本系列文章的下一篇,将会以全景图的形式展示和讲解OHOS的用户态IPC框架的实现流程和细节。

3.基于DBinder驱动的RPC(待定)

  DBinder应该是Distributed Binder的缩写。

  DBinder将会涉及软总线的一些实现细节,我先看看能理解得多深入,待有所理解后再写总结。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-9-24 14:06:50修改
6
收藏 2
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

随着技术的深入,要掌握的知识也越来越多。

回复
2022-9-26 10:59:33
回复
    相关推荐