1# UIExtensionComponent (System API)
2
3**UIExtensionComponent** is used to embed UIs provided by other applications in the local application UI. The embedded content runs in another process, and the local application does not participate in its layout and rendering.
4
5This component is usually used in modular development scenarios where process isolation is required.
6
7> **NOTE**
8>
9> This component is supported since API version 10. Updates will be marked with a superscript to indicate their earliest API version.
10>
11> The APIs provided by this component are system APIs.
12
13## Restrictions
14
15This component does not support preview.
16
17The ability to be started must be a UIExtensionAbility, an extension ability with UI. For details about how to implement a UIExtensionAbility, see [@ohos.app.ability.UIExtensionAbility (Base Class for ExtensionAbilities with UI)](../../apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md).
18
19The width and height of the component must be set to non-zero valid values.
20
21## Child Components
22
23Not supported
24
25## APIs
26
27UIExtensionComponent(want: Want, options?: UIExtensionOptions)
28
29**Parameters**
30
31| Name               | Type                                                  | Mandatory| Description          |
32| --------------------- | ---------------------------------------------------------- | ---- | ------------------ |
33| want                  | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | Yes  | Ability to start. |
34| options<sup>11+</sup> | [UIExtensionOptions](#uiextensionoptions11)                | No  | Construction parameters to be transferred.|
35
36## Attributes
37
38The [universal attributes](ts-universal-attributes-size.md) are supported.
39
40## Events
41
42The [universal events](ts-universal-events-click.md) are not supported.
43
44The events are passed to the remote UIExtensionAbility for processing after coordinate conversion.
45
46The following events are supported:
47
48### onRemoteReady
49
50onRemoteReady(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<UIExtensionProxy>)
51
52Invoked when the connection to the remote UIExtensionAbility is set up, that is, the UIExtensionAbility is ready to receive data through the proxy.
53
54**Parameters**
55
56| Name                      | Type  | Description                                                        |
57| ---------------------------- | ------ | ------------------------------------------------------------ |
58| proxy                        | UIExtensionProxy | Proxy used to send data to the remote UIExtensionAbility.                         |
59
60### onReceive
61
62onReceive(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{ [key: string]: Object }>)
63
64Invoked when the data sent by the started UIExtensionAbility is received.
65
66**Parameters**
67
68| Name                      | Type  | Description                                                        |
69| ---------------------------- | ------ | ------------------------------------------------------------ |
70| data                        | { [key: string]: Object } | Data from the remote UIExtensionAbility.                |
71
72### onResult<sup>(deprecated)</sup>
73
74onResult(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{code: number; want?: Want}>)
75
76Invoked when the started UIExtensionAbility calls **terminateSelfWithResult**. After this callback is invoked, **OnRelease** is invoked.
77
78The result data of the remote UIExtensionAbility can be processed in this callback. For details, see [AbilityResult](../../apis-ability-kit/js-apis-inner-ability-abilityResult.md).
79
80> **NOTE**
81> This API is supported since API version 10 and deprecated since API version 12. You are advised to use [onTerminated](#onterminated12) instead.
82
83**Parameters**
84
85| Name                      | Type  | Description                                                        |
86| ---------------------------- | ------ | ------------------------------------------------------------ |
87| code                        | number | Result code from the remote UIExtensionAbility.                         |
88| want                        | Want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) of the result from the remote UIExtensionAbility.|
89
90### onRelease<sup>(deprecated)</sup>
91
92onRelease(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number>)
93
94Invoked when the started UIExtensionAbility is destroyed.
95
96If the UIExtensionAbility is destroyed correctly by calling **terminateSelfWithResult** or **terminateSelf**, the value of **releaseCode** is **0**.
97
98If the UIExtensionAbility is destroyed because it crashes or is forced stopped, the value of **releaseCode** is **1**.
99
100> **NOTE**
101> This API is supported since API version 10 and deprecated since API version 12. You are advised to use [onTerminated](#onterminated12) or [onError](#onerror) instead.
102
103**Parameters**
104
105| Name                      | Type  | Description                                                        |
106| ---------------------------- | ------ | ------------------------------------------------------------ |
107| releaseCode                        | number | Code that indicates how the remote UIExtensionAbility is destroyed. The value **0** means normal destruction, and **1** means abnormal destruction.                         |
108
109### onError
110
111onError(callback:[ErrorCallback](../../apis-basic-services-kit/js-apis-base.md#errorcallback))
112
113Invoked when an exception occurs during the running of the UIExtensionAbility. You can obtain the error information based on the **code**, **name**, and **message** parameters in the callback and rectify the exception accordingly.
114
115**Parameters**
116
117| Name                      | Type  | Description                                                        |
118| ---------------------------- | ------ | ------------------------------------------------------------ |
119| err                        | [BusinessError](../../apis-basic-services-kit/js-apis-base.md#businesserror) | Error information.   |
120
121### onTerminated<sup>12+<sup>
122
123onTerminated(callback: Callback&lt;TerminationInfo&gt;)
124
125Called when the started UIExtensionAbility is terminated by calling **terminateSelfWithResult** or **terminateSelf**.
126
127**Parameters**
128
129| Name  | Type  | Description                                                                                    |
130| -------  | ------ | ---------------------------------------------------------------------------------------- |
131| callback | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<[TerminationInfo](#terminationinfo12)> | Callback used to return the result from the UIExtensionAbility.|
132
133> **NOTE**
134>
135> - If the UIExtensionAbility is terminated by calling **terminateSelfWithResult**, the carried information is passed as arguments into the callback function.
136> - If the UIExtensionAbility is terminated by calling **terminateSelf**, the input parameters **code** and **want** in the callback function are at their default values: **0** and **undefined**, respectively.
137
138### TerminationInfo<sup>12+<sup>
139
140Represents the result returned when the UIExtensionAbility that has been started exits properly by calling **terminateSelfWithResult** or **terminateSelf**.
141
142| Name | Type  | Description                                                |
143| ------- | ------ | ---------------------------------------------------  |
144| code    | number | Result code returned when the UIExtensionAbility exits.|
145| want    | [Want](../../apis-ability-kit/js-apis-app-ability-want.md)   | Data returned when the UIExtensionAbility exits.  |
146
147## UIExtensionOptions<sup>11+</sup>
148Describes the optional construction parameters during **UIExtensionComponent** construction.
149
150**Parameters**
151
152| Name              | Type                                | Mandatory| Description                                                                                                     |
153| ----                 | ---------------------------------------- | ---- | ---------------                                                                                               |
154| isTransferringCaller | boolean                                  | No  | Whether the UIExtensionComponent forwards the upper-level caller information when it is used for nesting.<br> Default value: **false**|
155| placeholder<sup>12+<sup> | [ComponentContent](../js-apis-arkui-ComponentContent.md)       | No  | Placeholder to be displayed before the UIExtensionComponent establishes a connection with the UIExtensionAbility.|
156| dpiFollowStrategy<sup>12+<sup> | [DpiFollowStrategy](ts-container-ui-extension-component-sys.md#dpifollowstrategy12)                  | No  | Whether the DPI settings follow the host or UIExtensionAbility.<br> Default value: **FOLLOW_UI_EXTENSION_ABILITY_DPI**|
157
158## DpiFollowStrategy<sup>12+</sup>
159
160| Name                            | Description            |
161| -------------------------------- | --------------- |
162| FOLLOW_HOST_DPI                  | The DPI settings follow the host.|
163| FOLLOW_UI_EXTENSION_ABILITY_DPI  | The DPI settings follow the UIExtensionAbility.|
164
165## UIExtensionProxy
166
167Implements a **UIExtensionProxy** instance for the component host to send data to, subscribe to, or unsubscribe from the started UIExtensionAbility through the connection established between the two parties.
168
169### send
170
171send(data: { [key: string]: Object }): void
172
173Asynchronously sends data from the component host to the started UIExtensionAbility through the connection established between the two parties.
174
175**System capability**: SystemCapability.ArkUI.ArkUI.Full
176
177**Parameters**
178
179| Name | Type                                    | Mandatory  | Description           |
180| ---- | ---------------------------------------- | ---- | --------------- |
181| data | { [key: string]: Object } | Yes   | Data to be asynchronously sent to the started UIExtensionAbility.|
182
183### sendSync<sup>11+</sup>
184
185sendSync(data: { [key: string]: Object }): { [key: string]: Object }
186
187Synchronously sends data from the component host to the started UIExtensionAbility through the connection established between the two parties.
188
189**System capability**: SystemCapability.ArkUI.ArkUI.Full
190
191**Parameters**
192
193| Name | Type                                    | Mandatory  | Description           |
194| ---- | ---------------------------------------- | ---- | --------------- |
195| data | { [key: string]: Object } | Yes   | Data to be synchronously sent to the started UIExtensionAbility.|
196
197**Return value**
198
199| Type| Description|
200| ---- | ----|
201|{ [key: string]: Object } | Data returned by the UIExtensionAbility.|
202
203**Error codes**
204
205| ID| Description|
206| ---- | ----|
207| 100011 | UIExtensionAbility not registered.|
208| 100012 | Failed to send data.|
209
210### on('asyncReceiverRegister')<sup>11+</sup>
211
212on(type: 'asyncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void
213
214Subscribes to asynchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility.
215
216**System capability**: SystemCapability.ArkUI.ArkUI.Full
217
218**Parameters**
219
220| Name | Type|Mandatory| Description|
221| ------ | -------- |---- | ------- |
222| type   | string | Yes| Event type. The value is fixed at **'asyncReceiverRegister'**.|
223| callback   | (proxy: UIExtensionProxy) => void | Yes| Callback used to return the result.|
224
225### on('syncReceiverRegister')<sup>11+</sup>
226
227on(type: 'syncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void
228
229Subscribes to synchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility.
230
231**System capability**: SystemCapability.ArkUI.ArkUI.Full
232
233**Parameters**
234
235| Name | Type|Mandatory| Description|
236| ------ | -------- |---- | ------- |
237| type   | string | Yes| Event type. The value is fixed at **'syncReceiverRegister'**.|
238| callback   | (proxy: UIExtensionProxy) => void | Yes| Callback used to return the result.|
239
240### off('asyncReceiverRegister')<sup>11+</sup>
241
242off(type: 'asyncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void
243
244Unsubscribes from asynchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility.
245
246**System capability**: SystemCapability.ArkUI.ArkUI.Full
247
248**Parameters**
249
250| Name | Type| Mandatory| Description|
251| ------ | -------- | ----- | ------- |
252| type   | string | Yes| Event type. The value is fixed at **'asyncReceiverRegister'**.|
253| callback | (proxy: UIExtensionProxy) => void | No| Callback used for unsubscription.<br> If this parameter is not set, this API unsubscribes from all callbacks corresponding to **type**.|
254
255### off('syncReceiverRegister')<sup>11+</sup>
256
257off(type: 'syncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void
258
259Unsubscribes from synchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility.
260
261**System capability**: SystemCapability.ArkUI.ArkUI.Full
262
263**Parameters**
264
265| Name | Type| Mandatory| Description|
266| ------ | -------- | ----- | ------- |
267| type   | string | Yes| Event type. The value is fixed at **'syncReceiverRegister'**.|
268| callback | (proxy: UIExtensionProxy) => void | No| Callback used for unsubscription.<br> If this parameter is not set, this API unsubscribes from all callbacks corresponding to **type**.|
269
270## Example
271
272This example shows only the method used by the component and the UIExtensionAbility. For the code to run properly, you need to install the ability whose **bundleName** is **"com.example.uiextensionprovider"** and **abilityName** is **"UIExtensionProvider"** on the device.
273
274```ts
275// Component usage example:
276import { ComponentContent } from '@kit.ArkUI';
277class Params {
278}
279@Builder
280function LoadingBuilder(params: Params) {
281  Column() {
282   LoadingProgress()
283      .color(Color.Blue)
284  }
285}
286@Entry
287@Component
288struct Second {
289  @State message1: string = 'Hello World 1'
290  @State message2: string = 'Hello World 2'
291  @State message3: string = 'Hello World 3'
292  @State visible: Visibility = Visibility.Hidden
293  @State wid: number = 300
294  @State hei: number = 300
295  private proxy: UIExtensionProxy | null = null;
296  private contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(LoadingBuilder), new Params);
297
298
299  build() {
300    Row() {
301      Column() {
302        Text(this.message1).fontSize(30)
303        Text(this.message2).fontSize(30)
304        Text(this.message3).fontSize(30)
305        UIExtensionComponent({
306          bundleName : "com.example.newdemo",
307          abilityName: "UIExtensionProvider",
308          parameters: {
309            "ability.want.params.uiExtensionType": "dialog"
310          }},
311          {
312            placeholder: this.contentNode
313          })
314          .width(this.wid)
315          .height(this.hei)
316          .border({width: 5, color: Color.Blue})
317          .onReceive((data) => {
318            console.info('Lee onReceive, for test')
319            this.message3 = JSON.stringify(data['data'])
320          })
321          .onTerminated((info) => {
322            console.info('onTerminated: code =' + info.code + ', want = ' + JSON.stringify(info.want));
323          })
324          .onRemoteReady((proxy) => {
325            console.info('onRemoteReady, for test')
326            this.proxy = proxy
327
328            this.proxy.on("syncReceiverRegister", syncRegisterCallback1);
329            // this.proxy.on("syncReceiverRegister", syncRegisterCallback2);
330
331
332            // this.proxy.off("syncReceiverRegister");
333
334            // this.proxy.off("syncReceiverRegister", (proxy) => {
335            //   console.info("off invoke for test, type is syncReceiverRegister");
336            // });
337
338            this.proxy.on("asyncReceiverRegister", (proxy1) => {
339              console.info("on invoke for test, type is asyncReceiverRegister");
340            });
341            //
342            // this.proxy.off("asyncReceiverRegister");
343          })
344
345        Button("Send to UIExtensionAbility").onClick(() => {
346          if (this.proxy != undefined) {
347            this.proxy.send({data: "Hello 1"})
348
349            try {
350              let re = this.proxy.sendSync({data: "Hello 2"})
351              console.info("for test, re=" + JSON.stringify(re));
352            } catch (err) {
353              console.error(`sendSync failed for test. errCode=${err.code}, msg=${err.message}`);
354            }
355          }
356        })
357      }
358      .width('100%')
359    }
360    .height('100%')
361  }
362}
363
364function syncRegisterCallback1(proxy: UIExtensionProxy) {
365  console.info("on invoke for test, syncRegisterCallback1, type is syncReceiverRegister");
366}
367
368function syncRegisterCallback2(proxy: UIExtensionProxy) {
369  console.info("on invoke for test, syncRegisterCallback2, type is syncReceiverRegister");
370}
371```
372
373```ts
374// Extension entry point file UIExtensionProvider.ts
375import { UIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
376
377const TAG: string = '[UIExtAbility]'
378export default class UIExtAbility extends UIExtensionAbility {
379
380  onCreate() {
381    console.log(TAG, `UIExtAbility onCreate`)
382  }
383
384  onForeground() {
385    console.log(TAG, `UIExtAbility onForeground`)
386  }
387
388  onBackground() {
389    console.log(TAG, `UIExtAbility onBackground`)
390  }
391
392  onDestroy() {
393    console.log(TAG, `UIExtAbility onDestroy`)
394  }
395
396  onSessionCreate(want: Want, session: UIExtensionContentSession) {
397    console.log(TAG, `UIExtAbility onSessionCreate, want: ${JSON.stringify(want)}`)
398    let param: Record<string, UIExtensionContentSession> = {
399      'session': session
400    };
401    let storage: LocalStorage = new LocalStorage(param);
402    session.loadContent('pages/extension', storage);
403  }
404
405  onSessionDestroy(session: UIExtensionContentSession) {
406    console.log(TAG, `UIExtAbility onSessionDestroy`)
407  }
408}
409```
410
411```ts
412// Entry page file of the Extension Ability: extension.ets
413import { UIExtensionContentSession } from '@kit.AbilityKit';
414import { router } from '@kit.ArkUI';
415
416let storage = LocalStorage.getShared()
417AppStorage.setOrCreate('message', 'UIExtensionAbility')
418
419@Entry(storage)
420@Component
421struct Extension {
422  @StorageLink('message') storageLink: string = '';
423  private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session');
424
425  onPageShow() {
426    if (this.session != undefined) {
427      this.session.setReceiveDataCallback((data)=> {
428        this.storageLink = JSON.stringify(data)
429        console.info("invoke for test, handle callback set by setReceiveDataCallback successfully");
430      })
431
432      this.session.setReceiveDataForResultCallback(func1)
433    }
434  }
435
436  build() {
437    Row() {
438      Column() {
439        Text(this.storageLink)
440          .fontSize(20)
441          .fontWeight(FontWeight.Bold)
442        Button("Send to Component").onClick(()=>{
443          if (this.session != undefined) {
444            this.session.sendData({"data": 543321})
445            console.info('send 543321, for test')
446          }
447        })
448        Button("terminate").onClick(()=> {
449          if (this.session != undefined) {
450            this.session.terminateSelf();
451          }
452          storage.clear()
453        })
454        Button("terminate with result").onClick(()=>{
455          if (this.session != undefined) {
456            this.session.terminateSelfWithResult({
457              resultCode: 0,
458              want: {
459                bundleName: "myBundleName",
460                parameters: { "result": 123456 }
461              }
462            })
463          }
464          storage.clear()
465        })
466
467        Button("Redirect").onClick(()=> {
468          router.pushUrl({url: 'pages/hello'})
469        })
470      }
471    }
472    .height('100%')
473  }
474}
475function func1(data: Record<string, Object>): Record<string, Object> {
476  let linkToMsg: SubscribedAbstractProperty<string> = AppStorage.link('message');
477  linkToMsg.set(JSON.stringify(data))
478  console.info("invoke for test, handle callback set by setReceiveDataForResultCallback successfully");
479  return data;
480}
481
482```
483