一、硬件资源池理念产生背景
随着智能设备的发展和普及,越来越多的智能设备已经深入人们的生活,比如手机,PC,平板,各类穿戴设备等。当前单个设备的外设资源已经非常丰富,硬件能力也很强大。像我们的手机、PC、平板都有相机,音频,屏幕,键鼠等各种外设资源;但是这些硬件外设是属于各个设备自身的,如果涉及到跨设备的协同操作就会比较繁琐。
比如用户正在 PC 上编辑文档,需要从平板复制一段文字,或者使用手机拍摄照片,然后插入文档作为素材,需要用户在各个设备上分别操作,然后发送文字或者图片到 PC,然后再回到 PC 进行编辑,非常繁琐。如果应用开发者从应用层实现设备间硬件能力共享,对于应用开发者工作量和难度非常大,而且各个应用之间需要重复开发,能力难以复用和继承。
图 1 单设备硬件孤立难以共享
为此,鸿蒙系统提出了硬件资源池的理念,打破了各个设备硬件的孤立状态,能够做到设备间硬件外设全局共享。我们把各个设备的硬件外设抽象为外设信息单元,外设信息在各个可信设备之间自动同步,如此,实现了外设信息的全局可见;结合分布式硬件虚拟化技术,实现任意设备之间的硬件外设能力跨设备调用;分布式硬件资源池作为系统能力下沉系统底层,北向开发者不感知资源池的存在;跨设备硬件和本地硬件使用同一套 API,开发者调用跨设备硬件体验和本地硬件一致,如此明显的便利了开发者调用跨设备硬件,开发者无需关注硬件底层细节,专注于业务创新。
图 2 硬件资源池打破硬件边界,全局共享
二、鸿蒙系统硬件资源池支持场景
鸿蒙系统采用硬件资源池的理念,能够结合多个设备的优势硬件为用户提供更优的体验,同时支持了消费者和开发者的多种创新体验。
2.1 消费者场景
在消费者层面,华为分布式硬件支持智慧办公,智慧出行等多种创新场景。例如智慧办公场景中,使用一套 PC 键鼠即可和周边平板等设备跨设备操作,使用到键鼠外设的跨设备操控能力;多屏协同场景中,手机屏幕显示到平板,手机视频通话可以使用平板的麦克风和摄像头,用户在平板上即可同时操作手机平板两台设备,避免设备间来回切换,操作方便,这个场景使用到了麦克风,扬声器,摄像头和屏幕等硬件的跨设备分布式能力。
在智慧出行场景中,用户在手机上听音乐或者视频通话,进入座舱后,手机上的音乐和通话可以自动接续到车机,使用车机的音频外设播音和拾音,使用车机的摄像头进行视频通话,更加符合用户在座舱中的使用习惯;手机导航接续到车机后,车机的 GPS 信号可以共享给手机,结合手机 GPS 信号提供更高精度的定位数据;可以看到,在智慧出行场景中,可以通过分布式硬件资源池结合手机和车机的优势硬件,为用户提供更好的服务体验。
图 3 鸿蒙硬件资源池支持各类消费者场景
2.2 开发者场景
对于开发者来说,由于分布式硬件资源池将跨设备硬件调用的复杂度都封装在了系统底层,跨设备硬件复用本地硬件的 API,开发者学习和适配难度可以做到最低。
以分布式相机为例,相机接口可以同时查询到本地相机和跨设备相机外设,本地相机和跨设备相机通过 ConnectionType.CAMERA_CONNECTION_REMOTE 属性相区分,开发者通过该属性过滤出分布式相机后,其他操作和本地相机完全一致。无需为使用跨设备硬件学习一套独立的 API,很大程度上的简化了开发者开发难度。
图 4 分布式硬件开发者使用示例
三、硬件资源池原理
以相机和音频为例,假设设备 A 和设备 B 都有各自的相机和音频外设,驱动层有对应的本地相机和本地音频驱动。
图 5 分布式硬件资源池原理示意
分布式硬件从各自设备本地采集相机和音频驱动信息,存入分布式数据库。如果 AB 两个设备建立了可信关系并且通过软总线组网上线成功,分布式数据库会在 AB 两个设备之间自动同步各自的本地外设数据信息,这样,设备 A 分布式硬件可以拿到设备 B 的相机和音频外设规格数据,同样,设备 B 也可以拿到设备 A 的相机和音频外设规格数据。
以设备 A 的流程为例,分布式硬件收到对端设备 B 的硬件规格数据后,在驱动层注册对应的虚拟相机和虚拟音频驱动,虚拟驱动相当于对端设备物理硬件在本地的代理;虚拟驱动实现和本地硬件驱动相同的 HDI 接口,区别在于,本地硬件驱动操作本地物理硬件,虚拟硬件驱动控制和数据传输通过软总线作用于对端分布式硬件。
由于和本地硬件实现同样的 HDI 接口,设备 B 相机和音频对应的虚拟硬件可以被相机服务和音频服务发现并管理,包括外设的查询,相机的预览拍照录像,音频的播放,声音的录制等功能。
对称的,在设备 B 上会执行同样的过程,为设备 A 相机和音频外设注册对应虚拟驱动,从而实现设备 B 上对设备 A 硬件外设的查询和使用。
如此就实现了外设信息在设备间互通共享,信息感知自动注册虚拟硬件,注册后即可用,成为一个无中心对称的分布式硬件外设管理系统。同时,分布式硬件框架定义了外设热插拔,虚拟硬件保活等机制,保证业务可靠性。在运行时,各个硬件外设的业务运行于独立进程中,在进程层面保证不同硬件的虚拟化业务互相隔离,提高了业务可靠性。
详细实现可以参考分布硬件管理框架源码:https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk
四、硬件资源池接入实践
4.1 接口定义
通过前文分析,可以看到分布式硬件与南向硬件的交互涉及"硬件信息采集"和"驱动注册"两类业务,与此对应,分布式硬件针对南向硬件接入定义了两类接口。一类是硬件规格采集接口,一类是驱动注册与准备接口。
图 6 分布式硬件资源池接入接口
(1)硬件规格采集接口
硬件规格采集接口定义了规格信息的采集以及外设热插拔事件监听等功能。
接口链接:https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk/blob/master/common/utils/include/ihardware_handler.h
(2)驱动注册与准备接口
由于我们是跨设备硬件调用,涉及双端设备的硬件,我们定义使用周边其他设备硬件外设的一端为 Source 端,共享本地硬件给其他设备调用的一端为 Sink 端。
驱动注册与准备接口包括 Source 和 Sink 两端。
Source 端包括初始化,释放以及虚拟驱动注册/去注册等功能;Sink 端主要是初始化和释放接口,用于响应 Source 端的控制指令,比如播放声音或者采集视频画面。在设备组网上线后,分布式硬件框架调用各个硬件类型的南向接口实现,分别初始化各类硬件的 Source 和 Sink 端业务进程,为后续的硬件跨设备调用做好准备。
Source 端接口链接:https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk/blob/master/common/utils/include/idistributed_hardware_source.h
Sink 端接口链接:https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk/blob/master/common/utils/include/idistributed_hardware_sink.h
4.2 硬件接入实例
由于分布式硬件良好的南向接入解耦设计,如果有新硬件外设接入,只需要如下三步即可,以分布式相机配置为例。
Step1:定义硬件外设类型枚举值 CAMERA。
enum class DHType : uint32_t {
UNKNOWN = 0x0, // unknown device
CAMERA = 0x01, // Camera
AUDIO = 0x02, // Mic
SCREEN = 0x08, // Display
GPS = 0x10, // GPS
INPUT = 0x20, // Key board
MAX_DH = 0x80000000
};
文件链接:https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk/blob/master/common/utils/include/device_type.h
Step2:实现分布式硬件框架定义的南向接入接口,分别实现为三个 so。
1、实现分布式硬件框架定义的硬件规格采集接口 IHardwareHandler,并编译获得接口实现 libdistributed_camera_handler.z.so。
参考代码:https://gitee.com/openharmony/distributedhardware_distributed_camera/blob/master/services/cameraservice/cameraoperator/handler/include/dcamera_handler.h
2、实现 Source 侧接入接口 IDistributedHardwareSource,并编译获得接口实现 libdistributed_camera_source_sdk.z.so。
参考代码:https://gitee.com/openharmony/distributedhardware_distributed_camera/blob/master/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler.h
3、实现 Sink 侧接入接口 IDistributedHardwareSink,并编译获得接口实现 libdistributed_camera_sink_sdk.z.so。
参考代码:https://gitee.com/openharmony/distributedhardware_distributed_camera/blob/master/interfaces/inner_kits/native_cpp/camera_sink/include/dcamera_sink_handler.h
Step3:在分布式硬件子部件配置文件中,添加新硬件外设相关配置,包括外设类型,南向接口实现的 so 名称,版本号,以及 Source 和 Sink 端服务分配的服务 Id。
● 该配置由产品定义确定,不同的产品可能使用不同的分布式能力。以 RK3568 开发板为例,配置如下:
{
"name": "distributed_camera",
"type": "CAMERA",
"comp_handler_loc": "libdistributed_camera_handler.z.so",
"comp_handler_version": "1.0",
"comp_source_loc": "libdistributed_camera_source_sdk.z.so",
"comp_source_version": "1.0",
"comp_source_sa_id": 4803,
"comp_sink_loc": "libdistributed_camera_sink_sdk.z.so",
"comp_sink_version": "1.0",
"comp_sink_sa_id": 4804
}
配置链接:https://gitee.com/openharmony/device_board_hihope/blob/master/rk3568/distributedhardware/distributed_hardware_components_cfg.json
三个接口的 so 实现后,编译打包到系统库路径下,同时配置到分布式硬件部件配置文件中,设备组网上线后,可以看到分布式相机的 dcamera 进程已经成功启动,表明相机外设已经纳入资源池管理,成为分布式相机。
从下述截图也可以看到分布式硬件其他相关进程,dhardware 就是分布式硬件资源池管理框架进程,顾名思义,dcamera 是分布式相机进程,dinput 是分布式键鼠输入进程,dscreen 是分布式屏幕进程。
图 7 分布式硬件相关进程
五、社区已开源分布式硬件代码仓
当前在 OpenHarmony 开源社区,已经开源了硬件资源池管理框架,分布式相机,分布式音频,分布式屏幕,分布式输入的代码仓,开放了相机,音频,屏幕和键鼠输入外设的跨设备控制源码,关于硬件资源池的详细实现,可以参考我们的开源代码仓。
1、 分布式硬件框架(distributedhardware_distributed_hardware_fwk)https://gitee.com/openharmony/distributedhardware_distributed_hardware_fwk
2、分布式相机(distributedhardware_distributed_camera)
https://gitee.com/openharmony/distributedhardware_distributed_camera
3、分布式音频(distributedhardware_distributed_audio)
https://gitee.com/openharmony/distributedhardware_distributed_audio
4、分布式屏幕(distributedhardware_distributed_screen)
https://gitee.com/openharmony/distributedhardware_distributed_screen
5、分布式输入(distributedhardware_distributed_input)https://gitee.com/openharmony/distributedhardware_distributed_input