diff --git a/en/application-dev/application-models/serviceextensionability.md b/en/application-dev/application-models/serviceextensionability.md index 0c3725a3761806124682550d26ba836448a613c1..d5b930aa4a1e3e7fb138f903dd436292867613cf 100644 --- a/en/application-dev/application-models/serviceextensionability.md +++ b/en/application-dev/application-models/serviceextensionability.md @@ -2,11 +2,11 @@ ## Overview -[ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) is an ExtensionAbility component of the service type that provides capabilities related to background services. It holds an internal [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md), through which a variety of APIs are provided for external systems. +[ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) is an ExtensionAbility component of the service type that provides capabilities related to background services. It holds an internal [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md), which provides a variety of APIs are provided for external systems. -In this document, the started ServiceExtensionAbility component is called the server, and the component that starts ServiceExtensionAbility is called the client. +In this document, the started ServiceExtensionAbility is called the server, and the component that starts the ServiceExtensionAbility is called the client. -A ServiceExtensionAbility can be started or connected by other components to process transactions in the background based on the request of the caller. System applications can call the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method to start background services or call the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to background services. Third-party applications can call only [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) to connect to background services. The differences between starting and connecting to background services are as follows: +A ServiceExtensionAbility can be started or connected by other components to process transactions in the background based on the request of the caller. System applications can call the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method to start a ServiceExtensionAbility or call the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to a ServiceExtensionAbility. Third-party applications can call only [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) to connect to a ServiceExtensionAbility. The differences between starting and connecting to a ServiceExtensionAbility are as follows: - **Starting**: In the case that AbilityA starts ServiceB, they are weakly associated. After AbilityA exits, ServiceB remains running. @@ -20,55 +20,56 @@ Note the following: > **NOTE** > -> - Currently, third-party applications cannot implement ServiceExtensionAbility. Alternatively, they can use background tasks to implement transaction processing in the background. For details, see [Background Task](../task-management/background-task-overview.md). -> - UIAbility of a third-party application can connect to ServiceExtensionAbility provided by the system through the context. -> - Third-party applications can connect to ServiceExtensionAbility provided by the system only when they gain focus in the foreground. +> - Currently, third-party applications cannot implement a ServiceExtensionAbility. To implement transaction processing in the background, they can use [background tasks](../task-management/background-task-overview.md). +> +> - A UIAbility of a third-party application can connect to a ServiceExtensionAbility provided by a system application through the context. +> +> - Third-party applications can connect to a ServiceExtensionAbility provided by a system application only when they gain focus in the foreground. ## Lifecycle -[ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) provides the lifecycle callbacks **onCreate()**, **onRequest()**, **onConnect()**, **onDisconnect()**, and **onDestory()**. Override them as required. The following figure shows the lifecycle of ServiceExtensionAbility. - -**Figure 1** ServiceExtensionAbility lifecycle +The [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) class provides the lifecycle callbacks **onCreate()**, **onRequest()**, **onConnect()**, **onDisconnect()**, and **onDestory()**. Override them as required. The following figure shows the ServiceExtensionAbility lifecycle. +**Figure 1** ServiceExtensionAbility lifecycle ![ServiceExtensionAbility-lifecycle](figures/ServiceExtensionAbility-lifecycle.png) - **onCreate** - + This callback is triggered when a ServiceExtensionAbility is created for the first time. You can perform initialization operations, for example, registering a common event listener. > **NOTE** > > If a ServiceExtensionAbility has been created, starting it again does not trigger the **onCreate()** callback. - -- **onRequest** - This callback is triggered when another component calls the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method to start a ServiceExtensionAbility. After being started, the ServiceExtensionAbility runs in the background. This callback is triggered each time the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method is called. +- **onRequest** -- **onConnect** + This callback is triggered when another component calls the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method to start a ServiceExtensionAbility. After being started, the ServiceExtensionAbility runs in the background. This callback is triggered each time the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartserviceextensionability) method is called. - This callback is triggered when another component calls the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to a ServiceExtensionAbility. In this method, a remote proxy object, namely, IRemoteObject, is returned, through which the client communicates with the server by means of RPC. At the same time, the system stores the IRemoteObject. If another component calls the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to this ServiceExtensionAbility, the system directly returns the saved IRemoteObject and does not trigger the callback. +- **onConnect** -- **onDisconnect** + This callback is triggered when another component calls the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to a ServiceExtensionAbility. In this method, a remote proxy object, namely, IRemoteObject, is returned, through which the client communicates with the server by means of RPC. At the same time, the system stores the IRemoteObject. If another component calls the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextconnectserviceextensionability) method to connect to this ServiceExtensionAbility, the system returns the saved IRemoteObject, without triggering the callback. - This callback is triggered when the last connection is interrupted. A connection is interrupted when the client exits or the [disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextdisconnectserviceextensionability) method is called. +- **onDisconnect** -- **onDestroy** + This callback is triggered when the last connection is interrupted. A connection is interrupted when the client exits or the [disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextdisconnectserviceextensionability) method is called. - This callback is triggered when ServiceExtensionAbility is no longer used and the instance is ready for destruction. You can clear resources in this callback, for example, deregister the listener. +- **onDestroy** + + This callback is triggered when a ServiceExtensionAbility is no longer used and the instance is ready for destruction. You can clear resources in this callback, for example, deregistering the listener. ## Implementing a Background Service (for System Applications Only) ### Preparations -Only system applications can implement ServiceExtensionAbility. You must make the following preparations before development: +Only system applications can implement a ServiceExtensionAbility. You must make the following preparations before development: -- **Switching to the full SDK**: All APIs related to ServiceExtensionAbility are marked as system APIs and hidden by default. Therefore, you must manually obtain the full SDK from the mirror and switch to it in DevEco Studio. For details, see [Guide to Switching to Full SDK](../faqs/full-sdk-switch-guide.md). +- **Switching to the full SDK**: All the APIs provided by the **ServiceExtensionAbility** class are marked as system APIs and hidden by default. Therefore, you must manually obtain the full SDK from the mirror and switch to it in DevEco Studio. For details, see [Guide to Switching to Full SDK](../faqs/full-sdk-switch-guide.md). -- **Requesting the AllowAppUsePrivilegeExtension privilege**: Only applications with the **AllowAppUsePrivilegeExtension** privilege can implement ServiceExtensionAbility. For details about how to request the privilege, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). +- **Requesting the AllowAppUsePrivilegeExtension privilege**: Only applications with the **AllowAppUsePrivilegeExtension** privilege can implement a ServiceExtensionAbility. For details about how to request the privilege, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). ### Defining IDL APIs -As a background service, ServiceExtensionAbility needs to provide APIs that can be called by external systems. You can define the APIs in IDL files and use the [IDL tool](../IDL/idl-guidelines.md) to generate proxy and stub files. The following demonstrates how to define a file named **IIdlServiceExt.idl**: +As a background service, a ServiceExtensionAbility needs to provide APIs that can be called by external systems. You can define the APIs in IDL files and use the [IDL tool](../IDL/idl-guidelines.md) to generate proxy and stub files. The following demonstrates how to define a file named **IIdlServiceExt.idl**: ```cpp interface OHOS.IIdlServiceExt { @@ -77,7 +78,7 @@ interface OHOS.IIdlServiceExt { } ``` -Create the **IdlServiceExt** directory in the **ets** directory corresponding to the module of the DevEco Studio project, and copy the files generated by the [IDL tool](../IDL/idl-guidelines.md) to this directory. Then create a file named **idl_service_ext_impl.ts** to implement the IDL APIs. +Create the **IdlServiceExt** directory in the **ets** directory of a module in a DevEco Studio project, and copy the files generated by the [IDL tool](../IDL/idl-guidelines.md) to this directory. Then create a file named **idl_service_ext_impl.ts** to implement the IDL APIs. ``` ├── ets @@ -120,7 +121,7 @@ export default class ServiceExtImpl extends IdlServiceExtStub { To manually create a ServiceExtensionAbility in the DevEco Studio project, perform the following steps: -1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **ServiceExtAbility**. +1. In the **ets** directory of a module in the project, right-click and choose **New > Directory** to create a directory named **ServiceExtAbility**. 2. In the **ServiceExtAbility** directory, right-click and choose **New > TypeScript File** to create a file named **ServiceExtAbility.ts**. @@ -136,7 +137,7 @@ To manually create a ServiceExtensionAbility in the DevEco Studio project, perfo └ ``` -3. In the **ServiceExtAbility.ts** file, add the dependency package for importing ServiceExtensionAbility. Customize a class that inherits from ServiceExtensionAbility and implement the lifecycle callbacks. Return the previously defined **ServiceExtImpl** object in the **onConnect** lifecycle callback. +3. In the **ServiceExtAbility.ts** file, import the ServiceExtensionAbility module. Customize a class that inherits from **ServiceExtensionAbility** and implement the lifecycle callbacks. Return the previously defined **ServiceExtImpl** object in the **onConnect** lifecycle callback. ```ts import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; @@ -171,7 +172,7 @@ To manually create a ServiceExtensionAbility in the DevEco Studio project, perfo } ``` -4. Register ServiceExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the **Module** project. Set **type** to **"service"** and **srcEntry** to the code path of the ServiceExtensionAbility component. +4. Register the ServiceExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) of the module in the project. Set **type** to **"service"** and **srcEntry** to the code path of the ServiceExtensionAbility component. ```json { @@ -197,7 +198,7 @@ A system application uses the [startServiceExtensionAbility()](../reference/apis > **NOTE** > -> [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability), [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability), and [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) of ServiceExtensionContext are system APIs and cannot be called by third-party applications. +> [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability), [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability), and [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) provided by the **ServiceExtensionContext** class are system APIs and cannot be called by third-party applications. 1. Start a new ServiceExtensionAbility in a system application. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). @@ -215,7 +216,7 @@ A system application uses the [startServiceExtensionAbility()](../reference/apis }) ``` -2. Stop ServiceExtensionAbility in the system application. +2. Stop the ServiceExtensionAbility in the system application. ```ts let context = ...; // UIAbilityContext @@ -231,7 +232,7 @@ A system application uses the [startServiceExtensionAbility()](../reference/apis }) ``` -3. Have ServiceExtensionAbility stop itself. +3. Enable the ServiceExtensionAbility to stop itself. ```ts let context = ...; // ServiceExtensionContext @@ -244,17 +245,17 @@ A system application uses the [startServiceExtensionAbility()](../reference/apis > **NOTE** > -> Background services can run in the background for a long time. To minimize resource usage, destroy a background service in time when it finishes the task of the requester. A background service can be destroyed in either of the following ways: +> Background services remain alive in the background for a long time. To minimize resource usage, destroy a background service in time in either of the following ways when it finishes the requested task: > > - The background service calls the [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) method to automatically stop itself. > - Another component calls the [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability) method to stop the background service. -> +> ## Connecting to a Background Service Either a system application or a third-party application can connect to a background service (specified in the **Want** object) through [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability). The [onConnect()](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect) callback is invoked, through which the background service receives the **Want** object passed by the caller. In this way, a persistent connection is established. -The ServiceExtensionAbility component returns an IRemoteObject in the **onConnect()** callback. Through this IRemoteObject, you can define communication interfaces for RPC interaction between the client and server. Multiple clients can connect to the same background service at the same time. After a client finishes the interaction, it must call [disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability) to disconnect from the service. If all clients connected to a background service are disconnected, the system destroys the service. +The ServiceExtensionAbility returns an IRemoteObject in the **onConnect()** callback. Through this IRemoteObject, you can define communication interfaces for RPC interaction between the client and server. Multiple clients can simultaneously connect to the same background service. After a client finishes the interaction, it must call [disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability) to disconnect from the service. If all clients connected to a background service are disconnected, the system destroys the service. - Call **connectServiceExtensionAbility()** to establish a connection to a background service. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). @@ -266,8 +267,8 @@ The ServiceExtensionAbility component returns an IRemoteObject in the **onConnec }; let options = { onConnect(elementName, remote) { - /* The input parameter remote is the object returned by ServiceExtensionAbility in the onConnect lifecycle callback. - * This object is used for communication with ServiceExtensionAbility. For details, see the section below. + /* The input parameter remote is the object returned by the ServiceExtensionAbility in the onConnect lifecycle callback. + * This object is used for communication with the ServiceExtensionAbility. For details, see the section below. */ console.info('onConnect callback'); if (remote === null) { @@ -282,7 +283,7 @@ The ServiceExtensionAbility component returns an IRemoteObject in the **onConnec console.info('onFailed callback') } } - // The ID returned after the connection is set up must be saved. The ID will be passed for service disconnection. + // The ID returned after the connection is set up must be saved. The ID will be used for disconnection. let connectionId = this.context.connectServiceExtensionAbility(want, options); ``` @@ -299,12 +300,12 @@ The ServiceExtensionAbility component returns an IRemoteObject in the **onConnec ## Communication Between the Client and Server -After obtaining the [rpc.RemoteObject](../reference/apis/js-apis-rpc.md#iremoteobject) from the **onConnect()** callback, the client can communicate with ServiceExtensionAbility in either of the following ways: +After obtaining the [rpc.RemoteObject](../reference/apis/js-apis-rpc.md#iremoteobject) from the **onConnect()** lifecycle callback, the client can communicate with the ServiceExtensionAbility in either of the following ways: -- Using the IDL API provided by the server for communication (recommended) +- Using the IDL APIs provided by the server for communication (recommended) ```ts - // The client needs to import idl_service_ext_proxy.ts provided by the server for external systems to the local project. + // The client needs to import idl_service_ext_proxy.ts provided by the server to the local project. import IdlServiceExtProxy from '../IdlServiceExt/idl_service_ext_proxy'; let options = { @@ -315,7 +316,7 @@ After obtaining the [rpc.RemoteObject](../reference/apis/js-apis-rpc.md#iremoteo return; } let serviceExtProxy = new IdlServiceExtProxy(remote); - // Communication is carried out by API call, without exposing RPC details. + // Communication is carried out by API calling, without exposing RPC details. serviceExtProxy.processData(1, (errorCode, retVal) => { console.info(`processData, errorCode: ${errorCode}, retVal: ${retVal}`); }); @@ -375,11 +376,11 @@ After obtaining the [rpc.RemoteObject](../reference/apis/js-apis-rpc.md#iremoteo ## Client Identity Verification by the Server -When ServiceExtensionAbility is used to provide sensitive services, the client identity must be verified. You can implement the verification on the IDL stub. For details about the IDL API implementation, see [Defining IDL APIs](#defining-idl-apis). Two verification modes are recommended: +When a ServiceExtensionAbility is used to provide sensitive services, the client identity must be verified. You can implement the verification on the IDL stub. For details about the IDL API implementation, see [Defining IDL APIs](#defining-idl-apis). Two verification modes are recommended: - **Verifying the client identity based on callerUid** - Call the [getCallingUid()](../reference/apis/js-apis-rpc.md#getcallinguid) method to obtain the UID of the client, and then call the [getBundleNameByUid()](../reference/apis/js-apis-bundleManager.md#bundlemanagergetbundlenamebyuid) method to obtain the corresponding bundle name. In this way, the client identify is verified. Note that [getBundleNameByUid()](../reference/apis/js-apis-bundleManager.md#bundlemanagergetbundlenamebyuid) is asynchronous, and therefore the server cannot return the verification result to the client. This verification mode applies when the client sends an asynchronous task execution request to the server. The sample code is as follows: + Call the [getCallingUid()](../reference/apis/js-apis-rpc.md#getcallinguid) method to obtain the UID of the client, and then call the [getBundleNameByUid()](../reference/apis/js-apis-bundleManager.md#bundlemanagergetbundlenamebyuid) method to obtain the corresponding bundle name. In this way, the client identify is verified. Note that [getBundleNameByUid()](../reference/apis/js-apis-bundleManager.md#bundlemanagergetbundlenamebyuid) is asynchronous, and therefore the server cannot return the verification result to the client. This verification mode applies when the client sends an asynchronous task request to the server. The sample code is as follows: ```ts import rpc from '@ohos.rpc'; @@ -457,4 +458,3 @@ When ServiceExtensionAbility is used to provide sensitive services, the client i } } ``` -