OpenHarmony 3.2 Release HDF的IDL文件初探(上)
1.IDL
安卓上我们熟知的aidl能够帮我们快速生成binder的代码,OpenHarmony 上也提供了此功能,用法与aidl相似.与安卓不同的地方以及和OpenHarmony 3.1不同的是:
-
不再需要在代码中分别引入proxy和sub,只需要在deps中是加入不同的包
-
idl文件也与服务端解耦,需要单独编写bundle.json.
1. IDL 声明和引入.
1.IDL的bundle.json: drivers\interface\location\gnss\bundle.json
"inner_kits": [ { "name": "//drivers/interface/location/gnss/v1_0:liblocation_gnss_proxy_1.0", "header": {"header_files": [],"header_base": "//drivers/interface/location/gnss" } }, { "name": "//drivers/interface/location/gnss/v1_0:location_gnss_idl_headers", "header": {"header_files": [],"header_base": "//drivers/interface/location/gnss" } } ]
2.proxy端引入:base\location\services\location_gnss\gnss\BUILD.gn
external_deps = [ ... "drivers_interface_location_agnss:liblocation_agnss_proxy_1.0", "drivers_interface_location_gnss:liblocation_gnss_proxy_1.0", ... ]
3.service端引入:drivers\peripheral\location\gnss\hdi_service\BUILD.gn
external_deps = [ "drivers_interface_location_agnss:location_gnss_idl_headers", ... ]
2.IDL 文件编写
先看readme.md,可以简单了解一下idl文件规则 OpenHarmony IDL工具规格及使用说明书.目前openharmony文档内容有点少,但是hdf中已经在使用,可能还没给上层开放.这里用的是harmonyOS的介绍:
IDL文件编写规范
一个 HarmonyOS IDL 文件只能定义一个接口类,接口定义的形式使用 BNF 范式描述,示例如下:
? interface { ? }
是接口属性声明,当前支持 oneway、callback、full、lite 属性:(openharmony的文档中只有oneway)
- oneway:表示该接口中的方法都是单向方法,即调用方法后不用等待该方法执行即可返回,该属性为可选项,如果无声明,则默认为同步调用方法
- callback:表示该接口为callback接口,即从下层实现中回调到上层服务中;
- full、lite:表示该接口在重量级部署或轻量级部署中使用。如果无声明,则默认为重量级、轻量级部署中都会使用。
是接口名声明,接口名需包含完整的命名空间,且必须包含方法声明,不允许出现空接口。接口示例:
[oneway] interface ohos.app.IAbilityManager {……};
是方法声明,形式为:
?
是方法属性声明,当前支持 oneway 、full、lite 属性:
- oneway:表示该方法是单向方法,即调用方法后不用等待该方法执行即可返回;
- full、lite:表示该方法在重量级部署或轻量级部署中使用。如果无声明,则默认为重量级、轻量级部署中都会使用。
是返回类型,是方法名和各个参数声明,参数声明的形式为:
\[ \]
的值为“in”、“out”或“inout”,分别表示该参数是输入参数、输出参数或输入输出参数。oneway 方法不允许有输出参数(包含输入输出参数)和返回值。方法示例:
void SetBundles([in] Map bundleInfos, [in, out] int number); [oneway] void Dump([in] ParcelableFileDescriptor fd, [in] long flags);
IDL主要三个内容:数据类型,callback,接口
├── bundle.json
└── v1_0
├── BUILD.gn # idl文件编译脚本
├── GnssTypes.idl # 数据类型定义idl文件
├── IGnssCallback.idl # callback 接口定义idl文件
└── IGnssInterface.idl # interface 接口定义idl文件
1. 数据类型定义 GnssTypes.idl
这里仅简单列举一些:
package ohos.hdi.location.gnss.v1_0;enum GnssWorkingMode// 枚举类型{ GNSS_WORKING_MODE_STANDALONE = 1, ...};struct SatelliteStatusInfo {// 结构体 unsigned int satellitesNumber; short[] satelliteIds; enum GnssConstellationType[] constellation; float[] carrierToNoiseDensitys;// ...};// ...struct GnssRefInfo { enum GnssRefInfoType type; struct GnssRefTime time; struct GnssRefLocation location; struct LocationInfo best_location;};
2. callback定义IGnssCallback.idl
[callback] 表示该接口为callback接口,即从下层实现中回调到上层服务中;
package ohos.hdi.location.gnss.v1_0;import ohos.hdi.location.gnss.v1_0.GnssTypes;[callback] interface IGnssCallback { ReportLocation([in] struct LocationInfo location); ReportGnssWorkingStatus([in] enum GnssWorkingStatus status); ReportNmea([in] long timestamp, [in] String nmea, [in] int length); ReportGnssCapabilities([in] enum GnssCapabilities capabilities); ReportSatelliteStatusInfo([in] struct SatelliteStatusInfo info); RequestGnssReferenceInfo([in] enum GnssRefInfoType type); RequestPredictGnssData(); ReportCachedLocation([in] struct LocationInfo[] gnssLocations);}
3. interface定义
package ohos.hdi.location.gnss.v1_0;import ohos.hdi.location.gnss.v1_0.IGnssCallback;import ohos.hdi.location.gnss.v1_0.GnssTypes;interface IGnssInterface { SetGnssConfigPara([in] struct GnssConfigPara para); EnableGnss([in] IGnssCallback callbackObj); DisableGnss(); StartGnss([in] enum GnssStartType type); StopGnss([in] enum GnssStartType type); SetGnssReferenceInfo([in] struct GnssRefInfo refInfo); DeleteAuxiliaryData([in] enum GnssAuxiliaryData data); SetPredictGnssData([in] String data); GetCachedGnssLocationsSize([out] int size); GetCachedGnssLocations();}
4. BUILD.gn编译文件编写
import("//drivers/hdf_core/adapter/uhdf2/hdi.gni")hdi("location_gnss") { module_name = "location_gnss" sources = [ "GnssTypes.idl", "IGnssCallback.idl", "IGnssInterface.idl", ] language = "cpp" subsystem_name = "hdf" part_name = "drivers_interface_location_gnss"}
3. IDL服务端实现
drivers\peripheral\location\gnss\hdi_service\gnss_interface_impl.h
客户端服务端头文件现在统一到一个ixxx_interface.h头文件中,在openharmony 3.1客户端是xxx_proxy.h,服务端是xxx_stub.h
#include "v1_0/ignss_interface.h"namespace OHOS {namespace HDI {namespace Location {namespace Gnss {namespace V1_0 {class GnssInterfaceImpl : public IGnssInterface {public: GnssInterfaceImpl(); virtual ~GnssInterfaceImpl(); int32_t SetGnssConfigPara(const GnssConfigPara& para) override; int32_t EnableGnss(const sptr<IGnssCallback>& callbackObj) override; int32_t DisableGnss() override; int32_t StartGnss(GnssStartType type) override; int32_t StopGnss(GnssStartType type) override; int32_t SetGnssReferenceInfo(const GnssRefInfo& refInfo) override; int32_t DeleteAuxiliaryData(GnssAuxiliaryData data) override; int32_t SetPredictGnssData(const std::string& data) override; int32_t GetCachedGnssLocationsSize(int32_t& size) override; int32_t GetCachedGnssLocations() override;};} // V1_0} // Gnss} // Location} // HDI} // OHOS
在HDF_INIT的地方还是要使用
drivers\peripheral\location\gnss\hdi_service\gnss_interface_driver.cpp
#include "v1_0/gnss_interface_stub.h"
3.1和3.2头文件对比 这里对比一下thermal
drivers\peripheral\thermal\interfaces\hdi_service\include\thermal_interface_impl.h
3.2
#include "v1_0/ithermal_interface.h"
namespace OHOS {
namespace HDI {
namespace Thermal {
namespace V1_0 {
class ThermalInterfaceImpl : public IThermalInterface {
3.1
#include "v1_0/thermal_interface_stub.h"
namespace OHOS {
namespace HDI {
namespace Thermal {
namespace V1_0 {
class ThermalInterfaceImpl : public ThermalInterfaceStub {
具体实现在 drivers\peripheral\location\gnss\hdi_service\gnss_interface_impl.cpp,本文只看idl,所以不涉及细节了
4. IDL客户端
#include
gnssInterface_ = IGnssInterface::Get();
下一篇聊聊idl生成的文件,其实跟aidl生成的东西差不多,都是封装binder