OpenHarmony 源码解析之账号子系统 原创 精华
作者:严明舟
1 简介
在标准系统上,账号子系统主要提供分布式帐号登录状态管理能力,支持在端侧对接厂商云帐号应用,提供云帐号登录状态查询和更新的管理能力
1.1 OpenHarmony架构图
1.2 账号子系统架构图
1.3 账号子系统目录结构
2 账号管理服务的启动
2.1 rc启动服务
2.1.1 rc文件结构解析
rc文件是以模块为单位的,模块分为3种类型:on、service、import
- import: 导入其它的
rc
文件 - on: 执行
chown、mkdir、write、export、symlink
等简单的shell指令,如:
post-fs-data
将一个section
里的所有命令加入到一个执行队列,在未来的某个时候会顺序执行队列里的命令
- service: 执行可执行程序,如:
accountmgr
为可执行程序名
/system/bin/sa_main /system/profile/accountmgr.xml
为可执行文件的路径
class、user、group、seclabel、writepid
这些关键字所对应的行是用来描述service
一些特点,不同的service
有着不同的特点
service什么时候被执行?
在某个on模块的指令里会存在“class_start”
,例如:
当执行到这里是service模块就会被调用
2.2 AccountMgrService的启动流程
2.2.1 AccountMgrService通过OnStart调用Init
AccountMgrService
继承自SystemAbility
,当应用启动时首先应用程序框架会调用AccountMgrService
的生命周期函数OnStart()
;OnStart()
首先判断服务运行状态是否已经开启,如果没有开启,则调用Init()
进行初始化操作- 初始化操作完成并返回
true
给OnStart()
后,服务运行状态则更新为开启状态
2.2.2 AccountMgrService的Init()实现
Init()
被调用后,依然要先判断服务运行状态是否已经开启- 随后,检查
DEVICE_OWNER_DIR
是否存在,如果不存在就强制创建 - 如果服务还没有被注册,则调用
Publish()
来注册服务,Publish()
执行成功后,标记服务已经被注册 - 创建
OhosAccountManager
对象,并调用它的OnInitialize
方法
2.2.3 OhosAccountManager的初始化
OhosAccountManager::OnInitialize
首先调用BuildEventsMapper()
进行事件映射,查看BuildEventsMapper()
实现可发现,写死的事件有账号登入、登出、注销和Token失效,并与对应的方法绑定- 组织账号配置文件路径,作为参数创建
OhosAccountDataDeal
对象,并调用它的Init
方法,查看Init()
实现可发现,Init()
读取账号配置文件并保存到jsonData_
中 - 调用
AccountInfoFromJson()
获取账号信息并保存到currentAccount_
中
2.2.4 OhosAccountManager::BuildEventsMapper()
OhosAccountManager::BuildEventsMapper()
将账号登入、登出、注销和Token失效四个事件与相应的处理函数绑定
2.2.5 ohos_account_data_deal的Init()实现
OhosAccountDataDeal::Init()
首先检查账号配置文件存不存在,如果不存在则创建,如果存在则读取账号配置文件内容并保存到jsonData_
中
3 分布式账号模块接口说明
分布式帐号模块的功能主要包括获取、查询和更新分布式账号信息,仅支持系统应用
在分布式账号模块的初始化中,可发现以下函数的注册:
方法 | 描述 |
---|---|
getDistributedAccountAbility | 获取分布式帐号单实例对象 |
queryOsAccountDistributedInfo | 查询分布式帐号信息 |
updateOsAccountDistributedInfo | 更新分布式帐号信息 |
4 分布式账号模块接口调用流程
这里以queryOsAccountDistributedInfo
为例,来分析调用流程:
NapiDistributedAccount::QueryOhosAccountInfo
实际调用的是OhosAccountKits::GetInstance().QueryOhosAccountInfo()
OhosAccountKitsImpl::QueryOhosAccountInfo()
实际调用的是AccountProxy::QueryOhosAccountInfo()
AccountProxy::QueryOhosAccountInfo()
调用SendRequest()
发送QUERY_OHOS_ACCOUNT_INFO
请求
-
我们看看它的对端
AccountStub::OnRemoteRequest
是如何处理发送端的请求并返回什么样的结果的:从
stubFuncMap_
匹配请求码,然后获取stubFuncMap_
的第二项来处理请求
-
我们来看看
stubFuncMap_
长啥样:很容易看出,
QUERY_OHOS_ACCOUNT_INFO
请求码对应的是AccountStub::CmdQueryOhosAccountInfo()
-
我们看看
AccountStub::CmdQueryOhosAccountInfo()
的实现:-
CmdQueryOhosAccountInfo()
中首先检查调用的进程是不是root
或者system
,从这可以看出,Account
的相关接口只有系统用户才能使用 -
接着检查是否有
PERMISSION_MANAGE_USERS
权限 -
然后获取
AccountInfo
的其实是QueryOhosAccountInfo()
,它的实现是在AccountMgrService
里面
-
- 在
AccountMgrService::QueryOhosAccountInfo()
里调用OhosAccountManager
的GetAccountInfo()
这里只是返回currentAccount_
变量,它是一个AccountInfo
,在前面的账号管理服务启动的时候,我们知道currentAccount_
是在初始化过程中通过读取账号配置文件到jsonData_
中得到的
5 账号登入、登出、注销以及Token失效
- 前面提到,
OhosAccountManager::OnInitialize
会首先调用BuildEventsMapper()
进行事件映射
- 可以看到,监听的事件处理回调有登入、登出、注销以及Token失效四种类型,下面以
LoginOhosAccount
为例看看它们具体做了什么:
从上面可以看出,登录、登出、注销及Token失效操作步骤基本一致,首先对收到的事件进行处理,然后将账号信息更新到缓存和配置文件中
-
因此,这里我们只需要看看
HandleEvent()
做了什么处理:这里首先根据
eventStr
找到对应的事件类型,然后将事件更新到账号状态机
可以看到,在状态机里面只是简单完成状态的切换
6 总结
通过本文的学习可了解到账号子系统源码架构的各个组成部分的实现以及流程(包括框架代码、内部接口、外部接口、系统服务等),结合上文内容,可进一步对账号子系统其它组件进行深入的学习。
下一步,
(1) 着重理解账号子系统框架代码,为开发的可重用性和扩充性做准备;
(2) 着重理解账号管理服务模块,看看账号管理服务是如何为各功能模块的业务请求提供应答的;
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
老师的账号子系统讲的非常详细,收藏了!