1# safwk
2## Introduction
3
4The System Ability Framework (safwk) component defines how to implement system abilities in OpenHarmony and provides APIs to start and register system abilities.
5
6## System Architecture
7
8**Figure 1** Architecture of safwk
9
10
11![](figures/en-us_image_0000001115820566.png)
12
13## Directory Structure
14
15```
16/foundation/systemabilitymgr
17│── safwk                # Directory of safwk
18│  ├── bundle.json      # Description and build file of safwk
19│  ├── etc              # Configuration files
20│  ├── interfaces       # APIs exposed externally
21│  ├── services         # Service implementation
22│  ├── test             # Test cases
23```
24
25## Usage
26
27### Available APIs
28
29| API                                                      | Description                              |
30| ------------------------------------------------------------ | -------------------------------------- |
31| sptr\<IRemoteObject> GetSystemAbility(int32_t systemAbilityId); | Obtains the remote procedure call (RPC) object of a system ability.           |
32| bool Publish(sptr\<IRemoteObject> systemAbility);            | Publishes a system ability.                        |
33| virtual void DoStartSAProcess(const std::string& profilePath) = 0; | Enables a system ability based on its profile.|
34
35### How to Use
36
37A system ability is implemented by using a XXX.cfg, a profile.json, and a libXXX.z.so. The init process starts the SystemAbility process by executing the corresponding XXX.cfg file.
38
39**Implementing a System Ability in C++**
40
41The sample code is as follows:
42
43**1. Define the *IXXX* class for IPC.**
44
45The *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.
46
47```
48namespace OHOS {
49class IListenAbility : public IRemoteBroker {
50public:
51    virtual int AddVolume(int volume) = 0;
52
53public:
54    enum {
55        ADD_VOLUME = 1,
56    };
57public:
58    DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.IListenAbility");
59};
60}
61```
62
63**2. Define the *XXX*Proxy class for client communication.**
64
65```
66namespace OHOS {
67class ListenAbilityProxy : public IRemoteProxy<IListenAbility> {
68public:
69    int AddVolume(int volume);
70
71    explicit ListenAbilityProxy(const sptr<IRemoteObject>& impl)
72        : IRemoteProxy<IListenAbility>(impl)
73    {
74    }
75
76private:
77    static inline BrokerDelegator<ListenAbilityProxy> delegator_;
78};
79} // namespace OHOS
80```
81
82**3. Define the *XXX*Stub class for server communication.**
83
84```
85namespace OHOS {
86int32_t ListenAbilityStub::OnRemoteRequest(uint32_t code,
87    MessageParcel& data, MessageParcel &reply, MessageOption &option)
88{
89    switch (code) {
90        case ADD_VOLUME: {
91            return reply.WriteInt32(AddVolume(data.ReadInt32()));
92        }
93
94        default:
95            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
96    }
97}
98}
99```
100
101**4. Implement a system ability.**
102
103```
104namespace {
105constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "SA_TST"};
106}
107
108REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility, DISTRIBUTED_SCHED_TEST_LISTEN_ID, true);
109
110ListenAbility::ListenAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate)
111{
112    HiLog::Info(LABEL, ":%s called", __func__);
113    HiLog::Info(LABEL, "ListenAbility()");
114}
115
116ListenAbility::~ListenAbility()
117{
118    HiLog::Info(LABEL, "~ListenAbility()");
119}
120
121int ListenAbility::AddVolume(int volume)
122{
123    pid_t current = getpid();
124    HiLog::Info(LABEL, "ListenAbility::AddVolume volume = %d, pid = %d.", volume, current);
125    return (volume + 1);
126}
127
128void ListenAbility::OnDump()
129{
130}
131
132void ListenAbility::OnStart()
133{
134    HiLog::Info(LABEL, "ListenAbility::OnStart()");
135    HiLog::Info(LABEL, "ListenAbility:%s called:-----Publish------", __func__);
136    bool res = Publish(this);
137    if (res) {
138        HiLog::Error(LABEL, "ListenAbility: res == false");
139    }
140    HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----beg-----", __func__);
141    AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID);
142    HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----end-----", __func__);
143
144    HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----beg-----", __func__);
145    StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID);
146    HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----end-----", __func__);
147    return;
148}
149
150void ListenAbility::OnStop()
151{
152}
153```
154
155**5. Configure the system ability.**
156
157Configure the profile of the system ability so that the system ability can be loaded and registered. The configuration procedure is as follows:
158
159Create a folder named **sa_profile** in the root directory of the subsystem. Then, create two files in this folder, including an json file prefixed with the service ID of the system ability and a **BUILD.gn** file.
160
161Sample *serviceid*.json file:
162
163```
164{
165    "process": "listen_test",
166    "systemability": [
167        {
168            "name": serviceid,
169            "libpath": "liblisten_test.z.so",
170            "run-on-create": true,
171            "distributed": true,
172            "dump_level": 1
173        }
174    ]
175}
176```
177
178Sample **BUILD.gn** file:
179
180```
181import("//build/ohos/sa_profile/sa_profile.gni")
182ohos_sa_profile("xxx_sa_profile") {
183    sources = [
184        "serviceid.json"
185    ]
186    subsystem_name = "systemabilitymgr"
187}
188```
189
190>**NOTE**
191>1.  Set **process** to the name of the process where the system ability will run. This parameter is mandatory.
192>2.  The *serviceid*.json file can contain only one **systemability** node. Multiple **systemability** nodes will cause a build failure.
193>3.  Set **name** to the service ID registered in the code for the system ability. This parameter is mandatory.
194>4.  Set **libpath** to the path for loading the system ability. This parameter is mandatory.
195>5.  Set **run-on-create** to **true** if you want to register this system ability with the Samgr component 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.
196>6.  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.
197>7.  **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**.
198>8.  **dump-level** specifies the level supported by the system dumper. The default value is **1**.
199>9. 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.
200
201After the preceding steps are complete, an json file named by the process will be generated in the **out**, for example, **out\...\system\profile\listen_test.json**.
202
203**6. Configure the .cfg file.**
204
205The .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.
206
207```
208{
209    "jobs" : [{
210            "name" : "post-fs-data",
211            "cmds" : [
212                "start listen_test"
213            ]
214        }
215    ],
216	"services" : [{
217            "name" : "listen_test",
218            "path" : ["/system/bin/sa_main", "/system/profile/listen_test.json"],
219            "uid" : "system",
220            "gid" : ["system", "shell"]
221        }
222    ]
223}
224```
225
226>**NOTE**
227>
228>For details about the implementation of listen_ability, see **test/services/safwk/unittest/common/listen_ability**.
229
230## Repositories Involved
231
232Samgr
233
234[**systemabilitymgr\_safwk**](https://gitee.com/openharmony/systemabilitymgr_safwk)
235
236[systemabilitymgr\_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr)
237
238[systemabilitymgr\_safwk\_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite)
239
240[systemabilitymgr\_samgr\_lite](https://gitee.com/openharmony/systemabilitymgr_samgr_lite)
241