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 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 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 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