• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# safwk<a name="EN-US_TOPIC_0000001115588558"></a>
2
3-   [Introduction](#section11660541593)
4-   [Directory Structure](#section161941989596)
5-   [Usage](#section1312121216216)
6    -   [Available APIs](#section1551164914237)
7    -   [Usage Guidelines](#section129654513264)
8
9-   [Repositories Involved](#section1371113476307)
10
11## Introduction<a name="section11660541593"></a>
12
13The  **safwk**  module of the Distributed Scheduler subsystem defines how to implement a  **SystemAbility**  in OpenHarmony and provides APIs for system ability startup and registration.
14
15## Directory Structure<a name="section161941989596"></a>
16
17```
18/foundation/distributedschedule
19│── safwk                # Directory for the safwk module
20│  ├── ohos.build       # Compilation script for safwk
21│  ├── interfaces       # APIs exposed externally
22│  ├── services         # Service implementation
23```
24
25## Usage<a name="section1312121216216"></a>
26
27### Available APIs<a name="section1551164914237"></a>
28
29<a name="table775715438253"></a>
30<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>
31</th>
32<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>
33</th>
34</tr>
35</thead>
36<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&lt;IRemoteObject&gt; GetSystemAbility(int32_t systemAbilityId);</p>
37</td>
38<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 specified system ability.</p>
39</td>
40</tr>
41<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&lt;IRemoteObject&gt; systemAbility);</p>
42</td>
43<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 specified system ability.</p>
44</td>
45</tr>
46<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&amp; profilePath) = 0;</p>
47</td>
48<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>Enables a system ability based on the SA profile information.</p>
49</td>
50</tr>
51<tr id="row159634125718"><td class="cellrowborder" valign="top" width="43.19%" headers="mcps1.1.3.1.1 "><p id="p10596134105710"><a name="p10596134105710"></a><a name="p10596134105710"></a>void OnConnectedSystemAbility(const sptr&lt;IRemoteObject&gt;&amp; connectionCallback);</p>
52</td>
53<td class="cellrowborder" valign="top" width="56.81%" headers="mcps1.1.3.1.2 "><p id="p105961241125713"><a name="p105961241125713"></a><a name="p105961241125713"></a>Called when a system ability is connected.</p>
54</td>
55</tr>
56<tr id="row611715428577"><td class="cellrowborder" valign="top" width="43.19%" headers="mcps1.1.3.1.1 "><p id="p10118242155716"><a name="p10118242155716"></a><a name="p10118242155716"></a>void OnDisConnectedSystemAbility(int32_t systemAbilityId);</p>
57</td>
58<td class="cellrowborder" valign="top" width="56.81%" headers="mcps1.1.3.1.2 "><p id="p81189429578"><a name="p81189429578"></a><a name="p81189429578"></a>Called when a system ability is disconnected.</p>
59</td>
60</tr>
61</tbody>
62</table>
63
64### Usage Guidelines<a name="section129654513264"></a>
65
66System abilities can be implemented in both C++ and Java languages. In C++, you must define the  _XXX_**.rc**,  **profile.xml**, and  **lib**_XXX_**.z.so**  files to declare the system ability, and the init process executes the specified  _XXX_**.rc**  file to start the process of the particular system ability. Similar to the implementation in C++, the system ability process is started by  [the foundationserver module](en-us_topic_0000001078878484.md)  in Java.
67
68**Implementing a System Ability in C++**
69
70-   **Define the  _IXXX_  class for IPC.**
71
72This  _IXXX_  class is used to define the functions for the system ability to provide specific capabilities. To define this class, implement the  **IRemoteBroker**  interface provided by OpenHarmony for inter-process communication \(IPC\). In addition, implement the  **DECLARE\_INTERFACE\_DESCRIPTOR\(_XXX_\)**  that uniquely identifies this class. The identifier is used for purposes such as IPC communication verification.
73
74The following example shows how to define the  **IListenAbility**  class for testing in the Distributed Scheduler subsystem:
75
76```
77namespace OHOS {
78class IListenAbility : public IRemoteBroker {
79public:
80    virtual int AddVolume(int volume) = 0;
81
82public:
83    enum {
84        ADD_VOLUME = 1,
85    };
86public:
87    DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.IListenAbility");
88};
89}
90```
91
92-   **Define the  _XXX_Proxy class for client communication.**
93
94```
95namespace OHOS {
96class ListenAbilityProxy : public IRemoteProxy<IListenAbility> {
97public:
98    int AddVolume(int volume);
99
100    explicit ListenAbilityProxy(const sptr<IRemoteObject>& impl)
101        : IRemoteProxy<IListenAbility>(impl)
102    {
103    }
104
105private:
106    static inline BrokerDelegator<ListenAbilityProxy> delegator_;
107};
108} // namespace OHOS
109```
110
111-   **Define the  _XXX_Stub class for server communication.**
112
113```
114namespace OHOS {
115int32_t ListenAbilityStub::OnRemoteRequest(uint32_t code,
116    MessageParcel& data, MessageParcel &reply, MessageOption &option)
117{
118    switch (code) {
119        case ADD_VOLUME: {
120            return reply.WriteInt32(AddVolume(data.ReadInt32()));
121        }
122
123        default:
124            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
125    }
126}
127}
128```
129
130-   **Implement a system ability.**
131
132```
133namespace {
134constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "SA_TST"};
135}
136
137REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility, DISTRIBUTED_SCHED_TEST_LISTEN_ID, true);
138
139ListenAbility::ListenAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate)
140{
141    HiLog::Info(LABEL, ":%s called", __func__);
142    HiLog::Info(LABEL, "ListenAbility()");
143}
144
145ListenAbility::~ListenAbility()
146{
147    HiLog::Info(LABEL, "~ListenAbility()");
148}
149
150int ListenAbility::AddVolume(int volume)
151{
152    pid_t current = getpid();
153    HiLog::Info(LABEL, "ListenAbility::AddVolume volume = %d, pid = %d.", volume, current);
154    return (volume + 1);
155}
156
157void ListenAbility::OnDump()
158{
159}
160
161void ListenAbility::OnStart()
162{
163    HiLog::Info(LABEL, "ListenAbility::OnStart()");
164    HiLog::Info(LABEL, "ListenAbility:%s called:-----Publish------", __func__);
165    bool res = Publish(this);
166    if (res) {
167        HiLog::Error(LABEL, "ListenAbility: res == false");
168    }
169    HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----beg-----", __func__);
170    AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID);
171    HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----end-----", __func__);
172
173    HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----beg-----", __func__);
174    StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID);
175    HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----end-----", __func__);
176    return;
177}
178
179void ListenAbility::OnStop()
180{
181}
182```
183
184-   **Configure the system ability.**
185
186If the system ability is implemented in C++, you must define a profile for it so that it can be loaded and registered. The configuration procedure is as follows:
187
188Create 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.
189
190Sample  _serviceid_**.xml**  file:
191
192```
193<?xml version="1.0" encoding="UTF-8"?>
194<info>
195    <process>listen_test</process>
196    <systemability>
197    <name>serviceid</name>
198    <libpath>/system/lib64/liblistentest.z.so</libpath>
199    <run-on-create>true</run-on-create>
200    <distributed>false</distributed>
201    <dump-level>1</dump-level>
202</systemability>
203</info>
204```
205
206Sample  **BUILD.gn**  file:
207
208```
209import("//build/ohos/sa_profile/sa_profile.gni")
210ohos_sa_profile("xxx_sa_profile") {
211    sources = [
212        "serviceid.xml"
213    ]
214    subsystem_name = "distributedschedule"
215}
216```
217
218>**NOTE:**
219>1.  Set the  **process**  tag to the name of the process where the system ability will run. This tag is mandatory.
220>2.  Add only one  **systemability**  node in the profile of a system ability. If multiple  **systemability**  nodes are added, the building fails.
221>3.  Set the  **name**  tag to the service ID registered in the code for the system ability. This tag is mandatory.
222>4.  Set the  **libpath**  tag to the path for loading the system ability. This tag is mandatory.
223>5.  Set the  **run-on-create**  tag to  **true**  if you want to register this system ability with the  **samgr**  module immediately after the process is started. Set this tag to  **false**  if you want the system ability to start only when other modules access the system ability. This tag is mandatory.
224>6.  Set the  **distributed**  tag to  **true**  if this system ability allows cross-device access; set it to  **false**  if it allows IPC only on the local device.
225>7.  Set the  **def-permission**  tag to define the permissions, if any, required for the process on another device to access this system ability during cross-device RPC communication when  **distributed**  is set to  **true**. This tag is optional.
226>8.  Set the  **bootphase**  tag to define the startup priority of the system ability, which \(from high to low\) can be  **BootStartPhase**,  **CoreStartPhase**, or  **OtherStartPhase**  \(default value\). In the same process, the system ability of the  **BootStartPhase**  priority will be started first, then that of the  **CoreStartPhase**  priority, and finally the  **OtherStartPhase**  priority. System abilities of a lower priority can be started and registered only after those of a high priority have all been started and registered. This tag is optional.
227>9.  Set  **dump-level**  to  **1**, which indicates that the level is supported by the system dumper.
228>10. In the  **BUILD.gn**  file, set  **subsystem\_name**  to the name of the corresponding subsystem, and add the list of system abilities that need to be configured for the specified subsystem in  **sources**. Multiple system abilities can be configured.
229
230After the preceding files are configured and full code building is complete, a  **listen\_test.xml**  prefixed with the process name will be generated in the  **out**  directory. The path is  **out\\phone-release\\system\\profile\\listen\_test.xml**  in this example.
231
232-   **Configure the  _XXX_.rc file.**
233
234The  **_XXX_.rc**  configuration file defines the native process startup policy provided by Linux. The  **init**  process parses the configured  **_XXX_.rc**  file during device startup.
235
236```
237service listen_test /system/bin/sa_main /system/profile/listen_test.xml
238    class z_core
239    user system
240    group system shell
241    seclabel u:r:xxxx:s0
242```
243
244>**NOTE:**
245>For details about the implementation of  **listen\_ability**, see the code in  **test/unittest/common/listen\_ability**.
246
247## Repositories Involved<a name="section1371113476307"></a>
248
249[Distributed Scheduler subsystem](en-us_topic_0000001115719369.md)
250
251[dmsadapter](en-us_topic_0000001124134145.md)
252
253[dmsfwk](en-us_topic_0000001078718754.md)
254
255[foundationserver](en-us_topic_0000001078878484.md)
256
257**[safwk](safwk.md)**
258
259[samgr](en-us_topic_0000001124076649.md)
260
261