鸿蒙OS分布式任务调度,#2020征文-其它#鸿蒙子系统解读-分布式任务调度篇(下)...

3.1.3.轻量设备端拉起FA

在前面的分析中,我们看到会话报文通过协议格式的解析最终得到一个TlvDmsMsgInfo结构体,这个结构体中包含了命令字、包名、Ability名、调用者的签名等信息。然后在DmsLiteProcessCommuMsg()函数中根据命令字执行相应的动作。目前的代码只支持一个动作,就是拉起FA。下面的是拉起FA的代码:

18a4c9f176a41914133d019521166bd7.png

⑴调用CheckRemotePermission()函数检查调用者(智慧屏端)是否有权限这样做。

CheckRemotePermission()函数位于dmslite_check_remote_permission.c中。代码如下:

1、从包管理器中得到BundleInfo

39e44b2eabdaf9ccd9bf9f529486d961.png

这段代码首先判断uid,由于我们是在foundation进程中,用的也是FOUNDATION_UID,因此判断的第一个条件通过,是属于进程内调用。否则如果是从Shell程序执行的话,将是跨进程调用。

我们再来看看GetBmsInterface()函数的实现:

74cbafd58299be2efe5909916581ea7a.png

这个函数首先通过 SAMGR_GetInstance()拿到samgr的实例(前面有过介绍),然后通过GetFeatureApi()函数得到BMS_SERVICE的FeatureApi的iUnknown接口指针。再通过iUnknown->QueryInterface()拿到bmsInterface指针(这个指针里面是BmsServerProxy结构体含有这个Feature的一些API接口指针)。这个实现有点类似Android的Binder接口实现,是在服务框架子系统中实现的。BMS_SERVICE这个服务是在./foundation/appexecfwk/services/bundlemgr_lite/src/bundle_ms_feature.cpp代码中注册的,有兴趣的同学可以去看下。从名字上看bundlemgr_lite应该是包管理器子系统。

我们再回到CheckRemotePermission()函数中,下面的代码是bmsInterface->GetBundleInfo(…)。这句代码是意思是通过包管理服务提供的GetBundleInfo函数查询轻量设备端的包的信息,这个包信息放在了bundleInfo结构体中。

2、检查签名是否一致

c9350bdabc9a569598b2914274fade37.png

bundleInfo.appId根据注释应该是一个子串,包含了:bundleName + “_” + signature。因此bundleInfo.appId + strlen( calleeBundleName) + 1 就是bundleInfo.appId中的签名的子串位置。

然后用这个签名与发送过来的消息中的签名做一个字符串的比较,看看调用者的签名是否正确。

⑵调用StartAblitiyFromRemote()函数拉起轻量设备端的FA。

在签名检查通过后,DmsLiteProcessCommuMsg()函数中最后调用StartAbilityFromRemote()函数执行拉起FA的功能。

我们来看看StartAbilityFromRemote()函数的实现:

606cc1444574315045ee059005d63cf3.png

这段代码分为两个部分:

①注册拉起FA后的回调函数

RegisterIpcCallback()的函数实现在./foundation/communication/frameworks/ipc_lite/liteipc/src/liteipc_adapter.c中,有兴趣的同学可以看看源码。它的功能是向ipc_lite子模块注册一个回调。当Java层的FA被拉起后,应该会通过ipc机制通知native层,这里就是回调注册的地方。我们看到注册的回调是AmsResultCallback()函数。我们看下这个函数的实现:

b0b18e33eea944f10276dcc31895003b.png

所以这个函数的重点就是调用了g_onStartAbilityDone()函数指针,而这个函数指针的值就是在StartAbilityFromRemote()中设置的。

②调用StartAbilityFromRemoteInner()函数实现拉起FA的功能

我们看一下StartAbilityFromRemoteInner()函数的实现:

ce0c0df9184ccb5876b4a325399beef8.png

我们把这个函数分为两个部分:

A、构造一个Want结构。Want结构我感觉可以类比成Android里面的Intent。用于在不同Ability之间传输信息。我们在最前面有介绍过在智慧屏端构造Want结构,发起一个分布式调用的代码。这里的Want可以理解成从智慧屏端发送过来的Want,经过网络的传输(TCP传输)后,在轻量设备侧重新组装成Want结构体。里面包含了要拉起的FA的包名,ability名称。

我们来看下FillWant()函数的实现:

dfe4f171051c69a8ff179a4855d40e90.png

这个函数的实现首先是构造Element,将包名(bundleName)和ability名都放入到element中,然后将Element放入到Want里面,再设置Want的Identity。

B、通过samgr拿到ams的FeatureApi接口,然后通过这个接口调用启动FA。

我们看一下GetAmsInterface()函数的实现:

e68f237791536a86edd1935ef78227a5.png

与前面介绍的检查签名时调用的GetBmsInterface()函数类似,都是通过samgr查询AMS_SERVICE服务的FEATURE,然后通过iUnknown接口的QueryInterface()获得AmsInterface接口。AMS_SERVICE的实现代码在./foundation/aafwk/services/abilitymgr_lite目录下,有兴趣的同学可以看看代码。

拿到amsInterface接口后,最后通过调用amsInterface->StartAbility(&want);来完成拉起FA的任务。

总结:

1、拉起FA的功能主要在dmslite_check_remote_permission.c、dmslite_famgr.c。

2、另外涉及到以下模块:

a)bundlemgr_lite:./foundation/appexecfwk/services/bundlemgr_lite

b)ipc_lite:./foundation/communication/frameworks/ipc_lite

c)abilitymgr_lite:./foundation/aafwk/services/abilitymgr_lite

3、完整的时序图如下:

b6c33b696c1353956cbac3a9fccd7d7f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值