1# PluginComponent (System API) 2 3The **PluginComponent** allows an application to display external UI from another application. To implement update through inter-process communication (IPC), see [@ohos.pluginComponent](../js-apis-plugincomponent.md). 4 5 6> **NOTE** 7> 8> - This component is supported since API version 9. Updates will be marked with a superscript to indicate their earliest API version. 9> 10> - The APIs provided by this module are system APIs. 11 12## Child Components 13 14Not supported 15 16 17## APIs 18 19PluginComponent(options: PluginComponentOptions) 20 21Creates a **PluginComponent** to display the UI provided by an external application. 22 23**Parameters** 24 25| Name | Type | Mandatory| Description | 26| ------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ | 27| options | [PluginComponentOptions](#plugincomponentoptions14) | Yes | Configuration options of the **PluginComponent**.| 28 29## PluginComponentOptions<sup>14+</sup> 30 31Defines options for constructing a **PluginComponent**. 32 33| Name | Type | Description | 34| ---------- | ------ | --------------------------- | 35| template | [PluginComponentTemplate](#plugincomponenttemplate9) | Template of the **PluginComponent**, which is bound to the component defined by the provider. | 36| data | any | Data passed to the **PluginComponent** provider.| 37 38## PluginComponentTemplate<sup>9+</sup> 39 40| Name | Type | Description | 41| ---------- | ------ | --------------------------- | 42| source | string | Component template name. | 43| bundleName | string | Bundle name of the provider ability.| 44## Attributes 45The width and height of the component must be explicitly set to non-zero valid values. 46 47**NOTE** 48 49 The template can be provided in either of the following modes: 50* 1. Use an absolute path. In this case, set **source** to the absolute path of the template and leave **bundleName** blank. This mode is not recommended as it is applicable only to standalone templates that do not need to load resources. 51* 2. Use an application package. In this case, set **bundleName** to the application bundle name and **source** to the relative path of the HAP file template. In the multi-HAP scenario, a HAP file is identified based on its relative path and name. 52 53 Example: **{source: 'pages/PluginProviderExample.ets&entry', bundleName:'com.example.provider'}** 54 55 The template is provided only when **source** can be set to an ability name or bundle name in the FA model. 56 57 Example: **{source:'plugin', bundleName:'com.example.provider'}** 58 59 60## Events 61 62[Gesture events](ts-gesture-settings.md) can be distributed to and processed inside the provider page. 63 64In addition to the [universal events](ts-component-general-events.md), the following events are supported. 65 66### onComplete 67 68onComplete(callback: VoidCallback) 69 70Triggered when the component loading is complete. 71 72**System API**: This is a system API. 73 74**System capability**: SystemCapability.ArkUI.ArkUI.Full 75 76### onError 77 78onError(callback: {info: PluginErrorCallback}) 79 80Triggered when an error occurs during component loading. 81 82**System API**: This is a system API. 83 84**System capability**: SystemCapability.ArkUI.ArkUI.Full 85 86**Parameters** 87 88| Name | Type | Mandatory| Description | 89| --------- | ------------------------------------------------------------ | ---- | ----------------------------------------------- | 90| callback | [PluginErrorCallback](#pluginerrorcallback14) | Yes | Callback invoked when an error occurs.| 91 92## PluginErrorCallback<sup>14+</sup> 93 94Defines the callback invoked when an error occurs. 95 96| Name | Type | Description | 97| -------- | ------------------ | --------------------------- | 98| info | [PluginErrorData](#pluginerrordata14) | Data provided when the error occurs.| 99 100## PluginErrorData<sup>14+</sup> 101 102Defines the data provided when an error occurs during component loading. 103 104| Name | Type | Description | 105| ---------- | ------ | -------------------------- | 106| errcode | number | Error code. | 107| msg | string | Error message. | 108 109## Example: Loading a PluginComponent 110 111This example demonstrates the basic usage of the **PluginComponent**. Specifically, you need to create an application acting as the **PluginComponent** [user](#plugincomponent-user) with the bundle name of **"com.example.user"** and an application acting as the **PluginComponent** [provider](#plugincomponent-provider) with the bundle name of **"com.example.provider"**. After building the application projects, perform the following steps for testing: 1121. Install the HAP packages of both applications on the device. 1132. Open the user application page. Both user and provider content should be displayed correctly. 1143. Register listeners by clicking the **Register Push Listener** button on the user side and the **Register Request Listener** button on the provider side. 1154. Send a request from the user to the provider by clicking the **Request** button. The log should print information related to **onRequestListener**. 1165. Send a push event from the provider to the user by clicking the **Push** button. The log should print information related to **onPushListener**. 117 118### PluginComponent User 119 120The user application has a bundle name of **"com.example.user"** and contains one page. 121- The EntryAbility (UIAbility) loads the entry page file **ets/pages/Index.ets**, which contains the following code: 122 ```ts 123 import plugin from "./plugin_component" 124 125 interface Info { 126 errcode: number, 127 msg: string 128 } 129 130 @Entry 131 @Component 132 struct PluginUserExample { 133 build() { 134 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 135 Text('Hello World') 136 .fontSize(50) 137 .fontWeight(FontWeight.Bold) 138 Button('Register Push Listener') 139 .fontSize(30) 140 .width(400) 141 .height(100) 142 .margin({ top: 20 }) 143 .onClick(() => { 144 plugin.onListener() 145 console.log("Button('Register Push Listener')") 146 }) 147 Button('Request') 148 .fontSize(50) 149 .width(400) 150 .height(100) 151 .margin({ top: 20 }) 152 .onClick(() => { 153 plugin.Request() 154 console.log("Button('Request')") 155 }) 156 PluginComponent({ 157 // Provider 158 template: { source: 'pages/Index.ets&entry', bundleName: 'com.example.provider' }, 159 data: { 'countDownStartValue': 'new countDownStartValue' } 160 }).size({ width: 500, height: 350 }) 161 .onComplete(() => { 162 console.log("onComplete") 163 }) 164 .onError((info: Info) => { 165 console.log("onComplete" + info.errcode + ":" + info.msg) 166 }) 167 } 168 .width('100%') 169 .height('100%') 170 } 171 } 172 ``` 173- Copy the [PluginComponent manager code](#plugincomponent-manager) corresponding to your project model type to the **ets/pages/plugin_component.js** file. 174- Add the **requestPermissions** tag in the **module.json5** file to allow the user application to query information from other applications: 175 ```json 176 "requestPermissions": [ 177 { 178 "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", 179 "usedScene": { 180 "abilities": [ 181 "EntryAbility" 182 ], 183 "when": "inuse" 184 } 185 } 186 ] 187 ``` 188 189### PluginComponent Provider 190 191The provider application has a bundle name of **"com.example.provider"** and contains one page. 192- The EntryAbility (UIAbility) loads the entry page file **ets/pages/Index.ets**, which contains the following code: 193 ```ts 194 import plugin from "./plugin_component" 195 196 @Entry 197 @Component 198 struct PluginProviderExample { 199 @State message: string = 'no click!' 200 201 build() { 202 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 203 Button('Register Request Listener') 204 .fontSize(30) 205 .width(400) 206 .height(100) 207 .margin({ top: 20 }) 208 .onClick(() => { 209 plugin.onListener() 210 console.log("Button('Register Request Listener')") 211 }) 212 Button('Push') 213 .fontSize(30) 214 .width(400) 215 .height(100) 216 .margin({ top: 20 }) 217 .onClick(() => { 218 plugin.Push() 219 this.message = "Button('Push')" 220 console.log("Button('Push')") 221 }) 222 Text(this.message) 223 .height(150) 224 .fontSize(30) 225 .padding(5) 226 .margin(5) 227 }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) 228 } 229 } 230 ``` 231- Copy the [PluginComponent manager code](#plugincomponent-manager) corresponding to your project model type to the **ets/pages/plugin_component.js** file. 232 233### PluginComponent Manager 234 235The **PluginComponent** manager is used for communication between the user and provider. You need to select the corresponding code based on the model type and copy it into your project. 236 237#### FA Model 238```js 239// This example code is only applicable to the FA model. 240import pluginComponentManager from '@ohos.pluginComponent' 241 242var providerBundleName = 'com.example.provider' 243var providerAbilityName = 'com.example.provider.EntryAbility' 244var providerName = 'Index' 245 246// Push event listener 247function onPushListener(source, template, data, extraData) { 248 console.log("onPushListener template.source=" + template.source) 249 console.log("onPushListener template.ability=" + template.ability) 250 console.log("onPushListener data=" + JSON.stringify(data)) 251 console.log("onPushListener extraData=" + JSON.stringify(extraData)) 252} 253 254// Request event listener 255function onRequestListener(source, name, data) 256{ 257 console.log("onRequestListener name=" + name); 258 console.log("onRequestListener data=" + JSON.stringify(data)); 259 return {template:"pluginTemplate", data:data}; 260} 261 262export default { 263 // Register event listeners. 264 onListener() { 265 pluginComponentManager.on("push", onPushListener) 266 pluginComponentManager.on("request", onRequestListener) 267 }, 268 Push() { 269 // The provider proactively sends an event, want: provider information. 270 pluginComponentManager.push( 271 { 272 want: { 273 bundleName: providerBundleName, 274 abilityName: providerAbilityName, 275 }, 276 name: providerName, 277 data: { 278 "key_1": "plugin component push data", 279 "key_2": 12345 280 }, 281 extraData: { 282 "extra_str": "this is push event" 283 }, 284 jsonPath: "", 285 }, 286 (err, data) => { 287 console.log("push_callback: push ok!"); 288 } 289 ) 290 }, 291 Request() { 292 // The user proactively sends an event, want: provider information. 293 pluginComponentManager.request({ 294 want: { 295 bundleName: providerBundleName, 296 abilityName: providerAbilityName, 297 }, 298 name: providerName, 299 data: { 300 "key_1": "plugin component request data", 301 "key_2": 67890 302 }, 303 jsonPath: "", 304 }, 305 (err, data) => { 306 console.log("request_callback: componentTemplate.ability=" + data.componentTemplate.ability) 307 console.log("request_callback: componentTemplate.source=" + data.componentTemplate.source) 308 console.log("request_callback: data=" + JSON.stringify(data.data)) 309 console.log("request_callback: extraData=" + JSON.stringify(data.extraData)) 310 } 311 ) 312 } 313} 314``` 315 316#### Stage Model 317```js 318// This example code is only applicable to the stage model. 319import pluginComponentManager from '@ohos.pluginComponent' 320 321var userBundleName = 'com.example.user' 322var userAbilityName = 'com.example.user.EntryAbility' 323var providerBundleName = 'com.example.provider' 324var providerAbilityName = 'com.example.provider.EntryAbility' 325var providerName = 'Index' 326 327// Push event listener 328function onPushListener(source, template, data, extraData) { 329 console.log("onPushListener template.source=" + template.source) 330 console.log("onPushListener template.ability=" + template.ability) 331 console.log("onPushListener data=" + JSON.stringify(data)) 332 console.log("onPushListener extraData=" + JSON.stringify(extraData)) 333} 334 335// Request event listener 336function onRequestListener(source, name, data) { 337 console.log("onRequestListener name=" + name) 338 console.log("onRequestListener data=" + JSON.stringify(data)) 339 return { template: "pluginTemplate", data: data } 340} 341 342export default { 343 // Register event listeners. 344 onListener() { 345 pluginComponentManager.on("push", onPushListener) 346 pluginComponentManager.on("request", onRequestListener) 347 }, 348 Push() { 349 // The provider proactively sends an event, owner: user, target: provider. 350 pluginComponentManager.push( 351 { 352 owner: { 353 bundleName: userBundleName, 354 abilityName: userAbilityName, 355 }, 356 target: { 357 bundleName: providerBundleName, 358 abilityName: providerAbilityName, 359 }, 360 name: providerName, 361 data: { 362 "key_1": "plugin component push data", 363 "key_2": 12345 364 }, 365 extraData: { 366 "extra_str": "this is push event" 367 }, 368 jsonPath: "", 369 }, 370 (err, data) => { 371 console.log("push_callback: push ok!"); 372 } 373 ) 374 }, 375 Request() { 376 // The user proactively sends an event, owner: user, target: provider. 377 pluginComponentManager.request({ 378 owner: { 379 bundleName: userBundleName, 380 abilityName: userAbilityName, 381 }, 382 target: { 383 bundleName: providerBundleName, 384 abilityName: providerAbilityName, 385 }, 386 name: providerName, 387 data: { 388 "key_1": "plugin component request data", 389 "key_2": 67890 390 }, 391 jsonPath: "", 392 }, 393 (err, data) => { 394 console.log("request_callback: componentTemplate.ability=" + data.componentTemplate.ability) 395 console.log("request_callback: componentTemplate.source=" + data.componentTemplate.source) 396 console.log("request_callback: data=" + JSON.stringify(data.data)) 397 console.log("request_callback: extraData=" + JSON.stringify(data.extraData)) 398 } 399 ) 400 } 401} 402``` 403