1# safwk组件<a name="ZH-CN_TOPIC_0000001115588558"></a> 2## 简介<a name="section11660541593"></a> 3 4在系统服务管理子系统中safwk组件定义OpenHarmony中SystemAbility的实现方法,并提供启动、注册等接口实现。 5 6## 目录<a name="section161941989596"></a> 7 8``` 9/foundation/distributedschedule 10│── safwk # 组件目录 11│ ├── bundle.json # 组件描述及编译脚本 12│ ├── etc # 配置文件 13│ ├── interfaces # 对外接口目录 14│ ├── services # 组件服务实现 15│ ├── test # 测试用例 16``` 17 18## 说明<a name="section1312121216216"></a> 19 20### 接口说明<a name="section1551164914237"></a> 21 22<a name="table775715438253"></a> 23<table><thead align="left"><tr id="row12757154342519"><th class="cellrowborder" valign="top" width="43.19%" id="mcps1.1.3.1.1"><p id="p1075794372512"><a name="p1075794372512"></a><a name="p1075794372512"></a>接口名</p> 24</th> 25<th class="cellrowborder" valign="top" width="56.81%" id="mcps1.1.3.1.2"><p id="p375844342518"><a name="p375844342518"></a><a name="p375844342518"></a>接口描述</p> 26</th> 27</tr> 28</thead> 29<tbody><tr id="row1975804332517"><td class="cellrowborder" valign="top" width="43.19%" headers="mcps1.1.3.1.1 "><p id="p5758174313255"><a name="p5758174313255"></a><a name="p5758174313255"></a>sptr<IRemoteObject> GetSystemAbility(int32_t systemAbilityId);</p> 30</td> 31<td class="cellrowborder" valign="top" width="56.81%" headers="mcps1.1.3.1.2 "><p id="p14758743192519"><a name="p14758743192519"></a><a name="p14758743192519"></a>获取指定系统服务的RPC对象。</p> 32</td> 33</tr> 34<tr id="row2758943102514"><td class="cellrowborder" valign="top" width="43.19%" headers="mcps1.1.3.1.1 "><p id="p107581438250"><a name="p107581438250"></a><a name="p107581438250"></a>bool Publish(sptr<IRemoteObject> systemAbility);</p> 35</td> 36<td class="cellrowborder" valign="top" width="56.81%" headers="mcps1.1.3.1.2 "><p id="p8758743202512"><a name="p8758743202512"></a><a name="p8758743202512"></a>发布系统服务。</p> 37</td> 38</tr> 39<tr id="row09311240175710"><td class="cellrowborder" valign="top" width="43.19%" headers="mcps1.1.3.1.1 "><p id="p159328405571"><a name="p159328405571"></a><a name="p159328405571"></a>virtual void DoStartSAProcess(const std::string& profilePath) = 0;</p> 40</td> 41<td class="cellrowborder" valign="top" width="56.81%" headers="mcps1.1.3.1.2 "><p id="p493294018574"><a name="p493294018574"></a><a name="p493294018574"></a>根据SA profile配置启动System Ability。</p> 42</td> 43</tr> 44</tbody> 45</table> 46 47### 使用说明<a name="section129654513264"></a> 48 49SystemAbility实现一般采用XXX.cfg + profile.xml + libXXX.z.so的方式由init进程执行对应的XXX.cfg文件拉起相关SystemAbility进程。 50 51**C++实现SystemAbility** 52 53示例代码如下: 54 55- **1. 定义IPC对外接口IXXX** 56 57定义该服务对外提供的能力集合函数,统一继承IPC接口类IRemoteBroker;同时实现该IPC对外接口唯一标识符DECLARE\_INTERFACE\_DESCRIPTOR\(XXX\);该标识符用于IPC通信的校验等目的。 58 59``` 60namespace OHOS { 61class IListenAbility : public IRemoteBroker { 62public: 63 virtual int AddVolume(int volume) = 0; 64 65public: 66 enum { 67 ADD_VOLUME = 1, 68 }; 69public: 70 DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.IListenAbility"); 71}; 72} 73``` 74 75- **2. 定义客户端通信代码XXXProxy** 76 77``` 78namespace OHOS { 79class ListenAbilityProxy : public IRemoteProxy<IListenAbility> { 80public: 81 int AddVolume(int volume); 82 83 explicit ListenAbilityProxy(const sptr<IRemoteObject>& impl) 84 : IRemoteProxy<IListenAbility>(impl) 85 { 86 } 87 88private: 89 static inline BrokerDelegator<ListenAbilityProxy> delegator_; 90}; 91} // namespace OHOS 92``` 93 94- **3. 定义服务端通信代码XXXStub** 95 96``` 97namespace OHOS { 98int32_t ListenAbilityStub::OnRemoteRequest(uint32_t code, 99 MessageParcel& data, MessageParcel &reply, MessageOption &option) 100{ 101 switch (code) { 102 case ADD_VOLUME: { 103 return reply.WriteInt32(AddVolume(data.ReadInt32())); 104 } 105 106 default: 107 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 108 } 109} 110} 111``` 112 113- **4. SystemAbility的实现类** 114 115``` 116namespace { 117constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "SA_TST"}; 118} 119 120REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility, DISTRIBUTED_SCHED_TEST_LISTEN_ID, true); 121 122ListenAbility::ListenAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) 123{ 124 HiLog::Info(LABEL, ":%s called", __func__); 125 HiLog::Info(LABEL, "ListenAbility()"); 126} 127 128ListenAbility::~ListenAbility() 129{ 130 HiLog::Info(LABEL, "~ListenAbility()"); 131} 132 133int ListenAbility::AddVolume(int volume) 134{ 135 pid_t current = getpid(); 136 HiLog::Info(LABEL, "ListenAbility::AddVolume volume = %d, pid = %d.", volume, current); 137 return (volume + 1); 138} 139 140void ListenAbility::OnDump() 141{ 142} 143 144void ListenAbility::OnStart() 145{ 146 HiLog::Info(LABEL, "ListenAbility::OnStart()"); 147 HiLog::Info(LABEL, "ListenAbility:%s called:-----Publish------", __func__); 148 bool res = Publish(this); 149 if (res) { 150 HiLog::Error(LABEL, "ListenAbility: res == false"); 151 } 152 HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----beg-----", __func__); 153 AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID); 154 HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----end-----", __func__); 155 156 HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----beg-----", __func__); 157 StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID); 158 HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----end-----", __func__); 159 return; 160} 161 162void ListenAbility::OnStop() 163{ 164} 165``` 166 167- **5. SystemAbility配置** 168 169以c++实现的SA必须配置相关System Ability的profile配置文件才会完成SA的加载注册逻辑,否则没有编写profile配置的System Ability不会完成注册。配置方法如下: 170 171在子系统的根目录新建一个以sa\_profile为名的文件夹,然后在此文件夹中新建两个文件:一个以serviceId为前缀的xml文件,另外一个为BUILD.gn文件。 172 173serviceid.xml: 174 175``` 176<?xml version="1.0" encoding="UTF-8"?> 177<info> 178 <process>listen_test</process> 179 <systemability> 180 <name>serviceid</name> 181 <libpath>/system/lib64/liblistentest.z.so</libpath> 182 <run-on-create>true</run-on-create> 183 <distributed>false</distributed> 184 <dump-level>1</dump-level> 185</systemability> 186</info> 187``` 188 189BUILD.gn: 190 191``` 192import("//build/ohos/sa_profile/sa_profile.gni") 193ohos_sa_profile("xxx_sa_profile") { 194 sources = [ 195 "serviceid.xml" 196 ] 197 subsystem_name = "distributedschedule" 198} 199``` 200 201>**说明:** 202>1. 进程名字即该SystemAbility要运行的进程空间,此字段是必填选项。 203>2. 一个SystemAbility配置文件只能配置一个SystemAbility节点,配置多个会导致编译失败。 204>3. SystemAbility的name为对应的serviceId必须与代码中注册的serviceId保持一致,必配项。 205>4. libpath为SystemAbility的加载路径,必配项。 206>5. run-on-create:true表示进程启动后即向samgr组件注册该SystemAbility;false表示按需启动,即在其他模块访问到该SystemAbility时启动,必配项。 207>6. distributed:true表示该SystemAbility为分布式SystemAbility,支持跨设备访问;false表示只有本地跨IPC访问。 208>7. bootphase:可不设置;可以设置的值有三种:BootStartPhase、CoreStartPhase、OtherStartPhase(默认类型),三种优先级依次降低,当同一个进程中,会优先拉起注册配置BootStartPhase的SystemAbility,然后是配置了CoreStartPhase的SystemAbility,最后是OtherStartPhase;当高优先级的SystemAbility全部启动注册完毕才会启动下一级的SystemAbility的注册启动。 209>8. dump-level:表示systemdumper支持的level等级,默认配置1。 210>9. BUILD.gn中subsystem\_name为相应部件名称;sources表示当前子系统需要配置的SystemAbility列表,可支持配置多个SystemAbility。 211 212以上步骤完成后,全量编译代码后会在out路径向生成一个以进程名为前缀的xml文件listen\_test.xml;路径为:out\\...\\system\\profile\\listen\_test.xml。 213 214- **6. cfg配置文件** 215 216cfg配置文件为linux提供的native进程拉起策略,开机启动阶段由init进程解析配置的cfg文件进行拉起。 217 218``` 219{ 220 "jobs" : [{ 221 "name" : "post-fs-data", 222 "cmds" : [ 223 "start listen_test" 224 ] 225 } 226 ], 227 "services" : [{ 228 "name" : "listen_test", 229 "path" : ["/system/bin/sa_main", "/system/profile/listen_test.xml"], 230 "uid" : "system", 231 "gid" : ["system", "shell"] 232 } 233 ] 234} 235``` 236 237>**说明:** 238>listen\_ability的实现可以参考:test/services/safwk/unittest/common/listen\_ability。 239 240## 相关仓<a name="section1371113476307"></a> 241 242系统服务管理子系统 243 244[**distributedschedule\_safwk**](https://gitee.com/openharmony/distributedschedule_safwk) 245 246[distributedschedule\_samgr](https://gitee.com/openharmony/distributedschedule_samgr) 247 248[distributedschedule\_safwk\_lite](https://gitee.com/openharmony/distributedschedule_safwk_lite) 249 250[distributedschedule\_samgr\_lite](https://gitee.com/openharmony/distributedschedule_samgr_lite)