提交 f462a9d7 编写于 作者: G Gloria

Update docs against 21243+20995+20978+21051+20693

Signed-off-by: wusongqing<wusongqing@huawei.com>
上级 c88b278c
# Native Window Development # NativeWindow Development
## When to Use ## When to Use
**NativeWindow** is a local platform-based window of OpenHarmony that represents the producer of a graphics queue. It provides APIs for you to create a native window from **Surface**, create a native window buffer from **SurfaceBuffer**, and request and flush a buffer. **NativeWindow** is a local platform-based window of OpenHarmony that represents the producer of a graphics queue. It provides APIs for you to request and flush a buffer and configure buffer attributes.
The following scenarios are common for native window development:
* Request a graphics buffer by using the NAPI provided by **NativeWindow**, write the produced graphics content to the buffer, and flush the buffer to the graphics queue. The following scenarios are common for NativeWindow development:
* Request a graphics buffer by using the native API provided by **NativeWindow**, write the produced graphics content to the buffer, and flush the buffer to the graphics queue.
* Request and flush a buffer when adapting to the **eglswapbuffer** interface at the EGL. * Request and flush a buffer when adapting to the **eglswapbuffer** interface at the EGL.
## Available APIs ## Available APIs
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| OH_NativeWindow_CreateNativeWindowFromSurface (void \*pSurface) | Creates a **NativeWindow** instance. A new **NativeWindow** instance is created each time this function is called.| | OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests an **OHNativeWindowBuffer** through an **OHNativeWindow** instance for content production.|
| OH_NativeWindow_DestroyNativeWindow (OHNativeWindow \*window) | Decreases the reference count of a **NativeWindow** instance by 1 and, when the reference count reaches 0, destroys the instance.| | OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **OHNativeWindowBuffer** filled with the content to the buffer queue through an **OHNativeWindow** instance for content consumption.|
| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void \*pSurfaceBuffer) | Creates a **NativeWindowBuffer** instance. A new **NativeWindowBuffer** instance is created each time this function is called.| | OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of an **OHNativeWindow**, including the width, height, and content format.|
| OH_NativeWindow_DestroyNativeWindowBuffer (OHNativeWindowBuffer \*buffer) | Decreases the reference count of a **NativeWindowBuffer** instance by 1 and, when the reference count reaches 0, destroys the instance.|
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests a **NativeWindowBuffer** through a **NativeWindow** instance for content production.| For details about the APIs, see [native_window](../reference/native-apis/_native_window.md).
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **NativeWindowBuffer** filled with the content to the buffer queue through a **NativeWindow** instance for content consumption.|
| OH_NativeWindow_NativeWindowAbortBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer) | Returns the **NativeWindowBuffer** to the buffer queue through a **NativeWindow** instance, without filling in any content. The **NativeWindowBuffer** can be used for another request.|
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of a native window, including the width, height, and content format.|
| OH_NativeWindow_GetBufferHandleFromNative (OHNativeWindowBuffer \*buffer) | Obtains the pointer to a **BufferHandle** of a **NativeWindowBuffer** instance.|
| OH_NativeWindow_NativeObjectReference (void \*obj) | Adds the reference count of a native object.|
| OH_NativeWindow_NativeObjectUnreference (void \*obj) | Decreases the reference count of a native object and, when the reference count reaches 0, destroys this object.|
| OH_NativeWindow_GetNativeObjectMagic (void \*obj) | Obtains the magic ID of a native object.|
| OH_NativeWindow_NativeWindowSetScalingMode (OHNativeWindow \*window, uint32_t sequence, OHScalingMode scalingMode) | Sets the scaling mode of the native window.|
| OH_NativeWindow_NativeWindowSetMetaData(OHNativeWindow \*window, uint32_t sequence, int32_t size, const OHHDRMetaData \*metaData) | Sets the HDR static metadata of the native window.|
| OH_NativeWindow_NativeWindowSetMetaDataSet(OHNativeWindow \*window, uint32_t sequence, OHHDRMetadataKey key, int32_t size, const uint8_t \*metaData) | Sets the HDR static metadata set of the native window.|
| OH_NativeWindow_NativeWindowSetTunnelHandle(OHNativeWindow \*window, const OHExtDataHandle \*handle) | Sets the tunnel handle to the native window.|
## How to Develop ## How to Develop
The following describes how to use the NAPI provided by **NativeWindow** to request a graphics buffer, write the produced graphics content to the buffer, and flush the buffer to the graphics queue. The following describes how to use the native APIs provided by **NativeWindow** to request a graphics buffer, write the produced graphics content to the buffer, and flush the buffer to the graphics queue.
**Adding Dynamic Link Libraries**
Add the following libraries to **CMakeLists.txt**:
```txt
libace_ndk.z.so
libnative_window.so
```
**Header File**
```c++
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <native_window/external_window.h>
```
1. Obtain an **OHNativeWindow** instance.
1. Obtain a **NativeWindow** instance, which can be obtained by running the APIs provided by **OH_NativeXComponent_Callback**. You can call the APIs provided by [OH_NativeXComponent_Callback](../reference/native-apis/_o_h___native_x_component___callback.md) to obtain an **OHNativeWindow** instance. An example code snippet is provided below. For details about how to use the **\<XComponent>**, see [XComponent](../ui/arkts-common-components-xcomponent.md).
1. Define **XComponent** in an .ets file. 1. Add an **\<XComponent>** to the .ets file.
```ts ```ts
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'nativerender'}) XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry'})
.onLoad((context) => { .width(360)
this.context = context; .height(360)
}) ```
.onDestroy(() => { 2. Obtain **NativeXComponent** at the native C++ layer.
}) ```c++
napi_value exportInstance = nullptr;
// Parse the attribute of the wrapped NativeXComponent pointer.
napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
OH_NativeXComponent *nativeXComponent = nullptr;
// Use the napi_unwrap API to parse the NativeXComponent instance pointer.
napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
```
3. Define **OH_NativeXComponent_Callback**.
```c++
// Define the callback.
void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
{
// Obtain an OHNativeWindow instance.
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
// ...
}
void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
{
// Obtain an OHNativeWindow instance.
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
// ...
}
void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
{
// Obtain an OHNativeWindow instance.
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
// ...
}
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
{
// Obtain an OHNativeWindow instance.
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
// ...
}
```
```c++
// Initialize OH_NativeXComponent_Callback.
OH_NativeXComponent_Callback callback;
callback.OnSurfaceCreated = OnSurfaceCreatedCB;
callback.OnSurfaceChanged = OnSurfaceChangedCB;
callback.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
callback.DispatchTouchEvent = DispatchTouchEventCB;
``` ```
2. Obtain **NativeXComponent** at the native C++ layer.
```c++
napi_value exportInstance = nullptr;
napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
OH_NativeXComponent *nativeXComponent = nullptr;
napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { };
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
```
3. Define **OH_NativeXComponent_Callback**.
```c++
// Define the callback.
void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
{
// Obtain a NativeWindow instance.
OHNativeWindow* nativeWindow = window;
// ...
}
void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
{
// Obtain a NativeWindow instance.
OHNativeWindow* nativeWindow = window;
// ...
}
void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
{
// Obtain a NativeWindow instance.
OHNativeWindow* nativeWindow = window;
// ...
}
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
{
// Obtain a NativeWindow instance.
OHNativeWindow* nativeWindow = window;
// ...
}
```
```c++
// Initialize OH_NativeXComponent_Callback.
OH_NativeXComponent_Callback callback_;
callback_->OnSurfaceCreated = OnSurfaceCreatedCB;
callback_->OnSurfaceChanged = OnSurfaceChangedCB;
callback_->OnSurfaceDestroyed = OnSurfaceDestroyedCB;
callback_->DispatchTouchEvent = DispatchTouchEventCB;
```
4. Register **OH_NativeXComponent_Callback** with **NativeXComponent**. 4. Register **OH_NativeXComponent_Callback** with **NativeXComponent**.
```c++ ```c++
OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback_); // Register the callback.
``` OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
```
2. Set the attributes of a native window buffer by using **OH_NativeWindow_NativeWindowHandleOpt**. 2. Set the attributes of an **OHNativeWindowBuffer** by using **OH_NativeWindow_NativeWindowHandleOpt**.
```c++ ```c++
// Set the read and write scenarios of the native window buffer. // Set the width and height of the OHNativeWindowBuffer.
int code = SET_USAGE; int32_t code = SET_BUFFER_GEOMETRY;
int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage);
// Set the width and height of the native window buffer.
code = SET_BUFFER_GEOMETRY;
int32_t width = 0x100; int32_t width = 0x100;
int32_t height = 0x100; int32_t height = 0x100;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height); // The nativeWindow instance is obtained from the callback in the previous step.
// Set the step of the native window buffer. int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
// Set the step of the OHNativeWindowBuffer.
code = SET_STRIDE; code = SET_STRIDE;
int32_t stride = 0x8; int32_t stride = 0x8;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride); ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
// Set the format of the native window buffer.
code = SET_FORMAT;
int32_t format = PIXEL_FMT_RGBA_8888;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format);
``` ```
3. Request a native window buffer from the graphics queue. 3. Request an **OHNativeWindowBuffer** from the graphics queue.
```c++ ```c++
struct NativeWindowBuffer* buffer = nullptr; OHNativeWindowBuffer* buffer = nullptr;
int fenceFd; int fenceFd;
// Obtain the NativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer. // Obtain the OHNativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd); OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
// Obtain the buffer handle by calling OH_NativeWindow_GetNativeBufferHandleFromNative. // Obtain the buffer handle by calling OH_NativeWindow_GetBufferHandleFromNative.
BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer); BufferHandle* bufferHandle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
``` ```
4. Write the produced content to the native window buffer. 4. Map memory.
```c++
#include <sys/mman.h>
// Use mmap() to obtain the memory virtual address of buffer handle.
void* mappedAddr = mmap(bufferHandle->virAddr, bufferHandle->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0);
if (mappedAddr == MAP_FAILED) {
// mmap failed
}
```
5. Write the produced content to the **OHNativeWindowBuffer**.
```c++ ```c++
auto image = static_cast<uint8_t *>(buffer->sfbuffer->GetVirAddr());
static uint32_t value = 0x00; static uint32_t value = 0x00;
value++; value++;
uint32_t *pixel = static_cast<uint32_t *>(mappedAddr); // Use the address obtained by mmap() to access the memory.
uint32_t *pixel = static_cast<uint32_t *>(image);
for (uint32_t x = 0; x < width; x++) { for (uint32_t x = 0; x < width; x++) {
for (uint32_t y = 0; y < height; y++) { for (uint32_t y = 0; y < height; y++) {
*pixel++ = value; *pixel++ = value;
...@@ -141,10 +144,18 @@ The following describes how to use the NAPI provided by **NativeWindow** to requ ...@@ -141,10 +144,18 @@ The following describes how to use the NAPI provided by **NativeWindow** to requ
} }
``` ```
5. Flush the native window buffer to the graphics queue. 5. Flush the **OHNativeWindowBuffer** to the graphics queue.
```c++ ```c++
// Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the native window buffer are changed. // Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the OHNativeWindowBuffer are changed.
Region region{nullptr, 0}; Region region{nullptr, 0};
// Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen. // Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen.
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region); OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
```
6. Unmap memory.
```c++
// Unmap the memory when the memory is no longer required.
int result = munmap(mappedAddr, bufferHandle->size);
if (result == -1) {
// munmap failed
}
``` ```
...@@ -2514,7 +2514,7 @@ try { ...@@ -2514,7 +2514,7 @@ try {
### on('avoidAreaChange')<sup>9+</sup> ### on('avoidAreaChange')<sup>9+</sup>
on(type: 'avoidAreaChange', callback: Callback&lt;{AvoidAreaType, AvoidArea}&gt;): void on(type: 'avoidAreaChange', callback: Callback&lt;{type: AvoidAreaType, area: AvoidArea}&gt;): void
Enables listening for changes to the area where the window cannot be displayed. Enables listening for changes to the area where the window cannot be displayed.
...@@ -2525,7 +2525,7 @@ Enables listening for changes to the area where the window cannot be displayed. ...@@ -2525,7 +2525,7 @@ Enables listening for changes to the area where the window cannot be displayed.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- |------------------------------------------------------------------| ---- |--------------------------------------| | -------- |------------------------------------------------------------------| ---- |--------------------------------------|
| 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.| | 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.|
| callback | Callback&lt;{[AvoidAreaType](#avoidareatype7), [AvoidArea](#avoidarea7)}&gt; | Yes | Callback used to return the area and area type.| | callback | Callback&lt;{type: [AvoidAreaType](#avoidareatype7), area: [AvoidArea](#avoidarea7)}&gt; | Yes | Callback used to return the area and area type.|
**Example** **Example**
...@@ -2542,7 +2542,7 @@ try { ...@@ -2542,7 +2542,7 @@ try {
### off('avoidAreaChange')<sup>9+</sup> ### off('avoidAreaChange')<sup>9+</sup>
off(type: 'avoidAreaChange', callback?: Callback&lt;{AvoidAreaType, AvoidArea}&gt;): void off(type: 'avoidAreaChange', callback?: Callback&lt;{type: AvoidAreaType, area: AvoidArea}&gt;): void
Disables listening for changes to the area where the window cannot be displayed. Disables listening for changes to the area where the window cannot be displayed.
...@@ -2553,7 +2553,7 @@ Disables listening for changes to the area where the window cannot be displayed. ...@@ -2553,7 +2553,7 @@ Disables listening for changes to the area where the window cannot be displayed.
| Name | Type | Mandatory | Description | | Name | Type | Mandatory | Description |
| -------- |-----------------------------------------------------------------------------|-----|------------------------------------| | -------- |-----------------------------------------------------------------------------|-----|------------------------------------|
| 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.| | 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.|
| callback | Callback&lt;{[AvoidAreaType](#avoidareatype7), [AvoidArea](#avoidarea7)}&gt; | No | Callback used to return the area and area type.| | callback | Callback&lt;{type: [AvoidAreaType](#avoidareatype7), area: [AvoidArea](#avoidarea7)}&gt; | No | Callback used to return the area and area type.|
**Example** **Example**
...@@ -2788,7 +2788,16 @@ class TestRemoteObject extends rpc.RemoteObject { ...@@ -2788,7 +2788,16 @@ class TestRemoteObject extends rpc.RemoteObject {
} }
let token = new TestRemoteObject('testObject'); let token = new TestRemoteObject('testObject');
let windowClass = null;
let config = {name: "dialogWindow", windowType: window.WindowType.TYPE_DIALOG, ctx: this.context};
try { try {
window.createWindow(config, (err, data) => {
if (err.code) {
console.error('Failed to create the window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
});
windowClass.bindDialogTarget(token, () => { windowClass.bindDialogTarget(token, () => {
console.info('Dialog Window Need Destroy.'); console.info('Dialog Window Need Destroy.');
}, (err) => { }, (err) => {
...@@ -2861,7 +2870,16 @@ class TestRemoteObject extends rpc.RemoteObject { ...@@ -2861,7 +2870,16 @@ class TestRemoteObject extends rpc.RemoteObject {
} }
let token = new TestRemoteObject('testObject'); let token = new TestRemoteObject('testObject');
let windowClass = null;
let config = {name: "dialogWindow", windowType: window.WindowType.TYPE_DIALOG, ctx: this.context};
try { try {
window.createWindow(config, (err, data) => {
if (err.code) {
console.error('Failed to create the window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
});
let promise = windowClass.bindDialogTarget(token, () => { let promise = windowClass.bindDialogTarget(token, () => {
console.info('Dialog Window Need Destroy.'); console.info('Dialog Window Need Destroy.');
}); });
...@@ -2875,6 +2893,172 @@ try { ...@@ -2875,6 +2893,172 @@ try {
} }
``` ```
### bindDialogTarget<sup>9+</sup>
bindDialogTarget(requestInfo: dialogRequest.RequestInfo, deathCallback: Callback&lt;void&gt;, callback: AsyncCallback&lt;void&gt;): void
Binds the modal window to the target window, and adds a callback to listen for modal window destruction events. This API uses an asynchronous callback to return the result.
**System API**: This is a system API.
**System capability**: SystemCapability.WindowManager.WindowManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| ----------- | ------------------------- | ---- | -------------------- |
| requestInfo | [dialogRequest.RequestInfo](js-apis-app-ability-dialogRequest.md#requestinfo) | Yes | **RequestInfo** of the target window.|
| deathCallback | Callback&lt;void&gt; | Yes | Callback used to listen for modal window destruction events.|
| callback | AsyncCallback&lt;void&gt; | Yes | Callback used to return the result.|
**Error codes**
For details about the error codes, see [Window Error Codes](../errorcodes/errorcode-window.md).
| ID| Error Message|
| ------- | -------------------------------------------- |
| 1300002 | This window state is abnormal. |
| 1300003 | This window manager service works abnormally. |
**Example**
```js
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
import rpc from '@ohos.rpc';
import dialogRequest from '@ohos.app.ability.dialogRequest';
import window from '@ohos.window';
export default class ServiceExtAbility extends ServiceExtensionAbility {
onCreate(want) {
console.info('onCreate');
}
onRequest(want, startId) {
console.info('onRequest');
let windowClass = null;
let config = {name: "dialogWindow", windowType: window.WindowType.TYPE_DIALOG, ctx: this.context};
try {
window.createWindow(config, (err, data) => {
if (err.code) {
console.error('Failed to create the window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
});
let requestInfo = dialogRequest.getRequestInfo(want)
windowClass.bindDialogTarget(requestInfo, () => {
console.info('Dialog Window Need Destroy.');
}, (err) => {
if (err.code) {
console.error('Failed to bind dialog target. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in binding dialog target.');
});
} catch(err) {
console.error('Failed to bind dialog target. Cause:' + JSON.stringify(err))
}
}
onConnect(want) {
console.info('onConnect');
}
onDisconnect(want) {
console.info('onDisconnect');
}
onDestroy() {
console.info('onDestroy');
}
}
```
### bindDialogTarget<sup>9+</sup>
bindDialogTarget(requestInfo: dialogRequest.RequestInfo, deathCallback: Callback&lt;void&gt;): Promise&lt;void&gt;
Binds the modal window to the target window, and adds a callback to listen for modal window destruction events. This API uses a promise to return the result.
**System API**: This is a system API.
**System capability**: SystemCapability.WindowManager.WindowManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| ----------- | ------------------------- | ---- | -------------------- |
| requestInfo | [dialogRequest.RequestInfo](js-apis-app-ability-dialogRequest.md#requestinfo) | Yes | **RequestInfo** of the target window.|
| deathCallback | Callback&lt;void&gt; | Yes | Callback used to listen for modal window destruction events.|
**Return value**
| Type | Description |
| ------------------- | ------------------------- |
| Promise&lt;void&gt; | Promise that returns no value.|
**Error codes**
For details about the error codes, see [Window Error Codes](../errorcodes/errorcode-window.md).
| ID| Error Message|
| ------- | -------------------------------------------- |
| 1300002 | This window state is abnormal. |
| 1300003 | This window manager service works abnormally. |
**Example**
```js
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
import rpc from '@ohos.rpc';
import dialogRequest from '@ohos.app.ability.dialogRequest';
import window from '@ohos.window';
export default class ServiceExtAbility extends ServiceExtensionAbility {
onCreate(want) {
console.info('onCreate');
}
onRequest(want, startId) {
console.info('onRequest');
let windowClass = null;
let config = {name: "dialogWindow", windowType: window.WindowType.TYPE_DIALOG, ctx: this.context};
try {
window.createWindow(config, (err, data) => {
if (err.code) {
console.error('Failed to create the window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
});
let requestInfo = dialogRequest.getRequestInfo(want)
let promise = windowClass.bindDialogTarget(requestInfo, () => {
console.info('Dialog Window Need Destroy.');
});
promise.then(()=> {
console.info('Succeeded in binding dialog target.');
}).catch((err)=>{
console.error('Failed to bind dialog target. Cause:' + JSON.stringify(err));
});
} catch(err) {
console.error('Failed to bind dialog target. Cause:' + JSON.stringify(err))
}
}
onConnect(want) {
console.info('onConnect');
}
onDisconnect(want) {
console.info('onDisconnect');
}
onDestroy() {
console.info('onDestroy');
}
}
```
### isWindowSupportWideGamut<sup>9+</sup> ### isWindowSupportWideGamut<sup>9+</sup>
isWindowSupportWideGamut(callback: AsyncCallback&lt;boolean&gt;): void isWindowSupportWideGamut(callback: AsyncCallback&lt;boolean&gt;): void
......
# Distributed Remote Startup<a name="EN-US_TOPIC_0000001051071561"></a>
## Overview<a name="section186634310418"></a>
The Distributed Manager Service sets up a distributed service platform in OpenHarmony by using a proxy between the primary and secondary devices. With the Distributed Manager Service, the primary device \(OpenHarmony-powered smart TV\) can start a Feature Ability \(FA\) deployed on the secondary device \(a memory-constrained OpenHarmony device such as an IP camera or a lite wearable\).
For example, if a user presses the **Remind Me** button for a TV program on the smart TV, the smart TV will start the corresponding reminder FA on the lite wearable to remind the user when the particular TV program is available.
## Basic Concepts<a name="section982651246"></a>
- FA
Feature Ability, representing an ability with a UI for interacting with users
- Remote startup
Cross-device FA startup, which is the counterpart of local FA startup
## Available APIs<a name="section125479541744"></a>
The following table describes the API that can be used by smart TVs to remotely start an FA. This API is provided in the **AbilitySlice** class. For details, see the Java API reference for OpenHarmony application development.
**Table 1** API for remotely starting an FA on the distributed network
<a name="table1731550155318"></a>
<table><thead align="left"><tr id="row4419501537"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p54150165315"><a name="p54150165315"></a><a name="p54150165315"></a>Method</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p941150145313"><a name="p941150145313"></a><a name="p941150145313"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row34145016535"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1682733119213"><a name="p1682733119213"></a><a name="p1682733119213"></a>void startAbility(Want want)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p13562171015712"><a name="p13562171015712"></a><a name="p13562171015712"></a>Remotely starts an FA based on the specified <strong id="b8984536181113"><a name="b8984536181113"></a><a name="b8984536181113"></a>Want</strong> information. If the name and type of the <strong id="b599520304618"><a name="b599520304618"></a><a name="b599520304618"></a>want</strong> parameter are different from those used in the integrated development environment (IDE), use the parameter name and type in the IDE.</p>
</td>
</tr>
</tbody>
</table>
**Table 2** Description of the want parameter
<a name="table02120432364"></a>
<table><thead align="left"><tr id="row172294315361"><th class="cellrowborder" valign="top" width="14.000000000000002%" id="mcps1.2.4.1.1"><p id="p722144318360"><a name="p722144318360"></a><a name="p722144318360"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="17%" id="mcps1.2.4.1.2"><p id="p10227434363"><a name="p10227434363"></a><a name="p10227434363"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="69%" id="mcps1.2.4.1.3"><p id="p22284383616"><a name="p22284383616"></a><a name="p22284383616"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row3228436365"><td class="cellrowborder" valign="top" width="14.000000000000002%" headers="mcps1.2.4.1.1 "><p id="p1391227193713"><a name="p1391227193713"></a><a name="p1391227193713"></a>want</p>
</td>
<td class="cellrowborder" valign="top" width="17%" headers="mcps1.2.4.1.2 "><p id="p20993611193719"><a name="p20993611193719"></a><a name="p20993611193719"></a>ohos.aafwk.content.Want</p>
</td>
<td class="cellrowborder" valign="top" width="69%" headers="mcps1.2.4.1.3 "><p id="p10555172211377"><a name="p10555172211377"></a><a name="p10555172211377"></a>When you use <strong id="b1013275220199"><a name="b1013275220199"></a><a name="b1013275220199"></a>startAbility(Want want)</strong> to remotely start an FA, you must first specify the <strong id="b1125035416223"><a name="b1125035416223"></a><a name="b1125035416223"></a>deviceId</strong>, <strong id="b16473135811222"><a name="b16473135811222"></a><a name="b16473135811222"></a>bundleName</strong>, and <strong id="b157931324230"><a name="b157931324230"></a><a name="b157931324230"></a>abilityName</strong> attributes of the target FA in the <strong id="b34832152239"><a name="b34832152239"></a><a name="b34832152239"></a>Want</strong> object.</p>
</td>
</tr>
</tbody>
</table>
## Limitations and Constraints<a name="section1165911177314"></a>
- The primary device can remotely start an FA of the secondary device, but the secondary device cannot remotely start an FA of the primary device.
- Before the remote startup, ensure that the two OpenHarmony devices are on the same network segment and can ping each other on the distributed network. Otherwise, the remote startup fails.
- Currently, only the FAs that have the same public key \(that is, the same Huawei certificate\) can be started between the primary and secondary devices.
## How to Develop<a name="section34171333656"></a>
To enable the primary device \(smart TV\) to start an FA of the secondary device \(assuming that the target FA has been developed\), perform the following steps:
1. Complete FA development for the smart TV on DevEco Studio.
2. Obtain the IDs of online secondary devices.
```
// Import the header files required for device selection.
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
// Obtain the online device list.
List<DeviceInfo> deviceInfoListOnline = DeviceManager.getDmsDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
String remote_device_id;
if (deviceInfoListOnline.size() > 0)
{
remote_device_id = deviceInfoListOnline[0].GetDeviceId(); // Obtain the ID of the first device in the online device list.
}
```
3. Create a **Want** instance. You should first create an **ElementName** object with **deviceId**, **bundleName**, **abilityName** specified and add this object to the **Want** instance. Then, set the multi-device startup flag **Want.FLAG\_ABILITYSLICE\_MULTI\_DEVICE** to the **Want** instance to enable remote FA startup.
```
// Import related header files.
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Want;
import ohos.bundle.ElementName;
// Start the remote FA on the secondary device.
Want want = new Want(); // Create a Want instance that encapsulates information about the remote FA to start.
// Use the device ID obtained in step 2 and specify the FA information.
ElementName name = new ElementName(remote_device_id, "com.huawei.remote_package_name", "remote_class_name");
want.setElement(name); // Add information about the target FA for startup to the Want instance.
want.setFlags(Want.FLAG_ABILITYSLICE_MULTI_DEVICE); // Set the multi-device startup flag. If this flag is not set, remote FA startup will be unavailable.
startAbility(want); // Start the specified FA based on the want parameter. If the name and type of the want parameter are different from those used in the IDE, use the parameter name and type in the IDE.
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册