1# IDL Specifications and User Guide (for System Applications Only) 2 3## IDL Overview 4To ensure successful communications between the client and server, interfaces recognized by both parties must be defined. The OpenHarmony Interface Definition Language (IDL) is a tool for defining such interfaces. IDL decomposes objects into primitives that can be understood by the operating system and encapsulates cross-boundary objects based on your requirements. 5 6**Figure 1** IDL interface description 7 8 9 10**IDL provides the following functions:** 11 12- Declares interfaces provided by system services for external systems, and based on the interface declaration, generates C, C++, JS, or TS code for inter-process communication (IPC) or remote procedure call (RPC) proxies and stubs during compilation. 13 14- Declares interfaces provided by abilities for external systems, and based on the interface declaration, generates C, C++, JS, or TS code for IPC or RPC proxies and stubs during compilation. 15 16**Figure 2** IPC/RPC communication model 17 18 19 20**IDL has the following advantages:** 21 22- Services are defined in the form of interfaces in IDL. Therefore, you do not need to focus on implementation details. 23 24- Interfaces defined by IDL can be used in IPC or RPC scenarios. The information or code generated based on the definitions in IDL simplifies IPC or RPC implementation. 25 26## IDL File Structure 27 28### Data Types 29 30#### Primitive Type 31| IDL Primitive Type| C++ Primitive Type| TS Primitive Type| 32| -------- | -------- | -------- | 33|void | void | void | 34|boolean | bool | boolean | 35|byte | int8_t | number | 36|short | int16_t | number | 37|int | int32_t | number | 38|long | int64_t | number | 39|float | float | number | 40|double | double | number | 41|String | std::string | string | 42 43The preceding table lists the primitive types supported by IDL and the mappings to the C++ and TS primitive types. 44 45#### sequenceable Type 46The sequenceable type is declared using the keyword **sequenceable**. This type can be passed during IPC or RPC through **Parcel** objects. The declaration mode of the sequenceable type in C++ is different from that in TS. 47 48In C++, the declaration is placed in the file header in the format of **sequenceable includedir..namespace.typename**. It can be in any of the following forms: 49 50```cpp 51sequenceable includedir..namespace.typename 52sequenceable includedir...typename 53sequenceable namespace.typename 54``` 55 56In the preceding information, **includedir** indicates the directory where the header file of the type is located, and the dot (.) is used as the separator. **namespace** indicates the namespace where the type is located, and the dot (.) is used as the separator. **typename** indicates the data type, which can contain only English characters. **includedir** and **namespace** are separated by two dots (..). If the declaration statement does not contain two dots, all characters except the last typename will be parsed as a namespace. Example: 57 58```cpp 59sequenceable a.b..C.D 60``` 61 62The preceding statement is parsed into the following code in the C++ header file: 63 64```cpp 65#include "a/b/d.h" 66using C::D; 67``` 68 69In TS, the declaration is placed in the file header in the format of **sequenceable namespace.typename;**. An example is provided below, where **idl** is the namespace and **MySequenceable** is the type name: 70 71```ts 72sequenceable idl.MySequenceable 73``` 74 75In the preceding information, **namespace** indicates the namespace to which the data type belongs, **typename** indicates the data type name, and **MySequenceable** indicates that data can be passed during IPC using **Parcel** objects. The sequenceable type is not defined in the IDL file, but in the .ts file. Therefore, IDL adds the following statement to the generated .ts file based on the declaration: 76 77```ts 78import MySequenceable from "./my_sequenceable" 79``` 80 81Note that IDL does not implement code for this type. It only imports the header file in the specified format or imports the specified module and uses the type. Therefore, you must ensure that the imported directory, namespace, and type are correct. 82 83#### Interface Type 84The interface type refers to interfaces defined in IDL files. The interfaces defined in an IDL file can be directly used as the parameter type or return value type of a method declared in the file. If an IDL file attempts to use interfaces defined in other IDL files, forward declaration must be contained in the header of that IDL file. 85 86The declaration form in C++ is similar to that of the sequenceable type. The declaration form is as follows: 87 88```cpp 89interface includedir..namespace.typename 90``` 91 92In TS, the declaration form is as follows: 93 94```ts 95interface namespace.interfacename 96``` 97 98In the preceding information, **namespace** indicates the namespace to which the interface belongs, and **interfacename** indicates the name of the interface. For example, **interface OHOS.IIdlTestObserver;** declares the **IIdlTestObserver** interface defined in another IDL file. This interface can be used as the parameter type or return value type of a method in the current file. IDL adds the following statement to the generated .ts file based on the statement: 99 100```ts 101import IIdlTestObserver from "./i_idl_test_observer" 102``` 103 104#### Array Type 105The array type is represented by T[], where **T** can be the primitive, sequenceable, interface, or array type. In C++, this type is generated as **std::vector<T>**. 106The table below lists the mappings between the IDL array type and TS and C++ data types. 107 108|IDL Data Type | C++ Data Type | TS Data Type | 109| ------- | -------- | -------- | 110|T[] | std::vector<T> | T[] | 111 112#### Container Type 113IDL supports two container types: List and Map. The List container is represented in the format of **List<T>**. The Map container is represented in the format of **Map<KT,VT>**, where **T**, **KT**, and **VT** can be of the primitive, sequenceable, interface, array, or container type. 114 115In C++, the List container type is generated as **std::list**, and the Map container type is generated as **std::map**. 116 117In TS, the List container type is not supported, and the Map container type is generated as **Map**. 118 119The table below lists the mappings between the IDL container type and TS and C++ data types. 120 121|IDL Data Type | C++ Data Type | TS Data Type | 122| -------- | -------- | ------- | 123|List<T> | std::list | Not supported | 124|Map<KT,VT> | std::map | Map | 125 126 127### Specifications for Compiling IDL Files 128Only one interface type can be defined in an IDL file, and the interface name must be the same as the file name. The interface definition of the IDL file is described in Backus-Naur form (BNF). The basic definition format is as follows: 129 130``` 131[<*interface_attr_declaration*>]interface<*interface_name_with_namespace*>{<*method_declaration*>} 132``` 133 134In the preceding information, <*interface_attr_declaration*> declares interface attributes. Currently, only the **oneway** attribute is supported, indicating that all methods in the interface are unidirectional. Such a method returns value without waiting for the execution to complete. This attribute is optional. If this attribute is not set, synchronous call is used. The interface name must contain the complete interface header file directory, namespace, and method declaration. Null interfaces are not allowed. 135The method declaration format in the interface is as follows: 136 137``` 138[<*method_attr_declaration*>]<*result_type*><*method_declaration*> 139``` 140 141In the preceding information, <*method_attr_declaration*> describes the interface attributes. Currently, only the **oneway** attribute is supported, indicating that the method is unidirectional. Such a method returns value without waiting for the execution to complete. This attribute is optional. If this attribute is not set, synchronous call is used. <*result_type*> indicates the type of the return value, and <*method_declaration*> indicates the method name and parameter declaration. 142The parameter declaration format is as follows: 143 144``` 145[<*formal_param_attr*>]<*type*><*identifier*> 146``` 147 148The value of <*formal_param_attr*> can be **in**, **out**, or **inout**, indicating that the parameter is an input parameter, an output parameter, or both an input and an output parameter, respectively. A **oneway** method does not allow **output** or **inout** parameters or return values. 149 150## How to Develop 151 152### Obtaining IDL 153On DevEco Studio, choose **Tools > SDK Manager** to view the local installation path of the OpenHarmony SDK. The following figure uses DevEco Studio 3.0.0.993 as an example. 154 155 156 157 158 159Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder named after the version number), and check whether the executable file of IDL exists. 160 161> **NOTE** 162> 163> Use the SDK of the latest version. The use of an earlier version may cause errors in some statements. 164 165If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md) as an example. 166 167For details about how to replace the SDK package, see [Full SDK Compilation Guide](../faqs/full-sdk-compile-guide.md). 168 169After obtaining the executable file, perform subsequent development steps based on your scenario. 170 171### Development Using TS 172 173#### Creating an IDL File 174 175You can use TS to create IDL files. 176 177 For example, create a file named **IIdlTestService.idl** with the following content: 178 179```cpp 180 interface OHOS.IIdlTestService { 181 int TestIntTransaction([in] int data); 182 void TestStringTransaction([in] String data); 183 void TestMapTransaction([in] Map<int, int> data); 184 int TestArrayTransaction([in] String[] data); 185 } 186``` 187 188Run the **idl -gen-ts -d *dir* -c dir/IIdlTestService.idl** command in the folder where the executable file is located. 189 190-*dir* next to **d** is the target output folder. For example, if the target output folder is **IIdlTestServiceTs**, run the **idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl** command in the folder where the executable file is located. The interface file, stub file, and proxy file are generated in the *dir* directory (**IIdlTestServiceTs** directory in this example) in the execution environment. 191 192> **NOTE** 193> 194> The generated interface class file name must be the same as that of the .idl file. Otherwise, an error occurs during code generation. 195 196For example, for an .idl file named **IIdlTestService.idl** and target output directory named **IIdlTestServiceTs**, the directory structure is similar to the following: 197 198``` 199├── IIdlTestServiceTs # IDL code output folder 200│ ├── i_idl_test_service.ts # File generated 201│ ├── idl_test_service_proxy.ts # File generated 202│ ├── idl_test_service_stub.ts # File generated 203│ └── IIdlTestService.idl # Constructed .idl file 204└── idl.exe # Executable file of IDL 205``` 206 207#### Exposing Interfaces on the Server 208 209The stub class generated by IDL is an abstract implementation of the interface class and declares all methods in the IDL file. 210 211```ts 212import {testIntTransactionCallback} from "./i_idl_test_service"; 213import {testStringTransactionCallback} from "./i_idl_test_service"; 214import {testMapTransactionCallback} from "./i_idl_test_service"; 215import {testArrayTransactionCallback} from "./i_idl_test_service"; 216import IIdlTestService from "./i_idl_test_service"; 217import rpc from "@ohos.rpc"; 218 219export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdlTestService { 220 constructor(des: string) { 221 super(des); 222 } 223 224 async onRemoteMessageRequest(code: number, data: rpc.MessageSequence, reply: rpc.MessageSequence, 225 option: rpc.MessageOption): Promise<boolean> { 226 console.log("onRemoteMessageRequest called, code = " + code); 227 if (code == IdlTestServiceStub.COMMAND_TEST_INT_TRANSACTION) { 228 let _data = data.readInt(); 229 this.testIntTransaction(_data, (errCode: number, returnValue: number) => { 230 reply.writeInt(errCode); 231 if (errCode == 0) { 232 reply.writeInt(returnValue); 233 } 234 }); 235 return true; 236 } else if (code == IdlTestServiceStub.COMMAND_TEST_STRING_TRANSACTION) { 237 let _data = data.readString(); 238 this.testStringTransaction(_data, (errCode: number) => { 239 reply.writeInt(errCode); 240 }); 241 return true; 242 } else if (code == IdlTestServiceStub.COMMAND_TEST_MAP_TRANSACTION) { 243 let _data: Map<number, number> = new Map(); 244 let _dataSize = data.readInt(); 245 for (let i = 0; i < _dataSize; ++i) { 246 let key = data.readInt(); 247 let value = data.readInt(); 248 _data.set(key, value); 249 } 250 this.testMapTransaction(_data, (errCode: number) => { 251 reply.writeInt(errCode); 252 }); 253 return true; 254 } else if (code == IdlTestServiceStub.COMMAND_TEST_ARRAY_TRANSACTION) { 255 let _data = data.readStringArray(); 256 this.testArrayTransaction(_data, (errCode: number, returnValue: number) => { 257 reply.writeInt(errCode); 258 if (errCode == 0) { 259 reply.writeInt(returnValue); 260 } 261 }); 262 return true; 263 } else { 264 console.log("invalid request code" + code); 265 } 266 return false; 267 } 268 269 testIntTransaction(data: number, callback: testIntTransactionCallback): void{} 270 testStringTransaction(data: string, callback: testStringTransactionCallback): void{} 271 testMapTransaction(data: Map<number, number>, callback: testMapTransactionCallback): void{} 272 testArrayTransaction(data: string[], callback: testArrayTransactionCallback): void{} 273 274 static readonly COMMAND_TEST_INT_TRANSACTION = 1; 275 static readonly COMMAND_TEST_STRING_TRANSACTION = 2; 276 static readonly COMMAND_TEST_MAP_TRANSACTION = 3; 277 static readonly COMMAND_TEST_ARRAY_TRANSACTION = 4; 278} 279``` 280 281You need to inherit the interface class defined in the IDL file and implement the methods in the class. The following code snippet shows how to inherit the **IdlTestServiceStub** interface class and implement the **testIntTransaction**, **testStringTransaction**, **testMapTransaction**, and **testArrayTransaction** methods. 282 283```ts 284import {testIntTransactionCallback} from "./i_idl_test_service" 285import {testStringTransactionCallback} from "./i_idl_test_service" 286import {testMapTransactionCallback} from "./i_idl_test_service"; 287import {testArrayTransactionCallback} from "./i_idl_test_service"; 288import IdlTestServiceStub from "./idl_test_service_stub" 289 290 291class IdlTestImp extends IdlTestServiceStub { 292 293 testIntTransaction(data: number, callback: testIntTransactionCallback): void 294 { 295 callback(0, data + 1); 296 } 297 testStringTransaction(data: string, callback: testStringTransactionCallback): void 298 { 299 callback(0); 300 } 301 testMapTransaction(data: Map<number, number>, callback: testMapTransactionCallback): void 302 { 303 callback(0); 304 } 305 testArrayTransaction(data: string[], callback: testArrayTransactionCallback): void 306 { 307 callback(0, 1); 308 } 309} 310``` 311 312After the service implements the interface, the interface needs to be exposed to the client for connection. If your service needs to expose this interface, extend **Ability** and implement **onConnect()** to return **IRemoteObject** so that the client can interact with the service process. The following code snippet shows how to expose the **IRemoteAbility** interface to the client: 313 314```ts 315import Want from '@ohos.app.ability.Want'; 316import rpc from "@ohos.rpc"; 317 318class ServiceAbility { 319 onStart() { 320 console.info('ServiceAbility onStart'); 321 } 322 onStop() { 323 console.info('ServiceAbility onStop'); 324 } 325 onCommand(want: Want, startId: number) { 326 console.info('ServiceAbility onCommand'); 327 } 328 onConnect(want: Want) { 329 console.info('ServiceAbility onConnect'); 330 try { 331 console.log('ServiceAbility want:' + typeof(want)); 332 console.log('ServiceAbility want:' + JSON.stringify(want)); 333 console.log('ServiceAbility want name:' + want.bundleName) 334 } catch(err) { 335 console.log('ServiceAbility error:' + err) 336 } 337 console.info('ServiceAbility onConnect end'); 338 return new IdlTestImp('connect') as rpc.RemoteObject; 339 } 340 onDisconnect(want: Want) { 341 console.info('ServiceAbility onDisconnect'); 342 console.info('ServiceAbility want:' + JSON.stringify(want)); 343 } 344} 345 346export default new ServiceAbility() 347``` 348 349#### Calling Methods from the Client for IPC 350 351When the client calls **connectServiceExtensionAbility()** to connect to a ServiceAbility, the **onConnect** callback in **onAbilityConnectDone** of the client receives the **IRemoteObject** instance returned by the **onConnect()** method of the ServiceAbility. The client and ServiceAbility are in different applications. Therefore, the directory of the client application must contain a copy of the .idl file (the SDK automatically generates the proxy class). The **onConnect** callback then uses the **IRemoteObject** instance to create the **testProxy** instance of the **IdlTestServiceProxy** class and calls the related IPC method. The sample code is as follows: 352 353```ts 354import common from '@ohos.app.ability.common'; 355import Want from '@ohos.app.ability.Want'; 356import IdlTestServiceProxy from './idl_test_service_proxy' 357 358function callbackTestIntTransaction(result: number, ret: number): void { 359 if (result == 0 && ret == 124) { 360 console.log('case 1 success'); 361 } 362} 363 364function callbackTestStringTransaction(result: number): void { 365 if (result == 0) { 366 console.log('case 2 success'); 367 } 368} 369 370function callbackTestMapTransaction(result: number): void { 371 if (result == 0) { 372 console.log('case 3 success'); 373 } 374} 375 376function callbackTestArrayTransaction(result: number, ret: number): void { 377 if (result == 0 && ret == 124) { 378 console.log('case 4 success'); 379 } 380} 381 382let onAbilityConnectDone: common.ConnectOptions = { 383 onConnect: (elementName, proxy) => { 384 let testProxy: IdlTestServiceProxy = new IdlTestServiceProxy(proxy); 385 let testMap: Map<number, number> = new Map(); 386 testMap.set(1, 1); 387 testMap.set(1, 2); 388 testProxy.testIntTransaction(123, callbackTestIntTransaction); 389 testProxy.testStringTransaction('hello', callbackTestStringTransaction); 390 testProxy.testMapTransaction(testMap, callbackTestMapTransaction); 391 testProxy.testArrayTransaction(['1','2'], callbackTestMapTransaction); 392 }, 393 onDisconnect: (elementName) => { 394 console.log('onDisconnectService onDisconnect'); 395 }, 396 onFailed: (code) => { 397 console.log('onDisconnectService onFailed'); 398 } 399}; 400 401let context: common.UIAbilityContext = this.context; 402 403function connectAbility(): void { 404 let want: Want = { 405 bundleName: 'com.example.myapplicationidl', 406 abilityName: 'com.example.myapplicationidl.ServiceAbility' 407 }; 408 let connectionId = -1; 409 connectionId = context.connectServiceExtensionAbility(want, onAbilityConnectDone); 410} 411 412 413``` 414 415#### Transferring a sequenceable Object During IPC 416 417You can send a class from one process to another through IPC interfaces. However, you must ensure that the peer can use the code of this class and this class supports the **marshalling** and **unmarshalling** methods. The system uses **marshalling** and **unmarshalling** to serialize and deserialize objects into objects that can be identified by each process. 418 419**To create a class that supports the sequenceable type, perform the following operations:** 420 4211. Implement the **marshalling** method, which obtains the current state of the object and serializes the object into a **Parcel** object. 4222. Implement the **unmarshalling** method, which deserializes the object from a **Parcel** object. 423 424The following is an example of the **MySequenceable** class code: 425 426```ts 427import rpc from '@ohos.rpc'; 428export default class MySequenceable implements rpc.Sequenceable { 429 constructor(num: number, str: string) { 430 this.num = num; 431 this.str = str; 432 } 433 getNum() : number { 434 return this.num; 435 } 436 getString() : string { 437 return this.str; 438 } 439 marshalling(messageParcel: rpc.MessageParcel) { 440 messageParcel.writeInt(this.num); 441 messageParcel.writeString(this.str); 442 return true; 443 } 444 unmarshalling(messageParcel: rpc.MessageParcel) { 445 this.num = messageParcel.readInt(); 446 this.str = messageParcel.readString(); 447 return true; 448 } 449 private num: number; 450 private str: string; 451} 452``` 453 454### Development Using C++ (Automatically Generating ServiceAbility Interface Template Code During Compilation) 455 456#### Creating an IDL File 457 458You can use C++ to create IDL files. 459 460For example, create a file named **IQuickFixManager.idl** with the following content: 461 462``` 463/* 464 * Copyright (c) 2023 Huawei Device Co., Ltd. 465 * Licensed under the Apache License, Version 2.0 (the "License"); 466 * you may not use this file except in compliance with the License. 467 * You may obtain a copy of the License at 468 * 469 * http://www.apache.org/licenses/LICENSE-2.0 470 * 471 * Unless required by applicable law or agreed to in writing, software 472 * distributed under the License is distributed on an "AS IS" BASIS, 473 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 474 * See the License for the specific language governing permissions and 475 * limitations under the License. 476 */ 477 478sequenceable QuickFixInfo..OHOS.AAFwk.ApplicationQuickFixInfo; 479interface OHOS.AAFwk.IQuickFixManager { 480 void ApplyQuickFix([in] String[] quickFixFiles, [in] boolean isDebug); 481 void GetApplyedQuickFixInfo([in] String bundleName, [out] ApplicationQuickFixInfo quickFixInfo); 482 void RevokeQuickFix([in] String bundleName); 483} 484``` 485 486#### Modifying the BUILD.gn File 487 4881. Import the IDL tool template to the current **BUILD.gn** file. 489 490 ```bash 491 # Copy the line below to the .gn file. 492 import("//foundation/ability/idl_tool/idl_config.gni") 493 ``` 494 4952. Invoke the IDL tool to generate a C++ template file. 496 497 Replace *axx_bxx_cxx* in the code below with the .cpp file names of the generated stub and proxy. 498 499 ```bash 500 idl_interface_sources = [ 501 # Change axx_bxx_cxx to the name of the .cpp file of the generated proxy. 502 "${target_gen_dir}/axx_bxx_cxx_proxy.cpp", 503 # Change axx_bxx_cxx to the name of the .cpp file of the generated stub. 504 "${target_gen_dir}/axx_bxx_cxx_stub.cpp", 505 ] 506 507 # Use idl_gen_interface to generate a template file. You need to enter the parameter name, which will be used in deps. 508 idl_gen_interface("EEEFFFGGG") { 509 # Name of your .idl file, which is in the same path as the .gn file. 510 src_idl = rebase_path("IAxxBxxCxx.idl") 511 # The template file .cpp of the proxy and stub. You can copy the line below to the .gn file. 512 dst_file = string_join(",", idl_interface_sources) 513 # Enable hitrace. The value is the uint64_t type identifier defined in the hitrace_meter.h file. You need to enter the variable name of the constant. 514 hitrace = "HITRACE_TAG_ABILITY_MANAGER" 515 # Enable hilog. The domain ID is a hexadecimal integer. 516 log_domainid = "0xD003900" 517 # Enable hilog. The tag name is a string, which is generally a subsystem name. 518 log_tag = "QuickFixManagerService" 519 } 520 ``` 521 522 The names of ***axx_bxx_cxx_*proxy.cpp** and ***axx_bxx_cxx_*stub.cpp** are the same as the corresponding .idl file names in lowercase, with an underscore (_) added for each CamelCase segment. 523 524 ```bash 525 # For example, if the .idl file is IQuickFixManager.idl, 526 then axx_bxx_cxx_proxy.cpp is quick_fix_manager_proxy.cpp 527 and axx_bxx_cxx_stub.cpp is quick_fix_manager_stub.cpp. 528 ``` 529 530 If the name of the template file to be generated starts with I, add one **I** before the interface name. 531 532 ```bash 533 # For example, if the generated template file is **quick_fix_manager_proxy.cpp**, the interface name is **IQuickFixManager**. 534 # Definition in the .idl file 535 interface OHOS.AAFwk.IQuickFixManager { 536 void ApplyQuickFix([in] String[] quickFixFiles, [in] boolean isDebug); 537 void GetApplyedQuickFixInfo([in] String bundleName, [out] ApplicationQuickFixInfo quickFixInfo); 538 void RevokeQuickFix([in] String bundleName); 539 } 540 ``` 541 542 Configure hilog. The log_domainid and log_tag parameters must appear in pairs; otherwise, a compilation error occurs. 543 544 ```bash 545 idl_gen_interface("quickfix_manager_interface") { 546 src_idl = rebase_path("IQuickFixManager.idl") 547 dst_file = string_join(",", idl_interface_sources) 548 hitrace = "HITRACE_TAG_ABILITY_MANAGER" 549 log_domainid = "0xD003900" 550 log_tag = "QuickFixManagerService" # An error occurs during compilation if only log_tag or log_domainid is included. 551 } 552 ``` 553 5543. Add the header file path of the template file to **BUILD.gn**. 555 556 You only need to add **${target_gen_dir}** to **include_dirs**. 557 558 ```bash 559 include_dirs = [ 560 "aaa/bbb/ccc", # Path of the original header file 561 "${target_gen_dir}", # Path of the template header file 562 ] 563 ``` 564 5654. Add the path of the template file .cpp to **BUILD.gn**. 566 567 If **sources** contain ***axx_bxx_cxx_*proxy.cpp** and ***axx_bxx_cxx_*stub.cpp**, delete them and add **sources += filter_include(output_values, [ "*.cpp" ])**. 568 569 ```bash 570 output_values = get_target_outputs(":EEEFFFGGG") # Return the output file list of the target tag. Replace EEEFFFGGG. 571 sources = [ "axx_bxx_cxx_proxy.cpp" ] # Delete axx_bxx_cxx_proxy.cpp. 572 sources += filter_include(output_values, [ "*.cpp" ]) # filter_include selects the list that meets the requirements. You can copy this line directly. 573 ``` 574 5755. Add the dependency **EEEFFFGGG** to **BUILD.gn**. 576 577 ```bash 578 deps = [ 579 ":EEEFFFGGG", 580 ] 581 ``` 582 583 The name of the dependency added to **deps** must be the same as the parameter name of the **idl_gen_interface** function. 584 585 ```bash 586 idl_gen_interface("quickfix_manager_interface") { 587 src_idl = rebase_path("IQuickFixManager.idl") 588 dst_file = string_join(",", idl_interface_sources) 589 hitrace = "HITRACE_TAG_ABILITY_MANAGER" 590 log_domainid = "0xD003900" 591 log_tag = "QuickFixManagerService" 592 } 593 deps = [ 594 "${ability_runtime_innerkits_path}/app_manager:app_manager", 595 ":quickfix_manager_interface"] # Same as the parameter name of the idl_gen_interface function. 596 ``` 597 5986. Add external dependencies of the template file to **BUILD.gn**. 599 600 Add the external dependencies of the template file to **external_deps**. 601 602 If a dependency already exists, you do not need to add it again; otherwise, compilation errors may occur. 603 604 ```bash 605 external_deps = [ 606 # Mandatory dependency of the template file 607 "c_utils:utils", 608 # Mandatory dependency of the hilog output 609 "hilog:libhilog", 610 # Mandatory dependency of the hitrace output 611 "hitrace:hitrace_meter", 612 # Mandatory dependency of the template file 613 "ipc:ipc_core", 614 ] 615 ``` 616 617#### Example 618 619The following uses the quick fix service as an example: 620 6211. Create the **IQuickFixManager.idl** file. 622 623 When creating the .idl file, ensure that the interface name is the same as the .idl file name; otherwise, an error occurs during code generation. 624 625 The path of the .idl file must be the same as that of the **BUILD.gn** file of the function code. 626 627 In the example, the file is in **foundation/ability/ability_runtime/interfaces/inner_api/quick_fix/**. 628 629 ```bash 630 /* 631 * Copyright (c) 2023 Huawei Device Co., Ltd. 632 * Licensed under the Apache License, Version 2.0 (the "License"); 633 * you may not use this file except in compliance with the License. 634 * You may obtain a copy of the License at 635 * 636 * http://www.apache.org/licenses/LICENSE-2.0 637 * 638 * Unless required by applicable law or agreed to in writing, software 639 * distributed under the License is distributed on an "AS IS" BASIS, 640 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 641 * See the License for the specific language governing permissions and 642 * limitations under the License. 643 */ 644 645 sequenceable QuickFixInfo..OHOS.AAFwk.ApplicationQuickFixInfo; 646 interface OHOS.AAFwk.IQuickFixManager { 647 void ApplyQuickFix([in] String[] quickFixFiles, [in] boolean isDebug); 648 void GetApplyedQuickFixInfo([in] String bundleName, [out] ApplicationQuickFixInfo quickFixInfo); 649 void RevokeQuickFix([in] String bundleName); 650 } 651 ``` 652 653 When creating the .idl file, change the return value of the function from int to void. 654 655 ```bash 656 # Functions in quick_fix_manager_client.h 657 int32_t ApplyQuickFix(const std::vector<std::string> &quickFixFiles); 658 int32_t GetApplyedQuickFixInfo(const std::string &bundleName, ApplicationQuickFixInfo &quickFixInfo); 659 int32_t RevokeQuickFix(const std::string &bundleName); 660 # Definition in the .idl file 661 interface OHOS.AAFwk.QuickFixManager { 662 void ApplyQuickFix([in] String[] quickFixFiles); 663 void GetApplyedQuickFixInfo([in] String bundleName, [out] ApplicationQuickFixInfo quickFixInfo); 664 void RevokeQuickFix([in] String bundleName); 665 } 666 ``` 667 6682. Modify the BUILD.gn file. 669 670 ```bash 671 # Copyright (c) 2023 Huawei Device Co., Ltd. 672 # Licensed under the Apache License, Version 2.0 (the "License"); 673 # you may not use this file except in compliance with the License. 674 # You may obtain a copy of the License at 675 # 676 # http://www.apache.org/licenses/LICENSE-2.0 677 # 678 # Unless required by applicable law or agreed to in writing, software 679 # distributed under the License is distributed on an "AS IS" BASIS, 680 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 681 # See the License for the specific language governing permissions and 682 # limitations under the License. 683 684 import("//build/ohos.gni") 685 import("//foundation/ability/ability_runtime/ability_runtime.gni") 686 import("//foundation/ability/idl_tool/idl_config.gni") 687 688 idl_interface_sources = [ 689 "${target_gen_dir}/quick_fix_manager_proxy.cpp", 690 "${target_gen_dir}/quick_fix_manager_stub.cpp", 691 ] 692 693 idl_gen_interface("quickfix_manager_interface") { 694 src_idl = rebase_path("IQuickFixManager.idl") 695 dst_file = string_join(",", idl_interface_sources) 696 hitrace = "HITRACE_TAG_ABILITY_MANAGER" 697 log_domainid = "0xD003900" 698 log_tag = "QuickFixManagerService" 699 } 700 701 config("quickfix_config") { 702 visibility = [ ":*" ] 703 include_dirs = [ 704 "include", 705 "${target_gen_dir}", 706 ] 707 cflags = [] 708 if (target_cpu == "arm") { 709 cflags += [ "-DBINDER_IPC_32BIT" ] 710 } 711 } 712 713 ohos_shared_library("quickfix_manager") { 714 configs = [ "${ability_runtime_services_path}/common:common_config" ] 715 public_configs = [ ":quickfix_config" ] 716 717 output_values = get_target_outputs(":quickfix_manager_interface") 718 sources = [ 719 "src/quick_fix_error_utils.cpp", 720 "src/quick_fix_info.cpp", 721 "src/quick_fix_load_callback.cpp", 722 "src/quick_fix_manager_client.cpp", 723 "src/quick_fix_utils.cpp", 724 ] 725 sources += filter_include(output_values, [ "*.cpp" ]) 726 defines = [ "AMS_LOG_TAG = \"QuickFixService\"" ] 727 deps = [ 728 ":quickfix_manager_interface", 729 "${ability_runtime_innerkits_path}/app_manager:app_manager", 730 ] 731 732 external_deps = [ 733 "ability_base:want", 734 "bundle_framework:appexecfwk_base", 735 "bundle_framework:appexecfwk_core", 736 "c_utils:utils", 737 "hilog:libhilog", 738 "hitrace:hitrace_meter", 739 "ipc:ipc_single", 740 "safwk:system_ability_fwk", 741 "samgr:samgr_proxy", 742 ] 743 744 innerapi_tags = [ "platformsdk" ] 745 subsystem_name = "ability" 746 part_name = "ability_runtime" 747 } 748 ``` 749 7503. Specify the path and directory structure of the generated template file. 751 752 Take rk3568 as an example. The path of the template file generated in the instance is **out/rk3568/gen/foundation/ability/ability_runtime/interfaces/inner_api/quick_fix/**, 753 754 where **foundation/ability/ability_runtime/interfaces/inner_api/quick_fix/** is the relative path of the .idl file. 755 756 The directory structure of the template file generated is as follows: 757 758 ```bash 759 |-- out/rk3568/gen/foundation/ability/ability_runtime/interfaces/inner_api/quick_fix/ 760 |-- iquick_fix_manager.h 761 |-- quick_fix_manager_stub.h 762 |-- quick_fix_manager_stub.cpp 763 |-- quick_fix_manager_proxy.h 764 |-- quick_fix_manager_proxy.cpp 765 ``` 766 767