1# OpenHarmony Component Design Guide
2
3## Basic Concepts
4
5For easy software design and management, OpenHarmony decouples software from images, components (named components originally), and modules. Their relationship is shown below.
6
7![](figures/Component-Module.png)
8
9### Component Definition
10
11OpenHarmony abstracts system capabilities as components, so you can customize OSs for different devices by assembling and configuring these components.
12
13A component is the basic unit of system capabilities. Divided based on source code, every component has independent files and directories, and can be instantiated into libraries or executable files on different devices.
14
15The introduction of components is to enable a set of OS code to support a variety of product forms, thereby solving the problem of hardware and product fragmentation in different industries and improving the device development efficiency.
16
17![](figures/Component-Definition.png)
18
19## Component Design
20
21### Component Classification Rules
22
23When developing a new function that is optional and can be tailored, add a component, rather than a module. In addition, observe the following rules:
24
25- A component must have an independent code directory for compiling libraries or executable files.
26- A component must be able to be independently deployed in the small system or standard system. Optional functions can be tailored without causing system exceptions.
27- A component must be able to be independently tested and verified.
28
29### **Rules and Recommendations**
30
31Comply with the following rules and recommendations during component design:
32
33**Rule 1.1** Components must be developed individually to ensure decoupling and independence.
34
35**Rule 1.2** A common component should not depend on a specific chip, development board, or product form, except for a component related to drivers and kernels.
36
37**Rule 1.3** All components in the minimum system component set are mandatory. They should not depend on an optional component outside the minimum system component set.
38
39> For details about the definition of the minimum system and the minimum system component set, see **PCS** in [OpenHarmony Product Compatibility Specifications](https://www.openharmony.cn/certification/document/pcs).
40
41**Rule 1.4** New components must be reviewed by architects and designers in the respective domain.
42
43**Rule 1.5** Reverse dependency and cyclic dependency between components are prohibited. Lower-layer components must not depend on upper-layer components.
44
45**Rule 1.6** Application APIs provided by a component must be stable and compatible with earlier versions. Deprecated APIs must be reclaimed as planned.
46
47**Rule 1.7** External APIs provided by a component must be the same regardless of whether the configurable features of the component are configured.
48
49**Rule 1.8** The component name must reflect the key function of a component and must be globally unique in the system. The name can contain a maximum of 63 characters and must be in the unix_like style, where only lowercase letters separated by underscores (\_) are used.
50
51**Rule 1.9** The component repository must be named in the format of <Subsystem\>\_<Component\>. For example, the repository name of the storage service component in the file management subsystem is **filemanagement\_storage\_service**. The repository name can contain a maximum of 100 characters.
52
53> **NOTE**
54>
55> 1. In principle, there is a one-to-one mapping between components and repositories. In some cases, multiple components can share a repository, but they must have independent directories.
56>
57> 2. For a third-party open source component, retain the original component name, and add the prefix **third_party** to the repository name. All third-party open source components are stored in the **third_party** directory.
58>
59> 3. The subsystem names in the repository name and path should not contain underscores (\_).
60
61**Rule 1.10**: The component source code path must be in the format of <Domain\>/<Subsystem\>/<Component\>, for example, **foundation/filemanagement/storage_service**.
62
63**Rule 1.11** The component directory structure must be as follows:
64
65```xml
66├── interfaces          # APIs
67│   ├── kits			# Application APIs (optional)
68│   │    ├── js			# JS APIs (optional)
69│   │    └── native  	# C/C++ APIs (optional)
70│   └── inner_api       # Internal APIs of components
71├── frameworks          # Implementation of components without independent processes (optional)
72│   ├── native          # C/C++ API implementation (optional)
73│   └── js              #  JS API implementation (optional)
74│        ├── napi       # Native API implementation (optional)
75│        ├── builtin	# Specific to LiteOS-M (optional)
76│        └── plugin     # Specific to ArkUI (optional)
77├── services            # Implementation of components with independent processes (optional)
78├── test                # Test code (mandatory)
79├── BUILD.gn            # Entry to build (mandatory)
80└── bundle.json         # Component description file (mandatory)
81```
82
83**Rec 1.1** Components should support automated build and verification.
84
85### System Capabilities
86
87System capabilities are provided by components. A system capability can be bound to one or more APIs. System capabilities function as a bridge between device development and application development. The differences in devices assembled with various components are represented by different system capabilities. In other words, the APIs that can be used vary according to the device in use. The figure below shows how system capabilities are used in the entire development process.
88
89![](figures/Component-SysCap.png)
90
911. An application developer uses the normalized SDK that supports multiple devices to develop an application. The SDK contains a full set of system capabilities (optional and mandatory) and corresponding APIs.
92
932. A device developer assembles optional components and adds private components to form the system capability set of a device.
94
953. The system capability set is automatically written to the device during compilation and packaging.
96
974. A Product Compatibility ID (PCID) is automatically generated during device compilation. When developing an application for a specific device, the application developer imports the PCID to DevEco Studio to obtain the system capability set of the device during development.
98
995. A Required Product Compatibility ID (RPCID), a set of system capabilities required by the application, is automatically generated during application compilation and packaging.
100
1016. When distributing an application, the application market matches the application's RPCID against the device's PCID. It distributes the application to that device only if the application's RPCID is within the device's PCID.
102
1037. In the ability continuation scenario, the system capabilities are synchronized between devices.
104
1058. In the installation-free scenario, the system capabilities of a device can be queried on the cloud.
106
107#### Using System Capabilities During Application Development
108
109An application developer can call the **CanIUse** API to query the system capabilities of a device at runtime. The code snippet is as follows:
110
111```javascript
112import geolocation from '@ohos.geolocation'
113
114const isLocationAvailable = canIUse('SystemCapability.Location.Location');
115if (isLocationAvailable) {
116    geolocation.getCurrentLocation((location) => {
117        console.log(location.latitude, location.longitue);
118    });
119} else {
120    console.log('Location not by this device.')
121}
122```
123
124The SDK defines the system capability set for typical device types. If a device type is selected during application development and the API called exceeds the range supported by the mandatory system capabilities of the device type, DevEco Studio displays a message indicating that the API is not supported by the device and the application compilation will fail.
125
126#### Defining System Capabilities During Device Development
127
128There is a one-to-one relationship between components and system capabilities, and the APIs mapped to different system capabilities do not overlap. A system capability must be named in the format of SystemCapability.Category. Feature.Subfeature (optional), for example, **SystemCapability.Media.Camera** and **SystemCapability.Media.Camera.Front**. Generally, a subfeature is implemented by an independent component. This component depends on a component that provides the basic feature, and therefore the dependent component must also be assembled into the product.
129
1301. Declare the system capability in the **bundle.json** file of the component. The code snippet is as follows:
131
132   ```json
133   {
134     ...
135     "component": {
136       "name": "camera",                              # Component name.
137       "syscap": [ "SystemCapability.Media.Camera" ]  # System capability of the component.
138     },
139     ...
140   }
141   ```
142
1432. Declare the system capability attribute of the API in the corresponding .d.ts file for binding. The code snippet is as follows:
144
145   ```js
146   /**
147    * @name camera
148    * @syscap SystemCapability.Media.Camera
149    * @ since 9
150    */
151   declare namespace camera {
152       ...
153   }
154   ```
155
156### Component Review
157
158The addition, modification (function or interface changes), and deletion of components must be reviewed by the architecture SIG and [related domain SIGs](https://gitee.com/openharmony/community/tree/master/sig). The review process is as follows:
159
1601. Prepare the following component attribute review form.
161
162   Table 1 Component attribute review form
163
164   | Component Attribute    | Description                                                        |
165   | ------------ | ------------------------------------------------------------ |
166   | Component name    | The name must reflect the key function of a component and must be globally unique in the system. The name can contain a maximum of 63 characters and must be in the unix\_like style, where only lowercase letters separated by underscores (\_) are used.|
167   | Subsystem      | Subsystem to which the component belongs.                                          |
168   | Function description    | Brief description of the functions of the component in one or two sentences.                         |
169   | Configurable features  | Features that can be configured externally.                                      |
170   | SysCap       | System capability, for example, **SystemCapability.Media.Camera** or **SystemCapability.Media.Camera.Front**.|
171   | Applicable systems| Mini system, small system, standard system, or their combinations.    |
172   | Source code directory    | Root directory of the source code of the component.                                          |
173   | ROM          | ROM baseline value of the component.                                       |
174   | RAM          | RAM baseline value of the component.                                       |
175   | Dependencies        | Components and open source software on which the component depends.                              |
176
177
1782. Send an email to the architecture SIG (dev@openharmony.io) and the [related domain SIG leaders](https://gitee.com/openharmony/community/tree/master/sig) for review. Use "Applying for Adding/Modifying/Deleting OpenHarmony Components" as the email subject, and include the filled-in **Table 1 Component Attribute Review Form** in the email body.
179
180   > For deleted components, provide the plan for stopping component maintenance. Exercise caution when deleting or modifying components and evaluate the impact on existing versions.
181
1823. After the review is passed, create a component repository and modify the manifest according to [SIG Management Regulations](https://gitee.com/openharmony/community/blob/master/sig/README_EN.md). After the SIG is incubated, incorporate it into the main code library of OpenHarmony.
183
184## Component Development
185
186After the component passes the review, the component name, repository, and source code path are determined. You can perform component development as follows:
187
188### Adding a Description File
189
190In the development state, create a **bundle.json** file in the root directory of the component. The file contains the component name, compilation, test, system capability, features, and internal interfaces. For details about the fields, see [Description File](../device-dev/subsystems/subsys-build-component-building-rules.md#description-file). The code snippet is as follows:
191
192```json
193{
194    "name": "@ohos/my_component",
195    "description": "my first component",
196    "version": "4.0",
197    "license": "Apache License 2.0",
198    "publicAs": "code-segment",
199    "segment": {
200        "destPath": "my_domain/my_subsystem/my_component"
201    },
202    "component": {
203        "name": "my_component",
204        "subsystem": "my_subsystem",
205        "syscap": [
206            "SystemCapability.MySubsystem.MyComponent"
207        ],
208        "build": {
209            "moudles": [
210                "//my_domain/my_subsystem/my_component/my_module:my_module"
211            ],
212            "inner_api": [
213                "name": "//my_domain/my_subsystem/my_component/my_module:inner_api",
214                "header_base": "//my_domain/my_subsystem/my_component/interfaces/inner_api/my_module"
215            ],
216            "test": [
217                "//my_domain/my_subsystem/my_component:unit_test"
218            ]
219        }
220    }
221}
222```
223
224**inner_api** is an interface declared by the component for dependency between components within the system. The dependency must be specified in **external_deps**. The following is an example:
225
226```c
227ohos_executable("other_component") {
228    ...
229    external_deps = [ "my_module:inner_api" ]
230}
231```
232
233### Adding a Compilation Script
234
235In the **bundle.json** file, **build:modules** provides the component compilation entry. The following is an example of the compilation script of the **my_module** module in the dynamic library:
236
237```c
238ohos_shared_library("my_module") {
239  sources = [ ... ]
240  ...
241  external_deps = [ ... ]
242
243  part_name = "my_component"
244  subsystem_name = "my_subsystem"
245}
246```
247
248The component compilation script must comply with component-based requirements. For details, see [Component Building Specifications](../device-dev/subsystems/subsys-build-component-building-rules.md#component-building-specifications).
249
250### Compilation Verification
251
252After adding the description file and compilation script of the component, compile the code source to develop the functions of the component. To enable the compilation of a component, configure the component in the product configuration file. The following is an example:
253
254```json
255{
256  "product_name": "my_product",
257  "device_company": "my_device_company",
258  "target_cpu": "arm",
259  ...
260  "subsystems": [
261    {
262      "subsystem": "my_subsystem",
263      "components": [
264        {
265          "component": "my_component"
266        }
267      ]
268    },
269  ...
270  ]
271}
272```
273
274The following code snippet is used to compile a component separately:
275
276```c
277./build.sh --product-name my_product --build-target my_domain/my_subsystem/my_component/my_module:my_module
278```
279
280Upload the compilation products and test cases of the component to the device to verify the functions.
281
282Full compilation can also be used to verify a new component. For details, see [Adding and Compiling Components](../device-dev/subsystems/subsys-build-component.md#adding-and-building-a-component).
283
284## Assembling Components
285
286The product configuration file ***vendor*/*{company}*/*{product}*/config.json** can be used to assemble a product form based on the component and feature dimensions. It allows device developers to quickly build a product without intrusively modifying OpenHarmony source code. The product configuration includes the product name, development board, subsystems, and components. The following is an example:
287
288```json
289{
290  "product_name": "my_product",
291  "device_company": "my_device_company",
292  "target_cpu": "arm64",
293  "subsystems": [
294    {
295      "subsystem": "my_subsystem",
296      "components": [
297        {
298          "component": "my_component",
299          "features": []
300        }
301      ]
302    },
303    ...
304   ]
305}
306```
307
308The compilation command is **./build.sh --product-name my_product**.
309
310### Determining Whether a Component Is Required
311
312A component set can be configured for a product based on hardware and product functions. For example, NFC-related components are not configured on a device that does not need to provide the NFC feature.
313
314> **NOTE**
315>
316> 1. The minimum system component set must be configured by default.
317>
318> 2. A component and its dependent components must be configured together. Otherwise, the compilation fails.
319
320### Configuring Features
321
322#### During Compilation
323
324A feature in the **bundle.json** file of a component is the compilation state option declared by the component. It can be of the Boolean, numeric, or string type. The feature in the product configuration file can be changed to the default value provided by the component. For example, the screen saver feature of power management is disabled by default. You can enable it in the product as follows:
325
326```json
327{
328  {
329    "subsystem": "powermgr",
330    "components": [
331      { "component": "powermgr", "features":[ "powermgr_screensaver_enable = true" ] }
332    ]
333  }
334}
335```
336
337For details about the feature configuration, see [Feature](../device-dev/subsystems/subsys-build-feature.md).
338
339#### Runtime
340
341For complex components, system parameters can be read or custom configuration files can be used during runtime to load different features, thereby meeting diverse product requirements. With feature configuration at the runtime, a component needs to be compiled only once. For different products, you only need to modify system parameters or configuration files during assembly and then create images.
342
343### Inheritance
344
345The product configuration file can inherit the component set through the **inherit** field. Currently, OpenHarmony provides two types of components: minimum system component set and typical product form set, which are defined in the **productdefine/common/base** and **productdefine/common/inherit** directories, respectively. The following is an example of inheriting the minimum system component set:
346
347```json
348{
349    "inherit": [ "productdefine/common/base/standard_system.json" ],
350}
351```
352
353Inheritance can simplify product configuration and improve efficiency.
354