1# safwk<a name="en-us_TOPIC_0000001115588558"></a> 2## Introduction<a name="section11660541593"></a> 3 4The **safwk** module of the System Ability Management subsystem defines how to implement a system ability in OpenHarmony and provides APIs to start and register system abilities. 5 6## Directory Structure<a name="section161941989596"></a> 7 8``` 9/foundation/systemabilitymgr 10│── safwk # Directory for the safwk module 11│ ├── bundle.json # Description and build file of safwk 12│ ├── etc # Configuration files 13│ ├── interfaces # APIs exposed externally 14│ ├── services # Service implementation 15│ ├── test # Test cases 16``` 17 18## Usage<a name="section1312121216216"></a> 19 20### Available APIs<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>API</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>Description</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>Obtains the Remote Procedure Call (RPC) object of a system ability.</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>Publishes a system ability.</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>Starts the system ability based on the system ability profile.</p> 42</td> 43</tr> 44</tbody> 45</table> 46 47### How to Use<a name="section129654513264"></a> 48 49A system ability is implemented by using a XXX.cfg, a profile.xml, and a libXXX.z.so. The init process starts the SystemAbility process by executing the corresponding XXX.cfg file. 50 51**Implementing a System Ability in C++** 52 53The sample code is as follows: 54 55**1. Define the *IXXX* class for IPC.** 56 57The *IXXX* class is used to define the functions for the system ability to provide specific capabilities. To define this class, inherit from the **IRemoteBroker** class provided by OpenHarmony for Inter-Process Communication (IPC) and implement the **DECLARE\_INTERFACE\_DESCRIPTOR\(*XXX*)** that uniquely identifies this class. The identifier is used for IPC verification. 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. Define the *XXX*Proxy class for client communication.** 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. Define the *XXX*Stub class for server communication.** 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. Implement a system ability.** 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. Configure the system ability.** 168 169Configure the profile of the system ability so that the system ability can be loaded and registered. The configuration procedure is as follows: 170 171Create a folder named **sa_profile** in the root directory of the subsystem. Then, create two files in this folder, including an XML file prefixed with the service ID of the system ability and a **BUILD.gn** file. 172 173Sample *serviceid*.xml file: 174 175``` 176 177 178 <process>listen_test</process> 179 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 186 187``` 188 189Sample **BUILD.gn** file: 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 = "systemabilitymgr" 198} 199``` 200 201>**NOTE**<br/> 202>- Set **process** to the name of the process where the system ability will run. This parameter is mandatory. 203>- The *serviceid*.xml file can contain only one **systemability** node. Multiple **systemability** nodes will cause a build failure. 204>- Set **name** to the service ID registered in the code for the system ability. This parameter is mandatory. 205>- Set **libpath** to the path for loading the system ability. This parameter is mandatory. 206>- Set **run-on-create** to **true** if you want to register this system ability with the **samgr** module immediately after the process is started. Set it to **false** if you want the system ability to start only when it is accessed. This parameter is mandatory. 207>- Set **distributed** to **true** if this system ability allows cross-device access. Set it to **false** if it allows IPC only on the local device. 208>- **bootphase** specifies the startup priority of the system ability. The value can be **BootStartPhase** (highest), **CoreStartPhase**, or **OtherStartPhase** (lowest). In the same process, system abilities of a lower priority can be started and registered only after those of a higher priority have all been started and registered. This parameter is optional. The default value is **OtherStartPhase**. 209>- **dump-level** specifies the level supported by the system dumper. The default value is **1**. 210>- In the **BUILD.gn** file, set **subsystem_name** to the subsystem name, and add the list of system abilities to be configured for the subsystem in **sources**. Multiple system abilities can be configured. 211 212After the preceding steps are complete, an XML file named by the process will be generated in the **out**, for example, **out\...\system\profile\listen_test.xml**. 213 214**6. Configure the .cfg file.** 215 216The .cfg file contains the native process startup policy provided by Linux. During the system startup process, the init process parses the .cfg file to start the native process. 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>**NOTE**<br/> 238>For details about the implementation of listen_ability, see **test/services/safwk/unittest/common/listen_ability**. 239 240## Repositories Involved<a name="section1371113476307"></a> 241 242**System Ability Management Subsystem** 243 244[**systemabilitymgr\_safwk**](https://gitee.com/openharmony/systemabilitymgr_safwk) 245 246[systemabilitymgr\_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr) 247 248[systemabilitymgr\_safwk\_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite) 249 250[systemabilitymgr\_samgr\_lite](https://gitee.com/openharmony/systemabilitymgr_samgr_lite) 251