1# @ohos.arkui.uiExtension (uiExtension)
2
3The **uiExtension** module provides APIs for the EmbeddedUIExtensionAbility (or UIExtensionAbility) to obtain the host application window information or the information about the corresponding **EmbeddedComponent**<!--Del--> (or **UIExtensionComponent**)<!--DelEnd--> component.
4
5> **NOTE**
6>
7> The initial APIs of this module are supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version.
8>
9
10## Modules to Import
11
12```
13import { uiExtension } from '@kit.ArkUI'
14```
15
16## WindowProxy
17
18### getWindowAvoidArea
19
20getWindowAvoidArea(type: window.AvoidAreaType): window.AvoidArea
21
22Obtains the area where this window cannot be displayed, for example, the system bar area, notch, gesture area, and soft keyboard area.
23
24**Atomic service API**: This API can be used in atomic services since API version 12.
25
26**System capability**: SystemCapability.ArkUI.ArkUI.Full
27
28| Name| Type| Mandatory| Description|
29| -------- | -------- | -------- | -------- |
30| type |[window.AvoidAreaType](./js-apis-window.md#avoidareatype7) | Yes| Type of the area.|
31
32**Return value**
33
34| Type| Description|
35| -------- | -------- |
36|[window.AvoidArea](./js-apis-window.md#avoidarea7) | Area where the window cannot be displayed.|
37
38**Error codes**
39
40For details about the error codes, see [Universal Error Codes](../errorcode-universal.md).
41
42| ID| Error Message|
43| ------- | -------- |
44| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
45
46**Example**
47
48```ts
49// ExtensionProvider.ts
50import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
51import { window } from '@kit.ArkUI';
52
53export default class EntryAbility extends EmbeddedUIExtensionAbility {
54  onSessionCreate(want: Want, session: UIExtensionContentSession) {
55    const extensionWindow = session.getUIExtensionWindowProxy();
56    // Obtain the information about the area where the window cannot be displayed.
57    let avoidArea: window.AvoidArea | undefined = extensionWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
58    console.info(`avoidArea: ${JSON.stringify(avoidArea)}`);
59  }
60}
61```
62
63### on('avoidAreaChange')
64
65on(type: 'avoidAreaChange', callback: Callback&lt;AvoidAreaInfo&gt;): void
66
67Subscribes to the event indicating changes to the area where the window cannot be displayed.
68
69**Atomic service API**: This API can be used in atomic services since API version 12.
70
71**System capability**: SystemCapability.ArkUI.ArkUI.Full
72
73| Name| Type| Mandatory| Description|
74| ------ | ---- | ---- | ---- |
75| type   | string | Yes| Event type. The value is fixed at **'avoidAreaChange'**, indicating the event of changes to the area where the window cannot be displayed.|
76| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[AvoidAreaInfo](#avoidareainfo)> | Yes| Callback used to return the area information.|
77
78**Error codes**
79
80For details about the error codes, see [Universal Error Codes](../errorcode-universal.md).
81
82| ID| Error Message|
83| ------- | -------- |
84| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
85
86**Example**
87
88```ts
89// ExtensionProvider.ts
90import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
91import { uiExtension } from '@kit.ArkUI';
92
93export default class EntryAbility extends EmbeddedUIExtensionAbility {
94  onSessionCreate(want: Want, session: UIExtensionContentSession) {
95    const extensionWindow = session.getUIExtensionWindowProxy();
96    // Subscribe to the event indicating changes to the area where the window cannot be displayed.
97    extensionWindow.on('avoidAreaChange', (info: uiExtension.AvoidAreaInfo) => {
98      console.info(`The avoid area of the host window is: ${JSON.stringify(info.area)}.`);
99    });
100  }
101}
102```
103
104### off('avoidAreaChange')
105
106off(type: 'avoidAreaChange', callback?: Callback&lt;AvoidAreaInfo&gt;): void
107
108Unsubscribes from the event indicating changes to the area where the window cannot be displayed.
109
110**Atomic service API**: This API can be used in atomic services since API version 12.
111
112**System capability**: SystemCapability.ArkUI.ArkUI.Full
113
114| Name  | Type| Mandatory| Description|
115| -------- | ---- | ---- | ---  |
116| type     | string | Yes| Event type. The value is fixed at **'avoidAreaChange'**, indicating the event of changes to the area where the window cannot be displayed.|
117| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[AvoidAreaInfo](#avoidareainfo)> | No| Callback used for unsubscription. If a value is passed in, the corresponding subscription is canceled. If no value is passed in, all subscriptions to the specified event are canceled.|
118
119**Error codes**
120
121For details about the error codes, see [Universal Error Codes](../errorcode-universal.md).
122
123| ID| Error Message                                                    |
124| -------- | ------------------------------------------------------------ |
125| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
126
127**Example**
128
129```ts
130// ExtensionProvider.ts
131import { EmbeddedUIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit';
132
133export default class EntryAbility extends EmbeddedUIExtensionAbility {
134  onSessionDestroy(session: UIExtensionContentSession) {
135    const extensionWindow = session.getUIExtensionWindowProxy();
136    // Cancel all subscriptions to the event indicating changes to the area where the window cannot be displayed.
137    extensionWindow.off('avoidAreaChange');
138  }
139}
140```
141
142### on('windowSizeChange')
143
144on(type: 'windowSizeChange', callback: Callback<window.Size>): void
145
146Subscribes to the window size change event of the host application.
147
148**Atomic service API**: This API can be used in atomic services since API version 12.
149
150**System capability**: SystemCapability.ArkUI.ArkUI.Full
151
152| Name  | Type                 | Mandatory| Description                  |
153| -------- | --------------------- | ---- | ---------------------- |
154| type     | string                | Yes  | Event type. The value is fixed at **'windowSizeChange'**, indicating the window size change event.|
155| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[window.Size](js-apis-window.md#size7)> | Yes  | Callback used to return the window size.|
156
157**Error codes**
158
159For details about the error codes, see [Universal Error Codes](../errorcode-universal.md).
160
161| ID| Error Message|
162| ------- | -------- |
163| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
164
165**Example**
166
167```ts
168// ExtensionProvider.ts
169import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
170import { window } from '@kit.ArkUI';
171
172export default class EntryAbility extends EmbeddedUIExtensionAbility {
173  onSessionCreate(want: Want, session: UIExtensionContentSession) {
174    const extensionWindow = session.getUIExtensionWindowProxy();
175    // Subscribe to the window size change event of the host application.
176    extensionWindow.on('windowSizeChange', (size: window.Size) => {
177      console.info(`The avoid area of the host window is: ${JSON.stringify(size)}.`);
178    });
179  }
180}
181```
182
183### off('windowSizeChange')
184
185off(type: 'windowSizeChange', callback?: Callback<window.Size>): void
186
187Unsubscribes from the window size change event of the host application.
188
189**Atomic service API**: This API can be used in atomic services since API version 12.
190
191**System capability**: SystemCapability.ArkUI.ArkUI.Full
192
193| Name  | Type                 | Mandatory| Description                  |
194| -------- | --------------------- | ---- | ---------------------- |
195| type     | string                | Yes  | Event type. The value is fixed at **'windowSizeChange'**, indicating the window size change event.|
196| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[window.Size](js-apis-window.md#size7)> | No  | Callback used for unsubscription. If a value is passed in, the corresponding subscription is canceled. If no value is passed in, all subscriptions to the specified event are canceled.|
197
198**Error codes**
199
200For details about the error codes, see [Universal Error Codes](../errorcode-universal.md).
201
202| ID| Error Message|
203| ------- | -------- |
204| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
205
206**Example**
207
208```ts
209// ExtensionProvider.ts
210import { EmbeddedUIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit';
211
212export default class EntryAbility extends EmbeddedUIExtensionAbility {
213  onSessionDestroy(session: UIExtensionContentSession) {
214    const extensionWindow = session.getUIExtensionWindowProxy();
215    // Unsubscribe from the window size change event of the host application.
216    extensionWindow.off('windowSizeChange');
217  }
218}
219```
220
221### createSubWindowWithOptions
222
223createSubWindowWithOptions(name: string, subWindowOptions: window.SubWindowOptions): Promise&lt;window.Window&gt;
224
225Creates a subwindow for this window proxy. This API uses a promise to return the result.
226
227**System capability**: SystemCapability.ArkUI.ArkUI.Full
228
229**Atomic service API**: This API can be used in atomic services since API version 12.
230
231**Model restriction**: This API can be used only in the stage model.
232
233**Parameters**
234
235| Name| Type  | Mandatory| Description          |
236| ------ | ------ | ---- | -------------- |
237| name   | string | Yes  | Name of the subwindow.|
238| subWindowOptions | [window.SubWindowOptions](js-apis-window.md#subwindowoptions11) | Yes  | Parameters used for creating the subwindow. |
239
240**Return value**
241
242| Type                            | Description                                            |
243| -------------------------------- | ------------------------------------------------ |
244| Promise&lt;[window.Window](js-apis-window.md#window)&gt; | Promise used to return the subwindow created.|
245
246**Error codes**
247
248For details about the error codes, see [Universal Error Codes](../errorcode-universal.md). and [Window Error Codes](errorcode-window.md).
249
250| ID| Error Message|
251| ------- | ------------------------------ |
252| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
253| 801 | Capability not supported. Failed to call the API due to limited device capabilities. |
254| 1300002 | This window state is abnormal. |
255| 1300005 | This window proxy is abnormal. |
256
257**Example:**
258
259```ts
260// ExtensionProvider.ts
261import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
262import { window } from '@kit.ArkUI';
263import { BusinessError } from '@kit.BasicServicesKit';
264
265export default class EntryAbility extends EmbeddedUIExtensionAbility {
266  onSessionCreate(want: Want, session: UIExtensionContentSession) {
267    const extensionWindow = session.getUIExtensionWindowProxy();
268    const subWindowOpts: window.SubWindowOptions = {
269      title: 'This is a subwindow',
270      decorEnabled: true
271    };
272    // Create a subwindow.
273    extensionWindow.createSubWindowWithOptions('subWindowForHost', subWindowOpts)
274      .then((subWindow: window.Window) => {
275        subWindow.setUIContent('pages/Index', (err, data) =>{
276          if (err && err.code != 0) {
277            return;
278          }
279          subWindow?.resize(300, 300, (err, data)=>{
280            if (err && err.code != 0) {
281              return;
282            }
283            subWindow?.moveWindowTo(100, 100, (err, data)=>{
284              if (err && err.code != 0) {
285                return;
286              }
287              subWindow?.showWindow((err, data) => {
288                if (err && err.code == 0) {
289                  console.info(`The subwindow has been shown!`);
290                } else {
291                  console.error(`Failed to show the subwindow!`);
292                }
293              });
294            });
295          });
296        });
297      }).catch((error: BusinessError) => {
298        console.error(`Create subwindow failed: ${JSON.stringify(error)}`);
299      })
300  }
301}
302```
303
304## AvoidAreaInfo
305
306Describes the information about the area where the window cannot be displayed.
307
308**Atomic service API**: This API can be used in atomic services since API version 12.
309
310**System capability**: SystemCapability.ArkUI.ArkUI.Full
311
312| Name| Type                | Mandatory| Description       |
313| ------ | -------------------- | ------------------ | ------------------ |
314| type   | [window.AvoidAreaType](js-apis-window.md#avoidareatype7) | Yes| Type of the area where the window cannot be displayed.  |
315| area   | [window.AvoidArea](js-apis-window.md#avoidarea7)     | Yes| Area where the window cannot be displayed.|
316
317## Example
318
319This example shows how to use all the available APIs in the EmbeddedUIExtensionAbility. The bundle name of the sample application is **com.example.embeddeddemo**, and the EmbeddedUIExtensionAbility to start is **ExampleEmbeddedAbility**.
320
321- The EntryAbility (UIAbility) of the sample application loads the **pages/Index.ets** file, whose content is as follows:
322
323  ```ts
324  // The UIAbility loads pages/Index.ets when started.
325  import { Want } from '@kit.AbilityKit';
326
327  @Entry
328  @Component
329  struct Index {
330    @State message: string = 'Message: '
331    private want: Want = {
332      bundleName: "com.example.embeddeddemo",
333      abilityName: "ExampleEmbeddedAbility",
334    }
335
336    build() {
337      Row() {
338        Column() {
339          Text(this.message).fontSize(30)
340          EmbeddedComponent(this.want, EmbeddedType.EMBEDDED_UI_EXTENSION)
341            .width('100%')
342            .height('90%')
343            .onTerminated((info)=>{
344              this.message = 'Termination: code = ' + info.code + ', want = ' + JSON.stringify(info.want);
345            })
346            .onError((error)=>{
347              this.message = 'Error: code = ' + error.code;
348            })
349        }
350        .width('100%')
351      }
352      .height('100%')
353    }
354  }
355  ```
356
357- The EmbeddedUIExtensionAbility to start by the **EmbeddedComponent** is implemented in the **ets/extensionAbility/ExampleEmbeddedAbility** file. The file content is as follows:
358
359  ```ts
360  import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
361
362  const TAG: string = '[ExampleEmbeddedAbility]'
363  export default class ExampleEmbeddedAbility extends EmbeddedUIExtensionAbility {
364
365    onCreate() {
366      console.info(TAG, `onCreate`);
367    }
368
369    onForeground() {
370      console.info(TAG, `onForeground`);
371    }
372
373    onBackground() {
374      console.info(TAG, `onBackground`);
375    }
376
377    onDestroy() {
378      console.info(TAG, `onDestroy`);
379    }
380
381    onSessionCreate(want: Want, session: UIExtensionContentSession) {
382      console.info(TAG, `onSessionCreate, want: ${JSON.stringify(want)}`);
383      let param: Record<string, UIExtensionContentSession> = {
384        'session': session
385      };
386      let storage: LocalStorage = new LocalStorage(param);
387      session.loadContent('pages/extension', storage);
388    }
389  }
390  ```
391
392- The entry page file of the EmbeddedUIExtensionAbility is **pages/extension.ets**, whose content is as follows:
393
394  ```ts
395  import { UIExtensionContentSession } from '@kit.AbilityKit';
396  import { uiExtension, window } from '@kit.ArkUI';
397  import { BusinessError } from '@kit.BasicServicesKit';
398  let storage = LocalStorage.getShared()
399
400  @Entry(storage)
401  @Component
402  struct Extension {
403    @State message: string = 'EmbeddedUIExtensionAbility Index';
404    private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session');
405    private extensionWindow: uiExtension.WindowProxy | undefined = this.session?.getUIExtensionWindowProxy();
406    private subWindow: window.Window | undefined = undefined;
407
408    aboutToAppear(): void {
409      this.extensionWindow?.on('windowSizeChange', (size: window.Size) => {
410          console.info(`size = ${JSON.stringify(size)}`);
411      });
412      this.extensionWindow?.on('avoidAreaChange', (info: uiExtension.AvoidAreaInfo) => {
413          console.info(`type = ${JSON.stringify(info.type)}, area = ${JSON.stringify(info.area)}`);
414      });
415    }
416
417    aboutToDisappear(): void {
418      this.extensionWindow?.off('windowSizeChange');
419      this.extensionWindow?.off('avoidAreaChange');
420    }
421
422    build() {
423      Column() {
424        Text(this.message)
425          .fontSize(20)
426          .fontWeight(FontWeight.Bold)
427        Button("Obtain Avoid Area Info").width('90%').margin({top: 5, bottom: 5}).fontSize(16).onClick(() => {
428          let avoidArea: window.AvoidArea | undefined = this.extensionWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
429          console.info(`System avoid area: ${JSON.stringify(avoidArea)}`);
430        })
431        Button("Create Subwindow").width('90%').margin({top: 5, bottom: 5}).fontSize(16).onClick(() => {
432          let subWindowOpts: window.SubWindowOptions = {
433              'title': 'This is a subwindow',
434              decorEnabled: true
435          };
436          this.extensionWindow?.createSubWindowWithOptions('subWindowForHost', subWindowOpts)
437              .then((subWindow: window.Window) => {
438                  this.subWindow = subWindow;
439                  this.subWindow.loadContent('pages/Index', storage, (err, data) =>{
440                      if (err && err.code != 0) {
441                          return;
442                      }
443                      this.subWindow?.resize(300, 300, (err, data)=>{
444                          if (err && err.code != 0) {
445                              return;
446                          }
447                          this.subWindow?.moveWindowTo(100, 100, (err, data)=>{
448                              if (err && err.code != 0) {
449                                  return;
450                              }
451                              this.subWindow?.showWindow((err, data) => {
452                                  if (err && err.code == 0) {
453                                      console.info(`The subwindow has been shown!`);
454                                  } else {
455                                      console.error(`Failed to show the subwindow!`);
456                                  }
457                              });
458                          });
459                      });
460                  });
461              }).catch((error: BusinessError) => {
462                  console.error(`Create subwindow failed: ${JSON.stringify(error)}`);
463              })
464        })
465      }.width('100%').height('100%')
466    }
467  }
468  ```
469
470- Add an item to **extensionAbilities** in the **module.json5** file of the sample application. The details are as follows:
471  ```json
472  {
473    "name": "ExampleEmbeddedAbility",
474    "srcEntry": "./ets/extensionAbility/ExampleEmbeddedAbility.ets",
475    "type": "embeddedUI"
476  }
477  ```
478