Function description: Bolstered by the Rockchip RK3568, the HH-SCDAYU200 development board integrates the dual-core GPU and efficient NPU. Its quad-core 64-bit Cortex-A55 processor uses the advanced 22 nm fabrication process and is clocked at up to 2.0 GHz. The board is packed with Bluetooth, Wi-Fi, audio, video, and camera features, with a wide range of expansion ports to accommodate various video input and outputs. It comes with dual GE auto-sensing RJ45 ports, so it can be used in multi-connectivity products, such as network video recorders (NVRs) and industrial gateways. Use case: [DAYU200 Use Case](device-dev/porting/porting-dayu200-on_standard-demo.md)
| Entertainment, easy travel, and smart home, such as kitchen hoods, ovens, and treadmills.| [device_soc_rockchip](https://gitee.com/openharmony/device_soc_rockchip) [device_board_hihope](https://gitee.com/openharmony/device_board_hihope) [vendor_hihope](https://gitee.com/openharmony/vendor_hihope) |
+| Standard system| Runhe HH-SCDAYU200| RK3568 |
Function description: Bolstered by the Rockchip RK3568, the HH-SCDAYU200 development board integrates the dual-core GPU and efficient NPU. Its quad-core 64-bit Cortex-A55 processor uses the advanced 22 nm fabrication process and is clocked at up to 2.0 GHz. The board is packed with Bluetooth, Wi-Fi, audio, video, and camera features, with a wide range of expansion ports to accommodate various video input and outputs. It comes with dual GE auto-sensing RJ45 ports, so it can be used in multi-connectivity products, such as network video recorders (NVRs) and industrial gateways.
| Entertainment, easy travel, and smart home, such as kitchen hoods, ovens, and treadmills.| [device_soc_rockchip](https://gitee.com/openharmony/device_soc_rockchip) [device_board_hihope](https://gitee.com/openharmony/device_board_hihope) [vendor_hihope](https://gitee.com/openharmony/vendor_hihope) |
| Small system| Hispark_Taurus | Hi3516DV300 |
Function Description: Hi3516D V300 is the next-generation system on chip (SoC) for smart HD IP cameras. It integrates the next-generation image signal processor (ISP), H.265 video compression encoder, and high-performance NNIE engine, and delivers high performance in terms of low bit rate, high image quality, intelligent processing and analysis, and low power consumption.
| Smart device with screens, such as refrigerators with screens and head units.| [device_soc_hisilicon](https://gitee.com/openharmony/device_soc_hisilicon) [device_board_hisilicon](https://gitee.com/openharmony/device_board_hisilicon) [vendor_hisilicon](https://gitee.com/openharmony/vendor_hisilicon) |
| Mini system| Multi-modal V200Z-R | BES2600 |
Function description: The multi-modal V200Z-R development board is a high-performance, multi-functional, and cost-effective AIoT SoC powered by the BES2600WM chip of Bestechnic. It integrates a quad-core ARM processor with a frequency of up to 1 GHz as well as dual-mode Wi-Fi and dual-mode Bluetooth. The board supports the 802.11 a/b/g/n/ and BT/BLE 5.2 standards. It is able to accommodate RAM of up to 42 MB and flash memory of up to 32 MB, and supports the MIPI display serial interface (DSI) and camera serial interface (CSI). It is applicable to various AIoT multi-modal VUI and GUI interaction scenarios. Use case: [Multi-modal V200Z-R Use Case](device-dev/porting/porting-bes2600w-on-minisystem-display-demo.md)
| Smart hardware, and smart devices with screens, such as speakers and watches.| [device_soc_bestechnic](https://gitee.com/openharmony/device_soc_bestechnic) [device_board_fnlink](https://gitee.com/openharmony/device_board_fnlink) [vendor_bestechnic](https://gitee.com/openharmony/vendor_bestechnic) |
## Getting Started
-- [Getting Started for Device Development](device-dev/quick-start/quickstart-ide-lite-overview.md)
+- [Getting Started for Device Development](device-dev/quick-start/quickstart-overview.md)
- [Getting Started for Application Development](application-dev/quick-start/start-overview.md)
-
-
## Code Repository Addresses
OpenHarmony project: [https://gitee.com/openharmony](https://gitee.com/openharmony)
@@ -173,6 +171,8 @@ OpenHarmony archived projects: [https://gitee.com/openharmony-retired](https://g
## OpenHarmony Documentation
+[Official website](https://www.openharmony.cn/)
+
[Chinese version](https://gitee.com/openharmony/docs/tree/master/zh-cn)
[English version](https://gitee.com/openharmony/docs/tree/master/en)
@@ -197,7 +197,7 @@ For details about how to contribute, see [How to contribute](contribute/how-to-c
OpenHarmony complies with Apache License Version 2.0. For details, see the LICENSE in each repository.
-OpenHarmony uses third-party open-source software and licenses. For details, see [Third-Party Open-Source Software](https://gitee.com/openharmony/docs/blob/master/en/contribute/third-party-open-source-software-and-license-notice.md).
+OpenHarmony uses third-party open-source software and licenses. For details, see [Open Source Software and License Notice](https://gitee.com/openharmony/docs/blob/master/en/contribute/open-source-software-and-license-notice.md).
## Contact Info
diff --git a/en/application-dev/IDL/figures/SDKpath.png b/en/application-dev/IDL/figures/SDKpath.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa7e33f0246e07fa9f6b8aeb0677c7159dfceb3d
Binary files /dev/null and b/en/application-dev/IDL/figures/SDKpath.png differ
diff --git a/en/application-dev/IDL/figures/SDKpath2.png b/en/application-dev/IDL/figures/SDKpath2.png
new file mode 100644
index 0000000000000000000000000000000000000000..51ac48d2f04d876a204493415b79a5f12e183685
Binary files /dev/null and b/en/application-dev/IDL/figures/SDKpath2.png differ
diff --git a/en/application-dev/IDL/idl-guidelines.md b/en/application-dev/IDL/idl-guidelines.md
index 661b2532c49d36c79855c3e0530326ef590c7cd2..f165215bad4d663b794c249f8029d33aeeda5863 100644
--- a/en/application-dev/IDL/idl-guidelines.md
+++ b/en/application-dev/IDL/idl-guidelines.md
@@ -7,7 +7,7 @@ To ensure successful communications between the client and server, interfaces re

-IDL provides the following functions:
+**IDL provides the following functions:**
- Declares interfaces provided by system services for external systems, and based on the interface declaration, generates C, C++, JS, or TS code for inter-process communication (IPC) or remote procedure call (RPC) proxies and stubs during compilation.
@@ -17,7 +17,7 @@ IDL provides the following functions:

-IDL has the following advantages:
+**IDL has the following advantages:**
- Services are defined in the form of interfaces in IDL. Therefore, you do not need to focus on implementation details.
@@ -149,198 +149,53 @@ The value of <*formal_param_attr*> can be **in**, **out**, or **inout**, indicat
## How to Develop
-### Development Using C++
+### Obtaining IDL
+On DevEco Studio, choose **Tools > SDK Manager** to view the local installation path of the OpenHarmony SDK. The following figure uses DevEco Studio 3.0.0.993 as an example.
+
+
-#### Creating an IDL File
-
- You can use C++ to create IDL files. An example IDL file is as follows:
+Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder named after the version number), and check whether the executable file of IDL exists.
-```cpp
- interface OHOS.IIdlTestService {
- int TestIntTransaction([in] int data);
- void TestStringTransaction([in] String data);
- }
-```
+> **NOTE**: Use the SDK of the latest version. The use of an earlier version may cause errors in some statements.
-You can run the **./idl -gen-cpp -d dir -c dir/iTest.idl** command (**-d** indicates the output directory) to generate the interface file, stub file, and proxy file in the **dir** directory in the execution environment. The names of the generated interface class files are the same as that of the IDL file, except that the file name extensions are **.h** and **.cpp**. For example, the files generated for **IIdlTestService.idl** are **i_idl_test_service.h**, **idl_test_service_proxy.h**, **idl_test_service_stub.h**, **idl_test_service_proxy.cpp**, and **idl_test_service_stub.cpp**.
+If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses the [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md#acquiring-source-code-from-mirrors) as an example.
-#### Exposing Interfaces on the Server
+For details about how to replace the SDK package, see [Guide to Switching to Full SDK](../quick-start/full-sdk-switch-guide.md).
-The stub class generated by IDL is an abstract implementation of the interface class and declares all methods in the IDL file.
+After obtaining the executable file, perform subsequent development steps based on your scenario.
-```cpp
-#ifndef OHOS_IDLTESTSERVICESTUB_H
-#define OHOS_IDLTESTSERVICESTUB_H
-#include
-#include "iidl_test_service.h"
-
-namespace OHOS {
-class IdlTestServiceStub : public IRemoteStub {
-public:
- int OnRemoteRequest(
- /* [in] */ uint32_t code,
- /* [in] */ MessageParcel& data,
- /* [out] */ MessageParcel& reply,
- /* [in] */ MessageOption& option) override;
-
-private:
- static constexpr int COMMAND_TEST_INT_TRANSACTION = MIN_TRANSACTION_ID + 0;
- static constexpr int COMMAND_TEST_STRING_TRANSACTION = MIN_TRANSACTION_ID + 1;
-};
-} // namespace OHOS
-#endif // OHOS_IDLTESTSERVICESTUB_H
-```
+### Development Using TS
-You need to inherit the interface class defined in the IDL file and implement the methods in the class. In addition, you need to register the defined services with SAMGR during service initialization. In the following code snippet, **TestService** inherits the **IdlTestServiceStub** interface class and implements the **TestIntTransaction** and **TestStringTransaction** methods.
+#### Creating an IDL File
-```cpp
-#ifndef OHOS_IPC_TEST_SERVICE_H
-#define OHOS_IPC_TEST_SERVICE_H
-
-#include "hilog/log.h"
-#include "log_tags.h"
-#include "idl_test_service_stub.h"
-
-namespace OHOS {
-class TestService : public IdlTestServiceStub {
-public:
- TestService();
- ~TestService();
- static int Instantiate();
- ErrCode TestIntTransaction(int data, int &rep) override;
- ErrCode TestStringTransaction(const std::string& data) override;
-private:
- static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "TestService" };
-};
-} // namespace OHOS
-#endif // OHOS_IPC_TEST_SERVICE_H
-```
+You can use TS to create IDL files.
-The sample code for registering a service is as follows:
+ For example, create a file named **IIdlTestService.idl** with the following content:
```cpp
-#include "test_service.h"
-
-#include
-
-#include "if_system_ability_manager.h"
-#include "ipc_debug.h"
-#include "ipc_skeleton.h"
-#include "iservice_registry.h"
-#include "system_ability_definition.h"
-
-namespace OHOS {
-using namespace OHOS::HiviewDFX;
-
-int TestService::Instantiate()
-{
- ZLOGI(LABEL, "%{public}s call in", __func__);
- auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
- if (saMgr == nullptr) {
- ZLOGE(LABEL, "%{public}s:fail to get Registry", __func__);
- return -ENODEV;
- }
-
- sptr newInstance = new TestService();
- int result = saMgr->AddSystemAbility(IPC_TEST_SERVICE, newInstance);
- ZLOGI(LABEL, "%{public}s: IPC_TEST_SERVICE result = %{public}d", __func__, result);
- return result;
-}
-
-TestService::TestService()
-{
-}
-
-TestService::~TestService()
-{
-}
-
-ErrCode TestService::TestIntTransaction(int data, int &rep)
-{
- ZLOGE(LABEL, " TestService:read from client data = %{public}d", data);
- rep = data + data;
- return ERR_NONE;
-}
-
-ErrCode TestService::TestStringTransaction(const std::string &data)
-{
- ZLOGE(LABEL, "TestService:read string from client data = %{public}s", data.c_str());
- return data.size();
-}
-} // namespace OHOS
+ interface OHOS.IIdlTestService {
+ int TestIntTransaction([in] int data);
+ void TestStringTransaction([in] String data);
+ }
```
-#### Calling Methods from the Client for IPC
-
-The C++ client obtains the service proxy defined in the system through SAMGR and then invokes the interface provided by the proxy. The sample code is as follows:
+Run the **idl -gen-ts -d *dir* -c dir/IIdlTestService.idl** command in the folder where the executable file is located.
-```cpp
-#include "test_client.h"
-
-#include "if_system_ability_manager.h"
-#include "ipc_debug.h"
-#include "ipc_skeleton.h"
-#include "iservice_registry.h"
-#include "system_ability_definition.h"
-
-namespace OHOS {
-int TestClient::ConnectService()
-{
- auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
- if (saMgr == nullptr) {
- ZLOGE(LABEL, "get registry fail");
- return -1;
- }
+-*dir* next to **d** is the target output folder. For example, if the target output folder is **IIdlTestServiceTs**, run the **idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl** command in the folder where the executable file is located. The interface file, stub file, and proxy file are generated in the *dir* directory (**IIdlTestServiceTs** directory in this example) in the execution environment.
- sptr object = saMgr->GetSystemAbility(IPC_TEST_SERVICE);
- if (object != nullptr) {
- ZLOGE(LABEL, "Got test Service object");
- testService_ = (new (std::nothrow) IdlTestServiceProxy(object));
- }
+> **NOTE**: The generated interface class file name must be the same as that of the .idl file. Otherwise, an error occurs during code generation.
- if (testService_ == nullptr) {
- ZLOGE(LABEL, "Could not find Test Service!");
- return -1;
- }
-
- return 0;
-}
+For example, for an .idl file named **IIdlTestService.idl** and target output directory named **IIdlTestServiceTs**, the directory structure is similar to the following:
-void TestClient::StartIntTransaction()
-{
- if (testService_ != nullptr) {
- ZLOGE(LABEL, "StartIntTransaction");
- [[maybe_unused]] int result = 0;
- testService_->TestIntTransaction(1234, result); // 1234 : test number
- ZLOGE(LABEL, "Rec result from server %{public}d.", result);
- }
-}
-
-void TestClient::StartStringTransaction()
-{
- if (testService_ != nullptr) {
- ZLOGI(LABEL, "StartIntTransaction");
- testService_->TestStringTransaction("IDL Test");
- }
-}
-} // namespace OHOS
```
-
-### Development Using TS
-
-#### Creating an IDL File
-
- You can use TS to create IDL files. An example IDL file is as follows:
-
-```ts
- interface OHOS.IIdlTestService {
- int TestIntTransaction([in] int data);
- void TestStringTransaction([in] String data);
- }
+├── IIdlTestServiceTs # IDL code output folder
+│ ├── i_idl_test_service.ts # File generated
+│ ├── idl_test_service_proxy.ts # File generated
+│ ├── idl_test_service_stub.ts # File generated
+│ └── IIdlTestService.idl # Constructed .idl file
+└── idl.exe # Executable file of IDL
```
-Run the **./idl -c IIdlTestService.idl -gen-ts -d /data/ts/** command (**-d** indicates the output directory) to generate the interface file, stub file, and proxy file in the **/data/ts** directory in the execution environment. The names of the generated interface class files are the same as that of the IDL file, except that the file name extension is **.ts**. For example, the files generated for the **IIdlTestService.idl** file are **i_idl_test_service.ts**, **idl_test_service_proxy.ts**, and **idl_test_service_stub.ts**.
-
#### Exposing Interfaces on the Server
The stub class generated by IDL is an abstract implementation of the interface class and declares all methods in the IDL file.
@@ -356,8 +211,8 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl
super(des);
}
- onRemoteRequest(code: number, data, reply, option): boolean {
- console.log("onRemoteRequest called, code = " + code);
+ async onRemoteRequestEx(code: number, data, reply, option): Promise {
+ console.log("onRemoteRequestEx called, code = " + code);
switch(code) {
case IdlTestServiceStub.COMMAND_TEST_INT_TRANSACTION: {
let _data = data.readInt();
@@ -433,7 +288,7 @@ export default {
console.log('ServiceAbility want:' + JSON.stringify(want));
console.log('ServiceAbility want name:' + want.bundleName)
} catch(err) {
- console.log("ServiceAbility error:" + err)
+ console.log('ServiceAbility error:' + err)
}
console.info('ServiceAbility onConnect end');
return new IdlTestImp('connect');
@@ -455,13 +310,13 @@ import featureAbility from '@ohos.ability.featureAbility';
function callbackTestIntTransaction(result: number, ret: number): void {
if (result == 0 && ret == 124) {
- console.log("case 1 success ");
+ console.log('case 1 success');
}
}
function callbackTestStringTransaction(result: number): void {
if (result == 0) {
- console.log("case 2 success ");
+ console.log('case 2 success');
}
}
@@ -472,17 +327,17 @@ var onAbilityConnectDone = {
testProxy.testStringTransaction('hello', callbackTestStringTransaction);
},
onDisconnect:function (elementName) {
- console.log("onDisconnectService onDisconnect");
+ console.log('onDisconnectService onDisconnect');
},
onFailed:function (code) {
- console.log("onDisconnectService onFailed");
+ console.log('onDisconnectService onFailed');
}
};
function connectAbility: void {
let want = {
- "bundleName":"com.example.myapplicationidl",
- "abilityName": "com.example.myapplicationidl.ServiceAbility"
+ bundleName: 'com.example.myapplicationidl',
+ abilityName: 'com.example.myapplicationidl.ServiceAbility'
};
let connectionId = -1;
connectionId = featureAbility.connectAbility(want, onAbilityConnectDone);
@@ -495,7 +350,7 @@ function connectAbility: void {
You can send a class from one process to another through IPC interfaces. However, you must ensure that the peer can use the code of this class and this class supports the **marshalling** and **unmarshalling** methods. OpenHarmony uses **marshalling** and **unmarshalling** to serialize and deserialize objects into objects that can be identified by each process.
-To create a class that supports the sequenceable type, perform the following operations:
+**To create a class that supports the sequenceable type, perform the following operations:**
1. Implement the **marshalling** method, which obtains the current state of the object and serializes the object into a **Parcel** object.
2. Implement the **unmarshalling** method, which deserializes the object from a **Parcel** object.
@@ -529,137 +384,3 @@ export default class MySequenceable {
private str;
}
```
-
-## How to Develop for Interworking Between C++ and TS
-
-### TS Proxy and C++ Stub Development
-
-#### C++ Service Object
-
-1. Use C++ to construct an IDL file and run commands to generate interfaces, stub files, and proxy files.
-
-2. Create a service object, inherit the interface class defined in the C++ stub file, and implement the methods in the class. An example is as follows:
-
- ```cpp
- class IdlTestServiceImpl : public IdlTestServiceStub {
- public:
- IdlTestServiceImpl() = default;
- virtual ~IdlTestServiceImpl() = default;
-
- ErrCode TestIntTransaction(int _data, int& result) override
- {
- result = 256;
- return ERR_OK;
- }
-
- ErrCode TestStringTransaction(const std::string& _data) override
- {
- return ERR_OK;
- }
- };
- ```
-
-#### Native APIs in C++
-
-C++ provides C++ service objects to TS in the format of native APIs. For example, C++ provides a **GetNativeObject** method, which is used to create an **IdlTestServiceImpl** instance. Using the **NAPI_ohos_rpc_CreateJsRemoteObject** method, you can create a JS remote object for the TS application.
-
-```cpp
-NativeValue* GetNativeObject(NativeEngine& engine, NativeCallbackInfo& info)
-{
- sptr impl = new IdlTestServiceImpl();
- napi_value napiRemoteObject = NAPI_ohos_rpc_CreateJsRemoteObject(reinterpret_cast(&engine), impl);
- NativeValue* nativeRemoteObject = reinterpret_cast(napiRemoteObject);
- return nativeRemoteObject;
-}
-```
-
-#### TS Proxy Object
-
-Use TS to construct an IDL file and run commands to generate interfaces, stub files, and proxy files. An example proxy file is as follows:
-
-```ts
-import {testIntTransactionCallback} from "./i_idl_test_service";
-import {testStringTransactionCallback} from "./i_idl_test_service";
-import IIdlTestService from "./i_idl_test_service";
-import rpc from "@ohos.rpc";
-
-export default class IdlTestServiceProxy implements IIdlTestService {
- constructor(proxy) {
- this.proxy = proxy;
- }
-
- testIntTransaction(data: number, callback: testIntTransactionCallback): void
- {
- let _option = new rpc.MessageOption();
- let _data = new rpc.MessageParcel();
- let _reply = new rpc.MessageParcel();
- _data.writeInt(data);
- this.proxy.sendRequest(IdlTestServiceProxy.COMMAND_TEST_INT_TRANSACTION, _data, _reply, _option).then(function(result) {
- if (result.errCode === 0) {
- let _errCode = result.reply.readInt();
- if (_errCode != 0) {
- let _returnValue = undefined;
- callback(_errCode, _returnValue);
- return;
- }
- let _returnValue = result.reply.readInt();
- callback(_errCode, _returnValue);
- } else {
- console.log("sendRequest failed, errCode: " + result.errCode);
- }
- })
- }
-
- testStringTransaction(data: string, callback: testStringTransactionCallback): void
- {
- let _option = new rpc.MessageOption();
- let _data = new rpc.MessageParcel();
- let _reply = new rpc.MessageParcel();
- _data.writeString(data);
- this.proxy.sendRequest(IdlTestServiceProxy.COMMAND_TEST_STRING_TRANSACTION, _data, _reply, _option).then(function(result) {
- if (result.errCode === 0) {
- let _errCode = result.reply.readInt();
- callback(_errCode);
- } else {
- console.log("sendRequest failed, errCode: " + result.errCode);
- }
- })
- }
-
- static readonly COMMAND_TEST_INT_TRANSACTION = 1;
- static readonly COMMAND_TEST_STRING_TRANSACTION = 2;
- private proxy
-}
-```
-
-#### Interworking Between TS and C++ Applications
-
-1. The TS application invokes the native API to obtain the remote C++ service object.
-2. Construct a TS proxy and transfers the remote C++ service object to it.
-3. Use the TS proxy to call the method declared in the IDL file to implement the interworking between the TS proxy and C++ stub. The following is an example:
-
-```ts
-import IdlTestServiceProxy from './idl_test_service_proxy'
-import nativeMgr from 'nativeManager';
-
-function testIntTransactionCallback(errCode: number, returnValue: number)
-{
- console.log("errCode: " + errCode + " returnValue: " + returnValue);
-}
-
-function testStringTransactionCallback(errCode: number)
-{
- console.log("errCode: " + errCode);
-}
-
-function jsProxyTriggerCppStub()
-{
- let nativeObj = nativeMgr.GetNativeObject();
- let tsProxy = new IdlTestServiceProxy(nativeObj);
- // Call testIntTransaction.
- tsProxy.testIntTransaction(10, testIntTransactionCallback);
-
- // Call testStringTransaction.
- tsProxy.testStringTransaction("test", testIntTransactionCallback);
-}
-```
diff --git a/en/application-dev/Readme-EN.md b/en/application-dev/Readme-EN.md
index f3fa0e7ac0e9b829f2418e4b1bf96001e66553d2..dba77cf37aab62a7bb4d33b367839a0c0c88bc4e 100644
--- a/en/application-dev/Readme-EN.md
+++ b/en/application-dev/Readme-EN.md
@@ -8,14 +8,14 @@
- Quick Start
- Getting Started
- [Preparations](quick-start/start-overview.md)
- - [Getting Started with eTS in Stage Model](quick-start/start-with-ets-stage.md)
- - [Getting Started with eTS in FA Model](quick-start/start-with-ets-fa.md)
+ - [Getting Started with ArkTS in Stage Model](quick-start/start-with-ets-stage.md)
+ - [Getting Started with ArkTS in FA Model](quick-start/start-with-ets-fa.md)
- [Getting Started with JavaScript in FA Model](quick-start/start-with-js-fa.md)
- Development Fundamentals
- [Application Package Structure Configuration File (FA Model)](quick-start/package-structure.md)
- [Application Package Structure Configuration File (Stage Model)](quick-start/stage-structure.md)
- [SysCap](quick-start/syscap.md)
- - [HarmonyAppProvision Configuration File](quick-start/app-provision-structure.md)
+
- Development
- [Ability Development](ability/Readme-EN.md)
- [UI Development](ui/Readme-EN.md)
@@ -26,6 +26,7 @@
- [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md)
- [Data Management](database/Readme-EN.md)
+ - [File Management](file-management/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md)
diff --git a/en/application-dev/ability-deprecated/Readme-EN.md b/en/application-dev/ability-deprecated/Readme-EN.md
new file mode 100644
index 0000000000000000000000000000000000000000..5c803a47558bbd52765090debe162dbecd996ae6
--- /dev/null
+++ b/en/application-dev/ability-deprecated/Readme-EN.md
@@ -0,0 +1,25 @@
+# Ability Development
+
+> **NOTE**
+> This folder is deprecated. Read [Application Models](../application-models/Readme-EN.md) instead.
+
+- [Ability Framework Overview](ability-brief.md)
+- [Context Usage](context-userguide.md)
+- FA Model
+ - [FA Model Overview](fa-brief.md)
+ - [Page Ability Development](fa-pageability.md)
+ - [Service Ability Development](fa-serviceability.md)
+ - [Data Ability Development](fa-dataability.md)
+ - [FA Widget Development](fa-formability.md)
+- Stage Model
+ - [Stage Model Overview](stage-brief.md)
+ - [Ability Development](stage-ability.md)
+ - [Service Extension Ability Development](stage-serviceextension.md)
+ - [Ability Continuation Development](stage-ability-continuation.md)
+ - [Ability Call Development](stage-call.md)
+ - [Stage Widget Development](stage-formextension.md)
+- Other
+ - [WantAgent Development](wantagent.md)
+ - [Ability Assistant Usage](ability-assistant-guidelines.md)
+ - [ContinuationManager Development](continuationmanager.md)
+ - [Test Framework Usage](ability-delegator.md)
diff --git a/en/application-dev/ability-deprecated/ability-assistant-guidelines.md b/en/application-dev/ability-deprecated/ability-assistant-guidelines.md
new file mode 100644
index 0000000000000000000000000000000000000000..d2e45f5d5492c23bcce0ec48674427df2cb2b765
--- /dev/null
+++ b/en/application-dev/ability-deprecated/ability-assistant-guidelines.md
@@ -0,0 +1,107 @@
+# Ability Assistant Usage
+
+The ability assistant enables you to start applications, atomic services, and test cases and debug applications. By using this tool, you can send commands in the hdc shell to perform various system operations, such as starting abilities, forcibly stopping processes, and printing ability information.
+
+## Query-related Commands
+
+- **help**
+
+ Displays help information for the ability assistant.
+
+ **Return value**
+
+ Returns the help information.
+
+ **Method**
+
+ ```
+ aa help
+ ```
+
+## Ability-related Commands
+
+- **start**
+
+ Starts an ability.
+
+ | Name | Description |
+ | --------- | -------------------------- |
+ | -h/--help | Help information. |
+ | -d | Device ID. This parameter is optional. |
+ | -a | Ability name. This parameter is mandatory.|
+ | -b | Bundle name. This parameter is mandatory. |
+ | -D | Debugging mode. This parameter is optional. |
+
+ **Return value**
+
+ Returns "start ability successfully." if the ability is started; returns "error: failed to start ability." otherwise.
+
+ **Method**
+
+ ```
+ aa start [-d ] -a -b [-D]
+ ```
+
+- **stop-service**
+
+ Stops a Service ability.
+
+ | Name | Description |
+ | --------- | ------------------------ |
+ | -h/--help | Help information. |
+ | -d | Device ID. This parameter is optional. |
+ | -a | Ability name. This parameter is mandatory.|
+ | -b | Bundle name. This parameter is mandatory. |
+
+ **Return value**
+
+ Returns "stop service ability successfully." if the Service ability is stopped; returns "error: failed to stop service ability." otherwise.
+
+ **Method**
+
+ ```
+ aa stop-service [-d ] -a -b
+ ```
+
+- **dump**
+
+ Prints ability-related information.
+
+ | Name | Level-2 Parameter | Description |
+ | ----------------- | -------------------- | ------------------------------------------------------------ |
+ | -h/--help | - | Prints help information. |
+ | -a/--all | - | Prints ability information in all missions. |
+ | -l/--mission-list | type (All logs are printed if this parameter is left unspecified.)| Prints mission stack information. The following values are available for **type**: - NORMAL - DEFAULT_STANDARD - DEFAULT_SINGLE - LAUNCHER |
+ | -e/--extension | elementName | Prints extended component information. |
+ | -u/--userId | UserId | Prints stack information of a specified user ID. This parameter must be used together with other parameters. Example commands: aa **dump -a -u 100** and **aa dump -d -u 100**.|
+ | -d/--data | - | Prints Data ability information. |
+ | -i/--ability | AbilityRecord ID | Prints detailed information about a specified ability. |
+ | -c/--client | - | Prints detailed ability information. This parameter must be used together with other parameters. Example commands: **aa dump -a -c** and **aa dump -i 21 -c**.|
+
+ **Method**
+
+ ```
+ aa dump -a
+ ```
+ 
+ ```
+ aa dump -l
+ ```
+ 
+ ```
+ aa dump -i 12
+ ```
+ 
+- **force-stop**
+
+ Forcibly stops a process based on the bundle name.
+
+ **Return value**
+
+ Returns "force stop process successfully." if the process is forcibly stopped; returns "error: failed to force stop process." otherwise.
+
+ **Method**
+
+ ```
+ aa force-stop
+ ```
diff --git a/en/application-dev/ability-deprecated/ability-brief.md b/en/application-dev/ability-deprecated/ability-brief.md
new file mode 100644
index 0000000000000000000000000000000000000000..867e2c750a7d98b7964b037dcb809954fb5b40fb
--- /dev/null
+++ b/en/application-dev/ability-deprecated/ability-brief.md
@@ -0,0 +1,34 @@
+# Ability Framework Overview
+
+Ability is the basic abstraction of applications in OpenHarmony.
+
+Each ability is an application component that provides an independent service and is the minimum unit for the system to schedule an application. An application can contain one or more **Ability** instances.
+
+The ability framework model has two forms:
+
+- FA model, which is available for application development using API version 8 and earlier versions. In the FA model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility.
+- Stage model, which is introduced since API version 9. In the stage model, there are two classes: UIAbility and ExtensionAbility. ExtensionAbility is further extended to ServiceExtensionAbility, FormExtensionAbility, DataShareExtensionAbility, and more.
+
+Starting from API version 9, the stage model is recommended.
+
+The stage model is designed to make it easier to develop complex applications in the distributed environment. The table below lists the design differences between the two models.
+
+| Item | FA Model | Stage Model |
+| -------------- | ------------------------------------------------------------ | -------------------------------------------------------- |
+| Application component development mode | Web-like development | Object-oriented development |
+| Engine instance | Each **Ability** instance exclusively occupies a VM instance. | Multiple **Ability** instances share a VM instance. |
+| Intra-process object sharing| Not supported | Supported |
+| Bundle description file | The **config.json** file is used to describe the HAP and component information. Each component must use a fixed file name.| The **module.json5** file is used to describe the HAP and component information. The entry file name can be specified.|
+| Component | Four types of components are provided: PageAbility (used for UI page display), ServiceAbility (used to provide services), DataAbility (used for data sharing), and FormAbility (used to provide widgets).| Two types of components are provided: UIAbility (used for UI page display) and ExtensionAbility (scenario-based service extension). |
+
+In addition, the following differences exist in the development process:
+
+* Different ability types
+
+ 
+
+* Different ability lifecycles
+
+ 
+
+For details about the two models, see [FA Model Overview](fa-brief.md) and [Stage Model Overview](stage-brief.md).
diff --git a/en/application-dev/ability-deprecated/ability-delegator.md b/en/application-dev/ability-deprecated/ability-delegator.md
new file mode 100644
index 0000000000000000000000000000000000000000..b32d472176a5b6270fece94ae4bd8ae9a7bd73fa
--- /dev/null
+++ b/en/application-dev/ability-deprecated/ability-delegator.md
@@ -0,0 +1,181 @@
+# Test Framework Usage
+
+## Overview
+The delegator test framework provides a self-test environment for OpenHarmony applications. Using this framework, you can start an ability, schedule its lifecycle, listen for its state changes, run a shell command, and print the test result.
+
+## Constraints
+
+The APIs provided by the test framework can be used only in the test HAP. They take effect only after the test framework is started.
+
+
+## Starting the Test Framework
+
+The test framework can be started in either of the following ways:
+
+- Method 1: Run the `aa test` command.
+- Method 2: Use DevEco Studio.
+
+### Running aa test
+
+To start the test framework, specify the **TestRunner** and the package name or module name of the HAP where the **TestRunner** is located.
+
+An example command in the FA model is as follows:
+
+```javascript
+aa test -b BundleName -p com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
+```
+
+An example command in the stage model is as follows:
+```javascript
+aa test -b BundleName -m com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
+```
+| Parameter | Mandatory| Description |
+| --------------- | -------- | ------------------------------------------------------------ |
+| -b | Yes | Bundle name of the HAP where the **TestRunner** is located. |
+| -p | Yes | Package name of the HAP where the **TestRunner** is located. This parameter is used by the FA model. |
+| -m | Yes | Module name of the HAP where the **TestRunner** is located. This parameter is used by the stage model. |
+| -s unittest | Yes | Name of the **TestRunner** to be used. The TestRunner name must be the same as the file name. |
+| -w | No | Timeout interval of a test case, in seconds. If this parameter is not specified or is set to a value less than or equal to **0**, the test framework exits only after **finishTest** is invoked.|
+| -s \\ | No | **-s** can be followed by any key-value pair obtained through **AbilityDelegatorArgs.parameters**. For example, in **-s classname myTest**, **-s classname** is the key and **myTest** is the value.|
+| -D | No | Debug mode for starting the tested application.|
+| -h | No | Help information.|
+
+### Using DevEco Studio
+
+For details about how to use DevEco Studio to start the test framework, see [OpenHarmony Test Framework](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453#section1034420367508).
+
+## Introduction to TestRunner
+
+**TestRunner** is the entry class of the test framework test process. When the test process is started, the system calls related APIs in **TestRunner**. You need to inherit this class and override the **onPrepare** and **onRun** APIs. When creating an application template, DevEco Studio initializes the default **TestRunner** and starts the default **TestAbility** in the **onRun** API. You can modify the test code of **TestAbility** or override **onPrepare** and **onRun** in **TestRunner** to implement your own test code. For details, see [TestRunner](../reference/apis/js-apis-application-testRunner.md).
+
+## Introduction to AbilityDelegatorRegistry
+
+**AbilityDelegatorRegistry** is the **AbilityDelegator** repository class provided by the test framework. You can use **AbilityDelegatorRegistry** to obtain an **AbilityDelegator** instance and the input and generated parameters **AbilityDelegatorArgs** during the test. You can use **AbilityDelegator** to invoke the function set provided by the test framework for testing and verification. For details, see [AbilityDelegatorRegistry](../reference/apis/js-apis-application-abilityDelegatorRegistry.md).
+
+## Introduction to AbilityDelegatorArgs
+
+**AbilityDelegatorArgs** is a test parameter class provided by the test framework. You can use **AbilityDelegatorArgs** to obtain the parameters passed and generated during the test. For details, see [AbilityDelegatorArgs](../reference/apis/js-apis-inner-application-abilityDelegatorArgs.md).
+
+## Introduction to AbilityMonitor
+
+**AbilityMonitor** is provided by the test framework for binding to and listening for abilities. You can use **AbilityMonitor** to bind to an **Ability** instance and add **AbilityMonitor** to the listening list. When **AbilityMonitor** is bound to an ability, the creation and lifecycle changes of the ability will trigger the related callback in **AbilityMonitor**. You can test and verify the ability in these callbacks. For details, see [AbilityMonitor](../reference/apis/js-apis-inner-application-abilityMonitor.md).
+
+**Example**
+
+```javascript
+import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
+
+function onAbilityCreateCallback(data) {
+ console.info("onAbilityCreateCallback");
+}
+
+var monitor = {
+ abilityName: "abilityname",
+ onAbilityCreate: onAbilityCreateCallback
+}
+
+var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+abilityDelegator.addAbilityMonitor(monitor).then(() => {
+ console.info("addAbilityMonitor promise");
+});
+```
+
+## Introduction to AbilityDelegator
+
+**AbilityDelegator** is a main function class of the test framework. It provides the functions of starting an ability, obtaining an **Ability** instance, scheduling the ability lifecycle, listening for the ability state, and printing test results.
+
+**Modules to Import**
+
+```javascript
+import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
+```
+
+```javascript
+var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+```
+
+### Starting an Ability and Listening for the Ability State
+
+Use **AbilityDelegator** and **AbilityMonitor** to start an ability, obtain an **Ability** instance, and listen for the ability state.
+
+**Example**
+
+```javascript
+var abilityDelegator;
+var ability;
+var timeout = 100;
+
+function onAbilityCreateCallback(data) {
+ console.info("onAbilityCreateCallback");
+}
+
+var monitor = {
+ abilityName: "abilityname",
+ onAbilityCreate: onAbilityCreateCallback
+}
+
+abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+abilityDelegator.waitAbilityMonitor(monitor, timeout, (err, data) => {
+ ability = data;
+ console.info("waitAbilityMonitor callback");
+});
+
+var want = {
+ bundleName: "bundleName",
+ abilityName: "abilityName"
+};
+abilityDelegator.startAbility(want, (err, data) => {
+ console.info("startAbility callback");
+});
+```
+
+### Scheduling the Ability Lifecycle
+
+**AbilityDelegator** provides APIs to display and schedule the ability lifecycle and supports the foreground and background. It works with **AbilityMonitor** to listen for the ability lifecycle. For details, see [AbilityDelegator](../reference/apis/js-apis-inner-application-abilityDelegator.md).
+
+### Running a Shell Command
+
+**AbilityDelegator** provides APIs to run shell commands in the test environment.
+
+**Example**
+
+```javascript
+var abilityDelegator;
+var cmd = "cmd";
+abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+abilityDelegator.executeShellCommand(cmd, (err, data) => {
+ console.info("executeShellCommand callback");
+});
+```
+
+### Printing Log Information
+
+**AbilityDelegator** provides APIs for printing log information. You can call any API in the test code to print process logs to the unit test console.
+
+**Example**
+
+```javascript
+var abilityDelegator;
+var msg = "msg";
+
+abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+abilityDelegator.print(msg, (err) => {
+ console.info("print callback");
+});
+```
+
+### Finishing the Test and Printing Log Information
+
+**AbilityDelegator** provides the APIs for actively finishing the test. You can call any API in test code to finish the test and print logs to the unit test console.
+
+**Example**
+
+```javascript
+var abilityDelegator;
+var msg = "msg";
+
+abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+abilityDelegator.finishTest(msg, 0, (err) => {
+ console.info("finishTest callback");
+});
+```
diff --git a/en/application-dev/ability-deprecated/context-userguide.md b/en/application-dev/ability-deprecated/context-userguide.md
new file mode 100644
index 0000000000000000000000000000000000000000..ac65d92cb9422d040ff16cab1640cd1f9bed5d5c
--- /dev/null
+++ b/en/application-dev/ability-deprecated/context-userguide.md
@@ -0,0 +1,318 @@
+# Context Usage
+
+## Context Overview
+
+**Context** provides the capability of obtaining contextual information of an application.
+
+ The OpenHarmony application framework has two models: Feature Ability (FA) model and stage model. Correspondingly, there are two sets of context mechanisms. **application/BaseContext** is a common context base class. It uses the **stageMode** attribute to specify whether the context is used for the stage model.
+
+- FA model
+
+Only the methods in **app/Context** can be used for the context in the FA model. Both the application-level context and ability-level context are instances of this type. If an ability-level method is invoked in the application-level context, an error occurs. Therefore, you must pay attention to the actual meaning of the **Context** instance.
+
+- Stage model
+
+ The stage model has the following types of contexts: **application/Context**, **application/ApplicationContext**, **application/AbilityStageContext**, **application/ExtensionContext**, **application/AbilityContext**, and **application/FormExtensionContext**. For details about these contexts and how to use them, see [Context in the Stage Model](#context-in-the-stage-model).
+
+
+
+## Context in the FA Model
+
+Only the methods in **app/Context** can be used for the context in the FA model.
+
+The FA model has only one context definition. All capabilities in the context are provided through methods. The context uses these methods to extend the capabilities of the FA.
+
+**d.ts statement**
+
+https://gitee.com/openharmony/interface_sdk-js/blob/master/api/app/context.d.ts
+
+**Example**
+
+```javascript
+import featureAbility from '@ohos.ability.featureAbility'
+export default {
+ onCreate() {
+ // Obtain the context and call related APIs.
+ let context = featureAbility.getContext();
+ context.getBundleName((data, bundleName)=>{
+ console.info("ability bundleName:" + bundleName)
+ });
+ console.info('Application onCreate')
+ },
+ onDestroy() {
+ console.info('Application onDestroy')
+ },
+}
+```
+
+### Common Context-related Methods in the FA Model
+The following context-related methods are available in the FA model:
+```javascript
+setDisplayOrientation(orientation: bundle.DisplayOrientation, callback: AsyncCallback): void
+setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise;
+```
+The methods are used to set the display orientation of the current ability.
+
+**Example**
+```javascript
+import featureAbility from '@ohos.ability.featureAbility'
+import bundle from '@ohos.bundle';
+
+export default {
+ onCreate() {
+ // Obtain the context and call related APIs.
+ let context = featureAbility.getContext();
+ context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => {
+ console.log("Set display orientation.")
+ })
+ console.info('Application onCreate')
+ },
+ onDestroy() {
+ console.info('Application onDestroy')
+ },
+}
+```
+
+## Context in the Stage Model
+
+The following describes the contexts provided by the stage model in detail.
+
+### application/Context
+
+**application/Context** is the base class context. It provides basic application information, such as **resourceManager**, **applicationInfo**, **cacheDir**, and **area**. It also provides basic application methods such as **createModuleContext**.
+
+**d.ts statement**
+
+https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/Context.d.ts
+
+### application/ApplicationContext
+
+**application/ApplicationContext** is an application-level context. In addition to the capabilities provided by the base class context, the application-level context provides **registerAbilityLifecycleCallback** and **unregisterAbilityLifecycleCallback** to monitor the ability lifecycle in a process.
+
+**How to Obtain**
+
+Obtain the context by calling **context.getApplicationContext()** in **Ability**.
+
+**Example**
+
+```javascript
+import Ability from "@ohos.application.Ability";
+
+var lifecycleid;
+
+export default class MainAbility extends Ability {
+ onCreate() {
+ console.log("MainAbility onCreate")
+ let AbilityLifecycleCallback = {
+ onAbilityCreate(ability){
+ console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability));
+ },
+ onWindowStageCreate(ability, windowStage){
+ console.log("AbilityLifecycleCallback onWindowStageCreate ability:" + JSON.stringify(ability));
+ console.log("AbilityLifecycleCallback onWindowStageCreate windowStage:" + JSON.stringify(windowStage));
+ },
+ onWindowStageActive(ability, windowStage){
+ console.log("AbilityLifecycleCallback onWindowStageActive ability:" + JSON.stringify(ability));
+ console.log("AbilityLifecycleCallback onWindowStageActive windowStage:" + JSON.stringify(windowStage));
+ },
+ onWindowStageInactive(ability, windowStage){
+ console.log("AbilityLifecycleCallback onWindowStageInactive ability:" + JSON.stringify(ability));
+ console.log("AbilityLifecycleCallback onWindowStageInactive windowStage:" + JSON.stringify(windowStage));
+ },
+ onWindowStageDestroy(ability, windowStage){
+ console.log("AbilityLifecycleCallback onWindowStageDestroy ability:" + JSON.stringify(ability));
+ console.log("AbilityLifecycleCallback onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));
+ },
+ onAbilityDestroy(ability){
+ console.log("AbilityLifecycleCallback onAbilityDestroy ability:" + JSON.stringify(ability));
+ },
+ onAbilityForeground(ability){
+ console.log("AbilityLifecycleCallback onAbilityForeground ability:" + JSON.stringify(ability));
+ },
+ onAbilityBackground(ability){
+ console.log("AbilityLifecycleCallback onAbilityBackground ability:" + JSON.stringify(ability));
+ },
+ onAbilityContinue(ability){
+ console.log("AbilityLifecycleCallback onAbilityContinue ability:" + JSON.stringify(ability));
+ }
+ }
+ // 1. Obtain applicationContext through the context attribute.
+ let applicationContext = this.context.getApplicationContext();
+ // 2. Use applicationContext to register and listen for the ability lifecycle in the application.
+ lifecycleid = applicationContext.registerAbilityLifecycleCallback(AbilityLifecycleCallback);
+ console.log("registerAbilityLifecycleCallback number: " + JSON.stringify(lifecycleid));
+ },
+ onDestroy() {
+ let applicationContext = this.context.getApplicationContext();
+ applicationContext.unregisterAbilityLifecycleCallback(lifecycleid, (error, data) => {
+ console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error));
+ });
+ }
+}
+```
+
+**d.ts statement**
+
+https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ApplicationContext.d.ts
+
+### application/AbilityStageContext
+
+**application/AbilityStageContext** is the context for the HAP file. In addition to those provided by the base class **application/Context**, this context contains **HapModuleInfo** and **Configuration**.
+
+**How to Obtain**
+
+Obtain the context from the **context** attribute in **AbilityStage**.
+
+**Example**
+
+```javascript
+export default class MyAbilityStage extends AbilityStage {
+ onCreate() {
+ // The context attribute is of the AbilityStageContext type.
+ console.log('HapModuleInfo is ' + this.context.currentHapModuleInfo);
+ }
+}
+```
+
+**d.ts statement**
+
+https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityStageContext.d.ts
+
+### application/AbilityContext
+
+In the stage model, each ability has a context attribute.
+
+**Ability** provides methods to manage the ability lifecycle, and **AbilityContext** provides methods to operate abilities (such as **startAbility** and **connectAbility**).
+
+**How to Obtain**
+
+Obtain the context from the **context** attribute in **Ability**.
+
+**Example**
+
+```javascript
+import Ability from '@ohos.application.Ability'
+
+export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log("[Demo] MainAbility onCreate")
+ globalThis.abilityWant = want;
+ }
+
+ onDestroy() {
+ console.log("[Demo] MainAbility onDestroy")
+ }
+
+ onWindowStageCreate(windowStage) {
+ // Set the main page for this ability when the main window is created.
+ console.log("[Demo] MainAbility onWindowStageCreate")
+
+ // Obtain AbilityContext and print the ability information.
+ let context = this.context;
+ console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName)
+
+ windowStage.loadContent("pages/index", (err, data) => {
+ if (err.code) {
+ console.error('Failed to load the content. Cause:' + JSON.stringify(err));
+ return;
+ }
+ console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data))
+ });
+ }
+
+ onWindowStageDestroy() {
+ // Release the UI related resources when the main window is destroyed.
+ console.log("[Demo] MainAbility onWindowStageDestroy")
+ }
+
+ onForeground() {
+ // The ability is switched to run in the foreground.
+ console.log("[Demo] MainAbility onForeground")
+ }
+
+ onBackground() {
+ // The ability is switched to run in the background.
+ console.log("[Demo] MainAbility onBackground")
+ }
+};
+```
+
+### application/FormExtensionContext
+
+For details, see [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md).
+
+### Obtaining the Context on an ArkTS Page
+
+In the stage model, in the onWindowStageCreate lifecycle of an ability, you can call **SetUIContent** of **WindowStage** to load an ArkTS page. In some scenarios, you need to obtain the context on the page to call related APIs.
+
+**How to Obtain**
+
+Use the API described in the table below to obtain the context associated with an ArkTS page.
+
+| API | Description |
+| :------------------------------------ | :--------------------------- |
+| getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.|
+
+**Example**
+
+```ts
+// MainAbility.ts
+import Ability from '@ohos.application.Ability'
+
+export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log("[Demo] MainAbility onCreate")
+ }
+
+ onDestroy() {
+ console.log("[Demo] MainAbility onDestroy")
+ }
+
+ onWindowStageCreate(windowStage) {
+ // Load the index page and pass the current Context object.
+ windowStage.setUIContent(this.context, "pages/index", null)
+ }
+
+ onWindowStageDestroy() {}
+
+ onForeground() {}
+
+ onBackground() {}
+};
+```
+
+```ts
+// pages/index.ets
+import context from '@ohos.application.context'
+
+type Context = context.Context
+
+@Entry
+@Component
+struct Index {
+ build() {
+ Row() {
+ Column() {
+ Text('GetContext')
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ .onClick(() => {
+ // Obtain the Context object associated with the current component.
+ var context : Context = getContext(this) as Context
+ console.info("CacheDir:" + context.cacheDir)
+ })
+ }
+ .width('100%')
+ }
+ .height('100%')
+ }
+}
+```
+
+## Common Incorrect Usage
+
+**Error 1: Use globalThis to obtain the context in the stage model.**
+
+**Reason**
+
+In the FA model, each ability instance has a JS VM instance. Therefore, a global ability instance can be obtained from the **global** object of the JS engine. In the stage model, where all the processes of an application share a JS VM instance, there is no global ability instance, and using **globalThis** may cause an error or crash.
diff --git a/en/application-dev/ability-deprecated/continuationmanager.md b/en/application-dev/ability-deprecated/continuationmanager.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ba79f95acf165d604d8f854832703d7fc4af3f8
--- /dev/null
+++ b/en/application-dev/ability-deprecated/continuationmanager.md
@@ -0,0 +1,277 @@
+# ContinuationManager Development
+
+> **NOTE**
+>
+> Currently, the **ContinuationManager** module is not available for application development. Its APIs are mainly used to start the device selection module.
+
+## When to Use
+Users are using two or more devices to experience an all-scenario, multi-device lifestyle. Each type of device has its unique advantages and disadvantages specific to scenarios. The ability continuation capability breaks boundaries of devices and enables multi-device collaboration, achieving precise control, universal coordination, and seamless hops of user applications.
+
+As the entry of the ability continuation capability, **continuationManager** is used to start the device selection module for the user to select the target device. After a device is selected, information about the selected device is returned to the user. The user can then initiate cross-device continuation or collaboration based on the device information.
+
+
+
+## Available APIs
+| API | Description|
+| ---------------------------------------------------------------------------------------------- | ----------- |
+| registerContinuation(callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API does not involve any filter parameters and uses an asynchronous callback to return the result.|
+| registerContinuation(options: ContinuationExtraParams, callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API uses an asynchronous callback to return the result.|
+| registerContinuation(options?: ContinuationExtraParams): Promise\ | Registers the continuation management service and obtains a token. This API uses a promise to return the result.|
+| on(type: "deviceSelected", token: number, callback: Callback\>): void | Subscribes to device connection events. This API uses an asynchronous callback to return the result.|
+| on(type: "deviceUnselected", token: number, callback: Callback\>): void | Subscribes to device disconnection events. This API uses an asynchronous callback to return the result.|
+| off(type: "deviceSelected", token: number): void | Unsubscribes from device connection events.|
+| off(type: "deviceUnselected", token: number): void | Unsubscribes from device disconnection events.|
+| startContinuationDeviceManager(token: number, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API does not involve any filter parameters and uses an asynchronous callback to return the result.|
+| startContinuationDeviceManager(token: number, options: ContinuationExtraParams, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API uses an asynchronous callback to return the result.|
+| startContinuationDeviceManager(token: number, options?: ContinuationExtraParams): Promise\ | Starts the device selection module to show the list of available devices. This API uses a promise to return the result.|
+| updateContinuationState(token: number, deviceId: string, status: DeviceConnectState, callback: AsyncCallback\): void | Instructs the device selection module to update the device connection state. This API uses an asynchronous callback to return the result.|
+| updateContinuationState(token: number, deviceId: string, status: DeviceConnectState): Promise\ | Instructs the device selection module to update the device connection state. This API uses a promise to return the result.|
+| unregisterContinuation(token: number, callback: AsyncCallback\): void | Deregisters the continuation management service. This API uses an asynchronous callback to return the result.|
+| unregisterContinuation(token: number): Promise\ | Deregisters the continuation management service. This API uses a promise to return the result.|
+
+## How to Develop
+1. Import the **continuationManager** module.
+
+ ```ts
+ import continuationManager from '@ohos.continuation.continuationManager';
+ ```
+
+2. Apply for the **DISTRIBUTED_DATASYNC** permission.
+
+ The permission application operation varies according to the ability model in use. In the FA mode, add the required permission in the `config.json` file, as follows:
+
+ ```json
+ {
+ "module": {
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
+ }
+ ]
+ }
+ }
+ ```
+
+ This permission must also be granted by the user through a dialog box when the application is started for the first time. The sample code is as follows:
+
+ ```ts
+ import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
+ import bundle from '@ohos.bundle';
+ import featureAbility from '@ohos.ability.featureAbility';
+
+ async function requestPermission() {
+ let permissions: Array = [
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+ ];
+ let needGrantPermission: boolean = false;
+ let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
+ let applicationInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', 0, 100);
+ for (let i = 0; i < permissions.length; i++) {
+ let result = await atManager.verifyAccessToken(applicationInfo.accessTokenId, permissions[i]);
+ // Check whether the permission is granted.
+ if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
+ needGrantPermission = true;
+ break;
+ }
+ }
+ // If the permission is not granted, call requestPermissionsFromUser to apply for the permission.
+ if (needGrantPermission) {
+ await featureAbility.getContext().requestPermissionsFromUser(permissions, 1);
+ } else {
+ console.info('app permission already granted');
+ }
+ }
+ ```
+
+ In the stage model, add the required permission in the `module.json5` file. The sample code is as follows:
+
+ ```json
+ {
+ "module": {
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
+ }
+ ]
+ }
+ }
+ ```
+
+ ```ts
+ import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
+ import bundle from '@ohos.bundle';
+
+ async function requestPermission() {
+ let permissions: Array = [
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+ ];
+ let needGrantPermission: boolean = false;
+ let atManger: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
+ let applicationInfo = await bundle.getApplicationInfo('ohos.samples.continuationmanager', 0, 100);
+ for (const permission of permissions) {
+ try {
+ let grantStatus = await atManger.verifyAccessToken(applicationInfo.accessTokenId, permission);
+ // Check whether the permission is granted.
+ if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
+ needGrantPermission = true;
+ break;
+ }
+ } catch (err) {
+ console.error('app permission query grant status error' + JSON.stringify(err));
+ needGrantPermission = true;
+ break;
+ }
+ }
+ // If the permission is not granted, call requestPermissionsFromUser to apply for the permission.
+ if (needGrantPermission) {
+ try {
+ // globalThis.context is Ability.context, which must be assigned a value in the MainAbility.ts file in advance.
+ await globalThis.context.requestPermissionsFromUser(permissions);
+ } catch (err) {
+ console.error('app permission request permissions error' + JSON.stringify(err));
+ }
+ } else {
+ console.info('app permission already granted');
+ }
+ }
+ ```
+
+3. Register the continuation management service and obtain a token.
+
+ The sample code is as follows:
+
+ ```ts
+ let token: number = -1; // Used to save the token returned after the registration. The token will be used when listening for device connection/disconnection events, starting the device selection module, and updating the device connection state.
+ try {
+ continuationManager.registerContinuation().then((data) => {
+ console.info('registerContinuation finished, ' + JSON.stringify(data));
+ token = data; // Obtain a token and assign a value to the token variable.
+ }).catch((err) => {
+ console.error('registerContinuation failed, cause: ' + JSON.stringify(err));
+ });
+ } catch (err) {
+ console.error('registerContinuation failed, cause: ' + JSON.stringify(err));
+ }
+ ```
+
+4. Listen for the device connection/disconnection state.
+
+ The sample code is as follows:
+
+ ```ts
+ let remoteDeviceId: string = ""; // Used to save the information about the remote device selected by the user, which will be used for cross-device continuation or collaboration.
+
+ try {
+ // The token parameter is the token obtained during the registration.
+ continuationManager.on("deviceSelected", token, (continuationResults) => {
+ console.info('registerDeviceSelectedCallback len: ' + continuationResults.length);
+ if (continuationResults.length <= 0) {
+ console.info('no selected device');
+ return;
+ }
+ remoteDeviceId = continuationResults[0].id; // Assign the deviceId of the first selected remote device to the remoteDeviceId variable.
+
+ // Pass the remoteDeviceId parameter to want.
+ let want = {
+ deviceId: remoteDeviceId,
+ bundleName: 'ohos.samples.continuationmanager',
+ abilityName: 'MainAbility'
+ };
+ globalThis.abilityContext.startAbility(want).then((data) => {
+ console.info('StartRemoteAbility finished, ' + JSON.stringify(data));
+ }).catch((err) => {
+ console.error('StartRemoteAbility failed, cause: ' + JSON.stringify(err));
+ });
+ });
+ } catch (err) {
+ console.error('on failed, cause: ' + JSON.stringify(err));
+ }
+ ```
+
+ The preceding multi-device collaboration operation is performed across devices in the stage model. For details about this operation in the FA model, see [Page Ability Development](fa-pageability.md).
+
+ You can also instruct the device selection module to update the device connection state. The sample code is as follows:
+
+ ```ts
+ // Set the device connection state.
+ let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.CONNECTED;
+
+ // The token parameter is the token obtained during the registration, and the remoteDeviceId parameter is the remoteDeviceId obtained.
+ try {
+ continuationManager.updateContinuationState(token, remoteDeviceId, deviceConnectStatus).then((data) => {
+ console.info('updateContinuationState finished, ' + JSON.stringify(data));
+ }).catch((err) => {
+ console.error('updateContinuationState failed, cause: ' + JSON.stringify(err));
+ });
+ } catch (err) {
+ console.error('updateContinuationState failed, cause: ' + JSON.stringify(err));
+ }
+ ```
+
+ Listen for the device disconnection state so that the user can stop cross-device continuation or collaboration in time. The sample code is as follows:
+
+ ```ts
+ try {
+ // The token parameter is the token obtained during the registration.
+ continuationManager.on("deviceUnselected", token, (continuationResults) => {
+ console.info('onDeviceUnselected len: ' + continuationResults.length);
+ if (continuationResults.length <= 0) {
+ console.info('no unselected device');
+ return;
+ }
+
+ // Update the device connection state.
+ let unselectedDeviceId: string = continuationResults[0].id; // Assign the deviceId of the first deselected remote device to the unselectedDeviceId variable.
+ let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.DISCONNECTING; // Device disconnected.
+
+ // The token parameter is the token obtained during the registration, and the unselectedDeviceId parameter is the unselectedDeviceId obtained.
+ continuationManager.updateContinuationState(token, unselectedDeviceId, deviceConnectStatus).then((data) => {
+ console.info('updateContinuationState finished, ' + JSON.stringify(data));
+ }).catch((err) => {
+ console.error('updateContinuationState failed, cause: ' + JSON.stringify(err));
+ });
+ });
+ } catch (err) {
+ console.error('updateContinuationState failed, cause: ' + JSON.stringify(err));
+ }
+ ```
+
+5. Start the device selection module to show the list of available devices on the network.
+
+ The sample code is as follows:
+
+ ```ts
+ // Filter parameters.
+ let continuationExtraParams = {
+ deviceType: ["00E"], // Device type.
+ continuationMode: continuationManager.ContinuationMode.COLLABORATION_SINGLE // Single-choice mode of the device selection module.
+ };
+
+ try {
+ // The token parameter is the token obtained during the registration.
+ continuationManager.startContinuationDeviceManager(token, continuationExtraParams).then((data) => {
+ console.info('startContinuationDeviceManager finished, ' + JSON.stringify(data));
+ }).catch((err) => {
+ console.error('startContinuationDeviceManager failed, cause: ' + JSON.stringify(err));
+ });
+ } catch (err) {
+ console.error('startContinuationDeviceManager failed, cause: ' + JSON.stringify(err));
+ }
+ ```
+
+6. If you do not need to perform cross-device migration or collaboration operations, you can deregister the continuation management service, by passing the token obtained during the registration.
+
+ The sample code is as follows:
+
+ ```ts
+ try {
+ // The token parameter is the token obtained during the registration.
+ continuationManager.unregisterContinuation(token).then((data) => {
+ console.info('unregisterContinuation finished, ' + JSON.stringify(data));
+ }).catch((err) => {
+ console.error('unregisterContinuation failed, cause: ' + JSON.stringify(err));
+ });
+ } catch (err) {
+ console.error('unregisterContinuation failed, cause: ' + JSON.stringify(err));
+ }
+ ```
diff --git a/en/application-dev/ability-deprecated/fa-brief.md b/en/application-dev/ability-deprecated/fa-brief.md
new file mode 100644
index 0000000000000000000000000000000000000000..5ad79cfe259f1fb9cf865b9d6f496c0f31c47ae0
--- /dev/null
+++ b/en/application-dev/ability-deprecated/fa-brief.md
@@ -0,0 +1,43 @@
+# FA Model Overview
+
+## Overall Architecture
+
+Ability is the entry for application development in OpenHarmony.
+
+The core of ability development is the processing on ability lifecycle callbacks.
+
+The Feature Ability (FA) model can be used only for application development using API version 8 and earlier versions. In this model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility.
+- PageAbility implements the ArkUI and provides the capability for interacting with users.
+- ServiceAbility does not have a UI. It runs in the background and provides custom services for other abilities to invoke.
+- DataAbility does not have a UI. It runs in the background and enables other abilities to insert, delete, and query data.
+- FormAbility is used to implement widgets, a new UI display form available on OpenHarmony devices.
+
+> Note: Starting from API version 9, the stage model is recommended for application development.
+
+## Lifecycle
+
+Among all abilities, PageAbility has the most complex lifecycle, because it has a UI and acts as a touchpoint for interacting with users.
+**The following figure shows the lifecycle of PageAbility.**
+
+
+
+The other abilities do not involve foreground and background switch or the **onShow** and **onHide** callbacks.
+You can override the lifecycle callbacks in **app.js** or **app.ets** to process application logic.
+
+The **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the callbacks covering the entire lifecycle.
+
+## Process and Thread Model
+
+Each application runs in a process. In the FA model, each ability runs in an independent VM.
+
+When an ability is started, an application process as well as a thread for this ability is created. For an application that has multiple abilities, each ability runs in an independent thread. In the FA model, each ability is bound to an independent VM instance. In this way, abilities are isolated from each other.
+
+
+
+## Application Package Structure
+
+For details about the project directory structure of the FA model, see [OpenHarmony Project Overview](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-project-overview-0000001218440650#section4154183910141).
+
+For details about how to configure the application package structure of the FA model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-fa.md).
+
+
\ No newline at end of file
diff --git a/en/application-dev/ability-deprecated/fa-dataability.md b/en/application-dev/ability-deprecated/fa-dataability.md
new file mode 100644
index 0000000000000000000000000000000000000000..8d94e8f225a3966d676e6c7631968c25f5634531
--- /dev/null
+++ b/en/application-dev/ability-deprecated/fa-dataability.md
@@ -0,0 +1,310 @@
+# Data Ability Development
+
+## When to Use
+
+A Data ability helps applications manage access to data stored by themselves and other applications. It also provides APIs for sharing data with other applications either on the same device or across devices.
+
+Data ability providers can customize data access-related APIs such as data inserting, deleting, updating, and querying, as well as file opening, and share data with other applications through these open APIs.
+
+## URI Introduction
+
+A Uniform Resource Identifier (URI) is used to identify a specific data item, such as a table in the database or a file on the disk. URIs used in OpenHarmony comply with the commonly used URI standard. A URI consists of the components:
+
+
+
+- **scheme**: name of the scheme used by the Data ability. The value is fixed at **dataability**.
+- **authority**: device ID. To access data on a remote device, set this component to the ID of the remote device. To access data on the local device, leave this component empty.
+- **path**: location of the specific resource to access.
+- **query**: query parameters.
+- **fragment**: subordinate resources to access.
+
+Example URIs:
+
+- Cross-device communication: **dataability://***device_id***/***com.domainname.dataability.persondata***/***person***/***10*
+- Local-device communication: **dataability:///***com.domainname.dataability.persondata***/***person***/***10*
+
+> **NOTE**
+>
+> In the case of local-device communication, **device_id** is empty, and therefore, there are three slashes (/) after **dataability:**.
+
+## Available APIs
+
+**Table 1** Data ability lifecycle APIs
+|API|Description|
+|:------|:------|
+|onInitialized(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).|
+|update(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Updates data in the database.|
+|query(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Queries data in the database.|
+|delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Deletes one or more data records from the database.|
+|normalizeUri(uri: string, callback: AsyncCallback\): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.|
+|batchInsert(uri: string, valueBuckets: Array\, callback: AsyncCallback\): void|Inserts multiple data records into the database.|
+|denormalizeUri(uri: string, callback: AsyncCallback\): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.|
+|insert(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\): void|Inserts a data record into the database.|
+|openFile(uri: string, mode: string, callback: AsyncCallback\): void|Opens a file.|
+|getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback\>): void|Obtains the MIME type of a file.|
+|getType(uri: string, callback: AsyncCallback\): void|Obtains the MIME type matching the data specified by the URI.|
+|executeBatch(ops: Array\, callback: AsyncCallback\>): void|Operates data in the database in batches.|
+|call(method: string, arg: string, extras: PacMap, callback: AsyncCallback\): void|Calls a custom API.|
+
+
+## How to Develop
+### Creating a Data Ability
+
+1. To meet the basic requirements of the database storage service, implement the **Insert**, **Query**, **Update**, and **Delete** APIs in the **Data** class. The **BatchInsert** and **ExecuteBatch** APIs have already implemented the traversal logic, but not batch data processing.
+
+ The following code snippet shows how to create a Data ability:
+
+ ```javascript
+ import featureAbility from '@ohos.ability.featureAbility'
+ import dataAbility from '@ohos.data.dataAbility'
+ import dataRdb from '@ohos.data.rdb'
+
+ const TABLE_NAME = 'book'
+ const STORE_CONFIG = { name: 'book.db' }
+ const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)'
+ let rdbStore: dataRdb.RdbStore = undefined
+
+ export default {
+ onInitialized(abilityInfo) {
+ console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName)
+ let context = featureAbility.getContext()
+ dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => {
+ console.info('DataAbility getRdbStore callback')
+ store.executeSql(SQL_CREATE_TABLE, [])
+ rdbStore = store
+ });
+ },
+ insert(uri, valueBucket, callback) {
+ console.info('DataAbility insert start')
+ rdbStore.insert(TABLE_NAME, valueBucket, callback)
+ },
+ batchInsert(uri, valueBuckets, callback) {
+ console.info('DataAbility batch insert start')
+ for (let i = 0;i < valueBuckets.length; i++) {
+ console.info('DataAbility batch insert i=' + i)
+ if (i < valueBuckets.length - 1) {
+ rdbStore.insert(TABLE_NAME, valueBuckets[i], (err: any, num: number) => {
+ console.info('DataAbility batch insert ret=' + num)
+ })
+ } else {
+ rdbStore.insert(TABLE_NAME, valueBuckets[i], callback)
+ }
+ }
+ },
+ query(uri, columns, predicates, callback) {
+ console.info('DataAbility query start')
+ let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
+ rdbStore.query(rdbPredicates, columns, callback)
+ },
+ update(uri, valueBucket, predicates, callback) {
+ console.info('DataAbilityupdate start')
+ let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
+ rdbStore.update(valueBucket, rdbPredicates, callback)
+ },
+ delete(uri, predicates, callback) {
+ console.info('DataAbilitydelete start')
+ let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
+ rdbStore.delete(rdbPredicates, callback)
+ }
+ };
+ ```
+
+2. Configure the submodule.
+
+ | JSON Field| Description |
+ | ------------ | ------------------------------------------------------------ |
+ | "name" | Ability name, corresponding to the **Data** class name derived from **Ability**. |
+ | "type" | Ability type, which is **Data** for a Data ability. |
+ | "uri" | URI used for communication. |
+ | "visible" | Whether the Data ability is visible to other applications. When this parameter is set to **true**, the Data ability can communicate with other applications.|
+
+ **config.json configuration example**
+
+ ```json
+ "abilities":[{
+ "srcPath": "DataAbility",
+ "name": ".DataAbility",
+ "icon": "$media:icon",
+ "srcLanguage": "ets",
+ "description": "$string:description_dataability",
+ "type": "data",
+ "visible": true,
+ "uri": "dataability://ohos.samples.etsdataability.DataAbility"
+ }]
+ ```
+
+### Accessing a Data ability
+#### Development Preparations
+
+Import the basic dependency packages and obtain the URI string for communicating with the Data submodule.
+
+The basic dependency packages include:
+- @ohos.ability.featureAbility
+- @ohos.data.dataAbility
+- @ohos.data.rdb
+
+#### Data Ability API Development
+
+
+1. Create a Data ability helper.
+
+ For details about the APIs provided by **DataAbilityHelper**, see [DataAbilityHelper Module](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md).
+ ```js
+ // Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/).
+ import featureAbility from '@ohos.ability.featureAbility'
+ import ohos_data_ability from '@ohos.data.dataAbility'
+ import ohos_data_rdb from '@ohos.data.rdb'
+
+ var urivar = "dataability:///com.ix.DataAbility"
+ var DAHelper = featureAbility.acquireDataAbilityHelper(
+ urivar
+ );
+ ```
+2. Construct RDB data.
+ ```js
+ var valuesBucket = {"name": "gaolu"}
+ var da = new ohos_data_ability.DataAbilityPredicates()
+ var valArray =new Array("value1");
+ var cars = new Array({"batchInsert1" : "value1",});
+ ```
+3. Use **insert** to insert data to the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.insert(
+ urivar,
+ valuesBucket,
+ (error, data) => {
+ console.log("DAHelper insert result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var datainsert = await DAHelper.insert(
+ urivar,
+ valuesBucket
+ );
+ ```
+4. Use **delete** to delete data from the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.delete(
+ urivar,
+ da,
+ (error, data) => {
+ console.log("DAHelper delete result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var datadelete = await DAHelper.delete(
+ urivar,
+ da,
+ );
+ ```
+5. Use **update** to update data in the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.update(
+ urivar
+ valuesBucket,
+ da,
+ (error, data) => {
+ console.log("DAHelper update result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var dataupdate = await DAHelper.update(
+ urivar,
+ valuesBucket,
+ da,
+ );
+ ```
+6. Use **query** to query data in the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.query(
+ urivar,
+ valArray,
+ da,
+ (error, data) => {
+ console.log("DAHelper query result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var dataquery = await DAHelper.query(
+ urivar,
+ valArray,
+ da
+ );
+ ```
+7. Use **batchInsert** to insert data in batches to the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.batchInsert(
+ urivar,
+ cars,
+ (error, data) => {
+ console.log("DAHelper batchInsert result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var databatchInsert = await DAHelper.batchInsert(
+ urivar,
+ cars
+ );
+ ```
+8. Use **executeBatch** to process data in batches in the Data submodule.
+ ```js
+ // Callback mode:
+ DAHelper.executeBatch(
+ urivar,
+ [
+ {
+ uri: urivar,
+ type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
+ valuesBucket: {"executeBatch" : "value1",},
+ predicates: da,
+ expectedCount:0,
+ predicatesBackReferences: null,
+ interrupted:true,
+ }
+ ],
+ (error, data) => {
+ console.log("DAHelper executeBatch result: " + data)
+ }
+ );
+ ```
+
+ ```js
+ // Promise mode:
+ var dataexecuteBatch = await DAHelper.executeBatch(
+ urivar,
+ [
+ {
+ uri: urivar,
+ type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
+ valuesBucket:
+ {
+ "executeBatch" : "value1",
+ },
+ predicates: da,
+ expectedCount:0,
+ predicatesBackReferences: null,
+ interrupted:true,
+ }
+ ]
+ );
+ ```
diff --git a/en/application-dev/ability-deprecated/fa-formability.md b/en/application-dev/ability-deprecated/fa-formability.md
new file mode 100644
index 0000000000000000000000000000000000000000..a91ca4b9baf98f32bad7ea081024d74949baf726
--- /dev/null
+++ b/en/application-dev/ability-deprecated/fa-formability.md
@@ -0,0 +1,404 @@
+# FA Widget Development
+
+## Widget Overview
+A widget is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first.
+
+A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message.
+
+Before you get started, it would be helpful if you have a basic understanding of the following concepts:
+- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users.
+- Widget host: an application that displays the widget content and controls the widget location.
+- Widget Manager: a resident agent that provides widget management features such as periodic widget updates.
+
+> **NOTE**
+>
+> The widget host and provider do not need to be running all the time. The Widget Manager will start the widget provider to obtain widget information when a widget is added, deleted, or updated.
+
+You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager.
+
+The widget provider controls the widget content to display, the layout of components used in the widget, and click events bound to the components.
+
+## Development Overview
+
+Carry out the following operations to develop the widget provider based on the [FA model](fa-brief.md):
+
+1. Implement lifecycle callbacks by using the **LifecycleForm** APIs.
+2. Create a **FormBindingData** instance.
+3. Update a widget by using the **FormProvider** APIs.
+4. Develop the widget UI pages.
+
+## Available APIs
+
+The table below describes the **LifecycleForm** APIs, which represent the lifecycle callbacks of a widget (known as a **Form** instance).
+
+**Table 1** LifecycleForm APIs
+
+| API | Description |
+| :----------------------------------------------------------- | :------------------------------------------- |
+| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created. |
+| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.|
+| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. |
+| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. |
+| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. |
+| onDestroy(formId: string): void | Called to notify the widget provider that a widget has been destroyed. |
+| onAcquireFormState?(want: Want): formInfo.FormState | Called to instruct the widget provider to receive the status query result of a widget. |
+
+The table below describes the **FormProvider** APIs. For details, see [FormProvider](../reference/apis/js-apis-application-formProvider.md).
+
+**Table 2** FormProvider APIs
+
+| API | Description |
+| :----------------------------------------------------------- | :------------------------------------------------ |
+| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. |
+| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.|
+| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. |
+| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. |
+
+## How to Develop
+
+### Implementing Lifecycle Callbacks
+
+To create an FA widget, you need to implement lifecycle callbacks using the **LifecycleForm** APIs. The sample code is as follows:
+
+1. Import the required modules.
+
+ ```javascript
+ import formBindingData from '@ohos.application.formBindingData'
+ import formInfo from '@ohos.application.formInfo'
+ import formProvider from '@ohos.application.formProvider'
+ ```
+
+2. Implement lifecycle callbacks for the widget.
+
+ ```javascript
+ export default {
+ onCreate(want) {
+ console.log('FormAbility onCreate');
+ // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
+ let obj = {
+ "title": "titleOnCreate",
+ "detail": "detailOnCreate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ return formData;
+ },
+ onCastToNormal(formId) {
+ // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
+ console.log('FormAbility onCastToNormal');
+ },
+ onUpdate(formId) {
+ // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host.
+ console.log('FormAbility onUpdate');
+ let obj = {
+ "title": "titleOnUpdate",
+ "detail": "detailOnUpdate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ formProvider.updateForm(formId, formData).catch((error) => {
+ console.log('FormAbility updateForm, error:' + JSON.stringify(error));
+ });
+ },
+ onVisibilityChange(newStatus) {
+ // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification.
+ console.log('FormAbility onVisibilityChange');
+ },
+ onEvent(formId, message) {
+ // If the widget supports event triggering, override this method and implement the trigger.
+ console.log('FormAbility onEvent');
+ },
+ onDestroy(formId) {
+ // Delete widget data.
+ console.log('FormAbility onDestroy');
+ },
+ onAcquireFormState(want) {
+ console.log('FormAbility onAcquireFormState');
+ return formInfo.FormState.READY;
+ },
+ }
+ ```
+
+### Configuring the Widget Configuration File
+
+The widget configuration file is named **config.json**. Find the **config.json** file for the widget and edit the file depending on your need.
+
+- The **js** module in the **config.json** file provides JavaScript resources of the widget. The internal structure is described as follows:
+
+ | Field| Description | Data Type| Default |
+ | -------- | ------------------------------------------------------------ | -------- | ------------------------ |
+ | name | Name of a JavaScript component. The default value is **default**. | String | No |
+ | pages | Route information about all pages in the JavaScript component, including the page path and page name. The value is an array, in which each element represents a page. The first element in the array represents the home page of the JavaScript FA.| Array | No |
+ | window | Window-related configurations. | Object | Yes |
+ | type | Type of the JavaScript component. **normal**: indicates an application instance. **form**: indicates a widget instance.| String | Yes (initial value: **normal**)|
+ | mode | Development mode of the JavaScript component. | Object | Yes (initial value: left empty) |
+
+ Example configuration:
+
+ ```json
+ "js": [{
+ "name": "widget",
+ "pages": ["pages/index/index"],
+ "window": {
+ "designWidth": 720,
+ "autoDesignWidth": true
+ },
+ "type": "form"
+ }]
+ ```
+
+- The **abilities** module in the **config.json** file corresponds to **LifecycleForm** of the widget. The internal structure is described as follows:
+
+ | Field | Description | Data Type | Default |
+ | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ |
+ | name | Class name of the widget. The value is a string with a maximum of 127 bytes. | String | No |
+ | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) |
+ | isDefault | Whether the widget is a default one. Each ability has only one default widget. **true**: The widget is the default one. **false**: The widget is not the default one.| Boolean | No |
+ | type | Type of the widget. **JS**: indicates a JavaScript-programmed widget. | String | No |
+ | colorMode | Color mode of the widget. **auto**: The widget adopts the auto-adaptive color mode. **dark**: The widget adopts the dark color mode. **light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)|
+ | supportDimensions | Grid styles supported by the widget. **1 * 2**: indicates a grid with one row and two columns. **2 * 2**: indicates a grid with two rows and two columns. **2 * 4**: indicates a grid with two rows and four columns. **4 * 4**: indicates a grid with four rows and four columns.| String array| No |
+ | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No |
+ | updateEnabled | Whether the widget can be updated periodically. **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**. **false**: The widget cannot be updated periodically.| Boolean | No |
+ | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute. **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) |
+ | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes. If the value is **0**, this field does not take effect. If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes. **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) |
+ | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) |
+ | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) |
+ | jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No |
+ | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) |
+ | customizeData | Custom information about the widget. | Object array | Yes (initial value: left empty) |
+
+ Example configuration:
+
+ ```json
+ "abilities": [{
+ "name": "FormAbility",
+ "description": "This is a FormAbility",
+ "formsEnabled": true,
+ "icon": "$media:icon",
+ "label": "$string:form_FormAbility_label",
+ "srcPath": "FormAbility",
+ "type": "service",
+ "srcLanguage": "ets",
+ "formsEnabled": true,
+ "forms": [{
+ "colorMode": "auto",
+ "defaultDimension": "2*2",
+ "description": "This is a widget.",
+ "formVisibleNotify": true,
+ "isDefault": true,
+ "jsComponentName": "widget",
+ "name": "widget",
+ "scheduledUpdateTime": "10:30",
+ "supportDimensions": ["2*2"],
+ "type": "JS",
+ "updateEnabled": true
+ }]
+ }]
+ ```
+
+
+### Persistently Storing Widget Data
+
+A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget.
+
+```javascript
+ onCreate(want) {
+ console.log('FormAbility onCreate');
+
+ let formId = want.parameters["ohos.extra.param.key.form_identity"];
+ let formName = want.parameters["ohos.extra.param.key.form_name"];
+ let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
+ // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
+ // The storeFormInfo API is not implemented here.
+ storeFormInfo(formId, formName, tempFlag, want);
+
+ let obj = {
+ "title": "titleOnCreate",
+ "detail": "detailOnCreate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ return formData;
+ }
+```
+
+You should override **onDestroy** to implement widget data deletion.
+
+```javascript
+ onDestroy(formId) {
+ console.log('FormAbility onDestroy');
+
+ // You need to implement the code for deleting the persistent widget data.
+ // The deleteFormInfo API is not implemented here.
+ deleteFormInfo(formId);
+ }
+```
+
+For details about how to implement persistence data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md).
+
+The **Want** passed by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary.
+
+- Normal widget: a widget persistently used by the widget host
+
+- Temporary widget: a widget temporarily used by the widget host
+
+Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake.
+
+### Updating Widget Data
+
+When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows:
+
+```javascript
+onUpdate(formId) {
+ // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host.
+ console.log('FormAbility onUpdate');
+ let obj = {
+ "title": "titleOnUpdate",
+ "detail": "detailOnUpdate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ // Call the updateForm method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged.
+ formProvider.updateForm(formId, formData).catch((error) => {
+ console.log('FormAbility updateForm, error:' + JSON.stringify(error));
+ });
+}
+```
+
+### Developing Widget UI Pages
+
+You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget.
+
+> **NOTE**
+>
+> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI.
+
+ - HML file:
+ ```html
+
+
+
+
+
+
+ {{title}}
+ {{detail}}
+
+
+
+ ```
+
+ - CSS file:
+
+ ```css
+.container {
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.bg-img {
+ flex-shrink: 0;
+ height: 100%;
+}
+
+.container-inner {
+ flex-direction: column;
+ justify-content: flex-end;
+ align-items: flex-start;
+ height: 100%;
+ width: 100%;
+ padding: 12px;
+}
+
+.title {
+ font-size: 19px;
+ font-weight: bold;
+ color: white;
+ text-overflow: ellipsis;
+ max-lines: 1;
+}
+
+.detail_text {
+ font-size: 16px;
+ color: white;
+ opacity: 0.66;
+ text-overflow: ellipsis;
+ max-lines: 1;
+ margin-top: 6px;
+}
+ ```
+
+ - JSON file:
+ ```json
+ {
+ "data": {
+ "title": "TitleDefault",
+ "detail": "TextDefault"
+ },
+ "actions": {
+ "routerEvent": {
+ "action": "router",
+ "abilityName": "com.example.entry.MainAbility",
+ "params": {
+ "message": "add detail"
+ }
+ }
+ }
+ }
+ ```
+
+Now you've got a widget shown below.
+
+
+
+### Developing Widget Events
+
+You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows:
+
+1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
+2. For the router event, set the following attributes:
+ - **action**: **router**, which indicates a router event.
+ - **abilityName**: target ability name, for example, **com.example.entry.MainAbility**, which is the default main ability name in DevEco Studio for the FA model.
+ - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field.
+3. For the message event, set the following attributes:
+ - **action**: **message**, which indicates a message event.
+ - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**.
+
+The code snippet is as follows:
+
+ - HML file:
+ ```html
+
+
+
+
+
+
+ {{title}}
+ {{detail}}
+
+
+
+ ```
+
+ - JSON file:
+ ```json
+ {
+ "data": {
+ "title": "TitleDefault",
+ "detail": "TextDefault"
+ },
+ "actions": {
+ "routerEvent": {
+ "action": "router",
+ "abilityName": "com.example.entry.MainAbility",
+ "params": {
+ "message": "add detail"
+ }
+ },
+ "messageEvent": {
+ "action": "message",
+ "params": {
+ "message": "add detail"
+ }
+ }
+ }
+ }
+ ```
\ No newline at end of file
diff --git a/en/application-dev/ability-deprecated/fa-pageability.md b/en/application-dev/ability-deprecated/fa-pageability.md
new file mode 100644
index 0000000000000000000000000000000000000000..2f4741b80ef771c9b478d32a7713b597fb65c2d4
--- /dev/null
+++ b/en/application-dev/ability-deprecated/fa-pageability.md
@@ -0,0 +1,224 @@
+# Page Ability Development
+
+## Overview
+
+### Concepts
+
+The Page ability implements the ArkUI and provides the capability of interacting with developers. When you create an ability in DevEco Studio, DevEco Studio automatically creates template code.
+
+The capabilities related to the Page ability are implemented through the **featureAbility**, and the lifecycle callbacks are implemented through the callbacks in **app.js** or **app.ets**.
+
+### Page Ability Lifecycle
+
+Introduction to the Page ability lifecycle:
+
+The Page ability lifecycle defines all states of a Page ability, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**.
+
+The following figure shows the lifecycle state transition of the Page ability.
+
+
+
+
+Description of ability lifecycle states:
+
+ - **UNINITIALIZED**: The Page ability is not initialized. This is a temporary state, from which a Page ability changes directly to the **INITIAL** state upon its creation.
+
+ - **INITIAL**: The Page ability is initialized but not running. The Page ability enters the **INACTIVE** state after it is started.
+
+ - **INACTIVE**: The Page ability is visible but does not gain focus.
+
+ - **ACTIVE**: The Page ability runs in the foreground and has focus.
+
+ - **BACKGROUND**: The Page ability runs in the background. After being re-activated, the Page ability enters the **ACTIVE** state. After being destroyed, the Page ability enters the **INITIAL** state.
+
+The following figure shows the relationship between lifecycle callbacks and lifecycle states of the Page ability.
+
+
+
+You can override the lifecycle callbacks provided by the Page ability in the **app.js** or **app.ets** file. Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks.
+
+### Launch Type
+
+The ability supports two launch types: singleton and multi-instance.
+
+You can specify the launch type by setting **launchType** in the **config.json** file.
+
+**Table 1** Startup modes
+
+| Launch Type | Description |Description |
+| ----------- | ------- |---------------- |
+| standard | Multi-instance | A new instance is started each time an ability starts.|
+| singleton | Singleton | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.|
+
+By default, **singleton** is used.
+
+
+## Development Guidelines
+
+### Available APIs
+
+**Table 2** APIs provided by featureAbility
+
+| API | Description |
+| --------------------------------------------------- | --------------- |
+| void startAbility(parameter: StartAbilityParameter) | Starts an ability. |
+| Context getContext(): | Obtains the application context.|
+| void terminateSelf() | Terminates the ability. |
+| bool hasWindowFocus() | Checks whether the ability has focus. |
+
+
+### Starting a Local Page Ability
+
+**Modules to Import**
+
+```js
+ import featureAbility from '@ohos.ability.featureAbility'
+```
+
+**Example**
+
+```javascript
+ import featureAbility from '@ohos.ability.featureAbility'
+ featureAbility.startAbility({
+ want: {
+ action: "",
+ entities: [""],
+ type: "",
+ deviceId: "",
+ bundleName: "com.example.myapplication",
+ /* In the FA model, abilityName consists of package and ability name. */
+ abilityName: "com.example.entry.secondAbility",
+ uri: ""
+ }
+ });
+```
+
+### Starting a Remote Page Ability
+>NOTE
+>
+>This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications.
+
+**Modules to Import**
+
+```
+ import featureAbility from '@ohos.ability.featureAbility'
+ import deviceManager from '@ohos.distributedHardware.deviceManager';
+```
+
+**Example**
+```ts
+ function onStartRemoteAbility() {
+ console.info('onStartRemoteAbility begin');
+ let params;
+ let wantValue = {
+ bundleName: 'ohos.samples.etsDemo',
+ abilityName: 'ohos.samples.etsDemo.RemoteAbility',
+ deviceId: getRemoteDeviceId(),
+ parameters: params
+ };
+ console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
+ featureAbility.startAbility({
+ want: wantValue
+ }).then((data) => {
+ console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
+ });
+ console.info('onStartRemoteAbility end');
+ }
+```
+
+Obtain **deviceId** from **DeviceManager**. The sample code is as follows:
+
+```ts
+ import deviceManager from '@ohos.distributedHardware.deviceManager';
+ let dmClass;
+ function getRemoteDeviceId() {
+ if (typeof dmClass === 'object' && dmClass != null) {
+ let list = dmClass.getTrustedDeviceListSync();
+ if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
+ return;
+ }
+ console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
+ return list[0].deviceId;
+ } else {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
+ }
+ }
+```
+
+In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows:
+
+```ts
+ import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
+ import bundle from '@ohos.bundle';
+ async function RequestPermission() {
+ console.info('RequestPermission begin');
+ let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"];
+ let bundleFlag = 0;
+ let tokenID = undefined;
+ let userID = 100;
+ let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
+ tokenID = appInfo.accessTokenId;
+ let atManager = abilityAccessCtrl.createAtManager();
+ let requestPermissions: Array = [];
+ for (let i = 0;i < array.length; i++) {
+ let result = await atManager.verifyAccessToken(tokenID, array[i]);
+ console.info("verifyAccessToken result:" + JSON.stringify(result));
+ if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
+ requestPermissions.push(array[i]);
+ }
+ }
+ console.info("requestPermissions:" + JSON.stringify(requestPermissions));
+ if (requestPermissions.length == 0 || requestPermissions == []) {
+ return;
+ }
+ let context = featureAbility.getContext();
+ context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
+ console.info("data:" + JSON.stringify(data));
+ console.info("data requestCode:" + data.requestCode);
+ console.info("data permissions:" + data.permissions);
+ console.info("data authResults:" + data.authResults);
+ });
+ console.info('RequestPermission end');
+ }
+```
+
+### Lifecycle APIs
+
+**Table 3** Lifecycle callbacks
+
+| API | Description |
+| ------------ | ------------------------------------------------------------ |
+| onShow() | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.|
+| onHide() | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible to users.|
+| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for application exit, such as recycling resources and clearing the cache.|
+| onCreate() | Called when the ability is created for the first time. You can initialize the application in this callback.|
+| onInactive() | Called when the ability loses focus. An ability loses focus when it is about to enter the background state.|
+| onActive() | Called when the ability is switched to the foreground and gains focus. |
+
+**Example**
+
+You need to override the lifecycle callbacks except **onCreate()** and **onDestroy()** in **app.js** or **app.ets**. The **onCreate()** and **onDestroy()** callbacks are automatically generated in the template code provided by DevEco Studio.
+
+```javascript
+export default {
+ onCreate() {
+ console.info('Application onCreate')
+ },
+ onDestroy() {
+ console.info('Application onDestroy')
+ },
+ onShow(){
+ console.info('Application onShow')
+ },
+ onHide(){
+ console.info('Application onHide')
+ },
+ onInactive(){
+ console.info('Application onInactive')
+ },
+ onActive(){
+ console.info('Application onActive')
+ },
+}
+```
diff --git a/en/application-dev/ability-deprecated/fa-serviceability.md b/en/application-dev/ability-deprecated/fa-serviceability.md
new file mode 100644
index 0000000000000000000000000000000000000000..cf766f35f72c76eb738d3b168d39cbcba0f21da3
--- /dev/null
+++ b/en/application-dev/ability-deprecated/fa-serviceability.md
@@ -0,0 +1,335 @@
+# Service Ability Development
+
+## When to Use
+A Service ability is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. Service abilities can be started by other applications or abilities and can keep running in the background even after the user switches to another application.
+
+## Lifecycle APIs
+
+**Table 1** Service ability lifecycle APIs
+|API|Description|
+|:------|:------|
+|onStart?(): void|Called to initialize a Service ability when the Service ability is being created. This callback is invoked only once in the entire lifecycle of a Service ability.|
+|onCommand?(want: Want, startId: number): void|Called every time a Service ability is created on the client. You can collect calling statistics and perform initialization operations in this callback.|
+|onConnect?(want: Want): rpc.RemoteObject|Called when another ability is connected to the Service ability.|
+|onDisconnect?(want: Want): void|Called when another ability is disconnected from the Service ability.|
+|onStop?(): void|Called when the Service ability is being destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners.|
+
+The differences between **onCommand()** and **onConnect()** are as follows:
+ - The **onCommand()** callback is triggered each time the client starts the Service ability by calling **startAbility** or **startAbilityForResult**.
+ - The **onConnect()** callback is triggered each time the client establishes a new connection with the Service ability by calling **connectAbility**.
+
+## How to Develop
+
+### Creating and Registering a Service Ability
+
+1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests.
+
+
+
+ ```ts
+ export default {
+ onStart() {
+ console.log('ServiceAbility onStart');
+ },
+ onCommand(want, startId) {
+ console.log('ServiceAbility onCommand');
+ },
+ onConnect(want) {
+ console.log('ServiceAbility OnConnect');
+ // Below lists the implementation of ServiceAbilityStub.
+ return new ServiceAbilityStub('test');
+ },
+ onDisconnect(want) {
+ console.log('ServiceAbility OnDisConnect');
+ },
+ onStop() {
+ console.log('ServiceAbility onStop');
+ }
+ }
+ ```
+
+2. Register a Service ability.
+
+ Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**.
+
+ ```json
+ {
+ "module": {
+ "abilities": [
+ {
+ "name": ".ServiceAbility",
+ "type": "service",
+ "visible": true
+ ...
+ }
+ ]
+ ...
+ }
+ ...
+ }
+ ```
+
+
+
+### Starting a Service Ability
+
+The **Ability** class provides the **startAbility()** API for you to start another Service ability by passing a **Want** object.
+
+To set information about the target Service ability, you can first construct a **Want** object with the **bundleName** and **abilityName** parameters specified.
+
+- **bundleName** specifies the bundle name of the target application.
+- **abilityName** specifies the target ability name.
+
+The following code snippet shows how to start a Service ability running on the local device:
+
+```ts
+import featureAbility from '@ohos.ability.featureAbility'
+
+featureAbility.startAbility(
+ {
+ want:
+ {
+ bundleName: "com.jstest.service",
+ abilityName: "com.jstest.service.ServiceAbility"
+ }
+ }
+).then((err) => {
+ console.log("startService success");
+}).catch (err => {
+ console.log("startService FAILED");
+});
+```
+
+In the preceding code, the **startAbility()** API is used to start the Service ability.
+- If the Service ability is not running, the system initializes the Service ability, and calls **onStart()** and **onCommand()** on the Service ability in sequence.
+- If the Service ability is running, the system directly calls **onCommand()** on the Service ability.
+
+The following code snippet shows how to start a Service ability running on the remote device. For details, see [Connecting to a Remote Service Ability](#connecting-to-a-remote-service-ability).
+
+```ts
+import featureAbility from '@ohos.ability.featureAbility'
+
+featureAbility.startAbility(
+ {
+ want:
+ {
+ deviceId: remoteDeviceId, // Remote device ID.
+ bundleName: "com.jstest.service",
+ abilityName: "com.jstest.service.ServiceAbility"
+ }
+ }
+).then((err) => {
+ console.log("startService success");
+}).catch (err => {
+ console.log("startService FAILED");
+});
+```
+
+
+### Stopping a Service Ability
+
+ In normal cases, a Service ability can be stopped by itself or by the system.
+ - The Service ability can call **particleAbility.terminateSelf()** to stop itself.
+ - If the application process where the Service ability is located exits, the Service ability is reclaimed along with the process.
+ - If the Service ability is only accessed through **connectAbility()** (the **onCommand()** callback has never been triggered), the system stops the Service ability when the last connection to the Service ability is disconnected.
+
+### Connecting to a Local Service Ability
+
+If a Service ability wants to interact with a Page ability or a Service ability in another application, you must first create a connection. A Service ability allows other abilities to connect to it through **connectAbility()**.
+
+
+You can use either of the following methods to connect to a Service ability:
+
+1. Using the IDL to automatically generate code
+
+ Use OpenHarmony Interface Definition Language (IDL) to automatically generate the corresponding client, server, and **IRemoteObject** code. For details, see [Development Using TS](../IDL/idl-guidelines.md#development-using-ts).
+
+2. Writing code in the corresponding file
+
+ When using **connectAbility()**, pass the **Want** and **ConnectOptions** objects of the target Service ability, where **ConnectOptions** encapsulates the following three callbacks that need to be implemented.
+ - **onConnect()**: callback used for processing when the Service ability is connected.
+ - **onDisconnect()**: callback used for processing when the Service ability is disconnected.
+ - **onFailed()**: callback used for processing when the connection to the Service ability fails.
+
+ The following code snippet shows how to implement the callbacks:
+
+ ```ts
+ import prompt from '@system.prompt'
+
+ var option = {
+ onConnect: function onConnectCallback(element, proxy) {
+ console.log(`onConnectLocalService onConnectDone`);
+ if (proxy === null) {
+ prompt.showToast({
+ message: "Connect service failed"
+ });
+ return;
+ }
+ // After obtaining the proxy of the Service ability, the calling ability can communicate with the Service ability.
+ let data = rpc.MessageParcel.create();
+ let reply = rpc.MessageParcel.create();
+ let option = new rpc.MessageOption();
+ data.writeString("InuptString");
+ proxy.sendRequest(0, data, reply, option);
+ prompt.showToast({
+ message: "Connect service success"
+ });
+ },
+ onDisconnect: function onDisconnectCallback(element) {
+ console.log(`onConnectLocalService onDisconnectDone element:${element}`);
+ prompt.showToast({
+ message: "Disconnect service success"
+ });
+ },
+ onFailed: function onFailedCallback(code) {
+ console.log(`onConnectLocalService onFailed errCode:${code}`);
+ prompt.showToast({
+ message: "Connect local service onFailed"
+ });
+ }
+ };
+ ```
+
+ The following code snippet shows how to connect to a local Service ability:
+
+ ```ts
+ import featureAbility from '@ohos.ability.featureAbility'
+
+ let want = {
+ bundleName: "com.jstest.service",
+ abilityName: "com.jstest.service.ServiceAbility"
+ };
+ let connectId = featureAbility.connectAbility(want, option);
+ ```
+
+ When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides the default implementation of **IRemoteObject**. You can inherit **rpc.RemoteObject** to create a custom implementation class for interaction with the Service ability. For details, see the [RPC API Reference](..\reference\apis\js-apis-rpc.md).
+
+ The following code snippet shows how the Service ability returns itself to the calling ability:
+
+ ```ts
+ import rpc from "@ohos.rpc"
+
+ class ServiceAbilityStub extends rpc.RemoteObject {
+ constructor(des: any) {
+ if (typeof des === 'string') {
+ super(des);
+ } else {
+ console.log("Error, the input param is not string");
+ return;
+ }
+ }
+
+ onRemoteRequest(code: number, data: any, reply: any, option: any) {
+ console.log("onRemoteRequest called");
+ // Execute the service logic.
+ if (code === 1) {
+ // Sort the input strings.
+ let string = data.readString();
+ console.log(`Input string = ${string}`);
+ let result = Array.from(string).sort().join('');
+ console.log(`Output result = ${result}`);
+ reply.writeString(result);
+ } else {
+ console.log(`Unknown request code`);
+ }
+ return true;
+ }
+ }
+
+ export default {
+ onStart() {
+ console.log('ServiceAbility onStart');
+ },
+ onCommand(want, startId) {
+ console.log('ServiceAbility onCommand');
+ },
+ onConnect(want) {
+ console.log('ServiceAbility OnConnect');
+ return new ServiceAbilityStub('ServiceAbilityRemoteObject');
+ },
+ onDisconnect(want) {
+ console.log('ServiceAbility OnDisConnect');
+ },
+ onStop() {
+ console.log('ServiceAbility onStop');
+ }
+ }
+ ```
+
+### Connecting to a Remote Service Ability
+
+This feature applies only to system applications. The method of creating a **ConnectOptions** object for connecting to a remote Service ability is similar to that for connecting to a local Service ability. The differences are as follows:
+ - The application must apply for the data synchronization permission from the user.
+ - **Want** of the target Service ability must contain the remote device ID.
+
+> **NOTE**
+>
+> The **getTrustedDeviceList** API of **DeviceManager** is open only to system applications. Currently, only system applications can connect to a remote Service ability.
+>
+> For details about the API definition, see [Device Management](..\reference\apis\js-apis-device-manager.md).
+
+The data synchronization permission is required in the cross-device scenario. Configure the permission in the **config.json** file.
+
+```json
+{
+ ...
+ "module": {
+ ...
+ "reqPermissions": [{
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
+ }]
+ }
+}
+```
+
+The **DISTRIBUTED_DATASYNC** permission is user granted. Therefore, your application, when being started, must display a dialog box to request the permission. The sample code is as follows:
+
+```ts
+import abilityAccessCtrl from "@ohos.abilityAccessCtrl"
+import bundle from '@ohos.bundle'
+
+async function RequestPermission() {
+ console.info('RequestPermission begin');
+ let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"];
+ let bundleFlag = 0;
+ let tokenID = undefined;
+ let userID = 100;
+ let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
+ tokenID = appInfo.accessTokenId;
+ let atManager = abilityAccessCtrl.createAtManager();
+ let requestPermissions: Array = [];
+ for (let i = 0;i < array.length; i++) {
+ let result = await atManager.verifyAccessToken(tokenID, array[i]);
+ console.info("verifyAccessToken result:" + JSON.stringify(result));
+ if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
+ requestPermissions.push(array[i]);
+ }
+ }
+ console.info("requestPermissions:" + JSON.stringify(requestPermissions));
+ if (requestPermissions.length == 0 || requestPermissions == []) {
+ return;
+ }
+ let context = featureAbility.getContext();
+ context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
+ console.info("data:" + JSON.stringify(data));
+ });
+ console.info('RequestPermission end');
+}
+```
+
+To obtain the device ID, import the **@ohos.distributedHardware.deviceManager** module, which provides **getTrustedDeviceList** to obtain the remote device ID. For details about how to use the API, see [Device Management](..\reference\apis\js-apis-device-manager.md).
+
+To connect to a remote Service ability, you only need to define **deviceId** in **Want**. The sample code is as follows:
+
+```ts
+import featureAbility from '@ohos.ability.featureAbility'
+
+let want = {
+ deviceId: remoteDeviceId,
+ bundleName: "com.jstest.service",
+ abilityName: "com.jstest.service.ServiceAbility"
+};
+let connectId = featureAbility.connectAbility(want, option);
+```
+
+The other implementations are the same as those for the connection to a local Service ability. For details, see the sample code provided under [Connecting to a Local Service Ability](#connecting-to-a-local-service-ability).
diff --git a/en/application-dev/ability/figures/AbilityComponentInstanceMission.png b/en/application-dev/ability-deprecated/figures/AbilityComponentInstanceMission.png
similarity index 100%
rename from en/application-dev/ability/figures/AbilityComponentInstanceMission.png
rename to en/application-dev/ability-deprecated/figures/AbilityComponentInstanceMission.png
diff --git a/en/application-dev/ability/figures/ExtensionAbility.png b/en/application-dev/ability-deprecated/figures/ExtensionAbility.png
similarity index 100%
rename from en/application-dev/ability/figures/ExtensionAbility.png
rename to en/application-dev/ability-deprecated/figures/ExtensionAbility.png
diff --git a/en/application-dev/ability/figures/aa-dump-a.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-a.PNG
similarity index 100%
rename from en/application-dev/ability/figures/aa-dump-a.PNG
rename to en/application-dev/ability-deprecated/figures/aa-dump-a.PNG
diff --git a/en/application-dev/ability/figures/aa-dump-i.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-i.PNG
similarity index 100%
rename from en/application-dev/ability/figures/aa-dump-i.PNG
rename to en/application-dev/ability-deprecated/figures/aa-dump-i.PNG
diff --git a/en/application-dev/ability/figures/aa-dump-l.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-l.PNG
similarity index 100%
rename from en/application-dev/ability/figures/aa-dump-l.PNG
rename to en/application-dev/ability-deprecated/figures/aa-dump-l.PNG
diff --git a/en/application-dev/ability-deprecated/figures/contextIntroduction.png b/en/application-dev/ability-deprecated/figures/contextIntroduction.png
new file mode 100644
index 0000000000000000000000000000000000000000..50ec4d39f722431513051be8f6674f15307117f4
Binary files /dev/null and b/en/application-dev/ability-deprecated/figures/contextIntroduction.png differ
diff --git a/en/application-dev/ability/figures/continuation-info.png b/en/application-dev/ability-deprecated/figures/continuation-info.png
similarity index 100%
rename from en/application-dev/ability/figures/continuation-info.png
rename to en/application-dev/ability-deprecated/figures/continuation-info.png
diff --git a/en/application-dev/ability/figures/continuationManager.png b/en/application-dev/ability-deprecated/figures/continuationManager.png
similarity index 100%
rename from en/application-dev/ability/figures/continuationManager.png
rename to en/application-dev/ability-deprecated/figures/continuationManager.png
diff --git a/en/application-dev/ability/figures/fa-dataability-uri.png b/en/application-dev/ability-deprecated/figures/fa-dataability-uri.png
similarity index 100%
rename from en/application-dev/ability/figures/fa-dataability-uri.png
rename to en/application-dev/ability-deprecated/figures/fa-dataability-uri.png
diff --git a/en/application-dev/ability/figures/fa-form-example.png b/en/application-dev/ability-deprecated/figures/fa-form-example.png
similarity index 100%
rename from en/application-dev/ability/figures/fa-form-example.png
rename to en/application-dev/ability-deprecated/figures/fa-form-example.png
diff --git a/en/application-dev/ability/figures/fa-pageAbility-lifecycle.png b/en/application-dev/ability-deprecated/figures/fa-pageAbility-lifecycle.png
similarity index 100%
rename from en/application-dev/ability/figures/fa-pageAbility-lifecycle.png
rename to en/application-dev/ability-deprecated/figures/fa-pageAbility-lifecycle.png
diff --git a/en/application-dev/ability/figures/fa-threading-model.png b/en/application-dev/ability-deprecated/figures/fa-threading-model.png
similarity index 100%
rename from en/application-dev/ability/figures/fa-threading-model.png
rename to en/application-dev/ability-deprecated/figures/fa-threading-model.png
diff --git a/en/application-dev/ability-deprecated/figures/favsstage.png b/en/application-dev/ability-deprecated/figures/favsstage.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e5980fc1df4634d4ea1ff23158e79d62637f8ba
Binary files /dev/null and b/en/application-dev/ability-deprecated/figures/favsstage.png differ
diff --git a/zh-cn/application-dev/ability/figures/lifecycle.png b/en/application-dev/ability-deprecated/figures/lifecycle.png
similarity index 100%
rename from zh-cn/application-dev/ability/figures/lifecycle.png
rename to en/application-dev/ability-deprecated/figures/lifecycle.png
diff --git a/en/application-dev/ability/figures/page-ability-lifecycle.png b/en/application-dev/ability-deprecated/figures/page-ability-lifecycle.png
similarity index 100%
rename from en/application-dev/ability/figures/page-ability-lifecycle.png
rename to en/application-dev/ability-deprecated/figures/page-ability-lifecycle.png
diff --git a/en/application-dev/ability/figures/stage-call.png b/en/application-dev/ability-deprecated/figures/stage-call.png
similarity index 100%
rename from en/application-dev/ability/figures/stage-call.png
rename to en/application-dev/ability-deprecated/figures/stage-call.png
diff --git a/zh-cn/application-dev/ability/figures/stageabilitylifecyclecallback.png b/en/application-dev/ability-deprecated/figures/stageabilitylifecyclecallback.png
similarity index 100%
rename from zh-cn/application-dev/ability/figures/stageabilitylifecyclecallback.png
rename to en/application-dev/ability-deprecated/figures/stageabilitylifecyclecallback.png
diff --git a/en/application-dev/ability/figures/stageconcept.png b/en/application-dev/ability-deprecated/figures/stageconcept.png
similarity index 100%
rename from en/application-dev/ability/figures/stageconcept.png
rename to en/application-dev/ability-deprecated/figures/stageconcept.png
diff --git a/en/application-dev/ability/figures/stagedesign.png b/en/application-dev/ability-deprecated/figures/stagedesign.png
similarity index 100%
rename from en/application-dev/ability/figures/stagedesign.png
rename to en/application-dev/ability-deprecated/figures/stagedesign.png
diff --git a/en/application-dev/ability/figures/stageprocessmodel.png b/en/application-dev/ability-deprecated/figures/stageprocessmodel.png
similarity index 100%
rename from en/application-dev/ability/figures/stageprocessmodel.png
rename to en/application-dev/ability-deprecated/figures/stageprocessmodel.png
diff --git a/en/application-dev/ability/public_sys-resources/icon-caution.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-caution.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-caution.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-caution.gif
diff --git a/en/application-dev/ability/public_sys-resources/icon-danger.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-danger.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-danger.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-danger.gif
diff --git a/en/application-dev/ability/public_sys-resources/icon-note.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-note.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-note.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-note.gif
diff --git a/en/application-dev/ability/public_sys-resources/icon-notice.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-notice.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-notice.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-notice.gif
diff --git a/en/application-dev/ability/public_sys-resources/icon-tip.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-tip.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-tip.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-tip.gif
diff --git a/en/application-dev/ability/public_sys-resources/icon-warning.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-warning.gif
similarity index 100%
rename from en/application-dev/ability/public_sys-resources/icon-warning.gif
rename to en/application-dev/ability-deprecated/public_sys-resources/icon-warning.gif
diff --git a/en/application-dev/ability-deprecated/stage-ability-continuation.md b/en/application-dev/ability-deprecated/stage-ability-continuation.md
new file mode 100644
index 0000000000000000000000000000000000000000..7a11716f18f2c8b866e1fd11722ae0e07a32d4ce
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-ability-continuation.md
@@ -0,0 +1,313 @@
+# Ability Continuation Development
+
+## When to Use
+
+Ability continuation is to continue the current mission of an application, including the UI component state variables and distributed objects, on another device. The UI component state variables are used to synchronize UI data, and the distributed objects are used to synchronize memory data.
+
+## Available APIs
+
+The following table lists the APIs used for ability continuation. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md).
+
+**Table 1** Ability continuation APIs
+
+|API| Description|
+|:------ | :------|
+| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for continuation. The return value indicates whether the continuation request is accepted. The value **AGREE** means that the continuation request is accepted, **REJECT** means that the continuation request is rejected, and **MISMATCH** means a version mismatch.|
+| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance ability scenario.|
+| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton ability scenario.|
+
+
+
+**Figure 1** Ability continuation development
+
+
+
+In effect, ability continuation is a cross-device ability startup that carries data. When a continuation action is initiated, the system on device A calls back **onContinue()** of the application. You must implement storage of the current data in this API. Then, the system initiates a cross-device ability startup on device B and transmits the data to device B. The system on device B calls back **onCreate()** or **onNewWant()**. You must implement restoration of the transmitted data in this API.
+
+## How to Develop
+
+The code snippets provided below are all from [Sample](https://gitee.com/openharmony/ability_dmsfwk/tree/master/services/dtbschedmgr/test/samples/continuationManualTestSuite).
+
+### Application Continuation
+
+1. Modify the configuration file.
+
+ - Configure the application to support ability continuation.
+
+ Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on another device.
+
+ ```javascript
+ {
+ "module": {
+ "abilities": [
+ {
+ "continuable": true
+ }
+ ]
+ }
+ }
+ ```
+
+
+
+
+ - Configure the application startup type.
+
+ If **launchType** is set to **standard** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md).
+
+ Configure a multi-instance application as follows:
+
+ ```javascript
+ {
+ "module": {
+ "abilities": [
+ {
+ "launchType": "standard"
+ }
+ ]
+ }
+ }
+ ```
+
+ Configure a singleton application as follows or retain the default settings of **launchType**:
+
+ ```javascript
+ {
+ "module": {
+ "abilities": [
+ {
+ "launchType": "singleton"
+ }
+ ]
+ }
+ }
+ ```
+
+
+
+ - Apply for the distributed permissions.
+
+ Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application.
+
+ ```javascript
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
+ },
+ ```
+
+
+
+ This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class:
+
+ ```javascript
+ requestPermissions = async () => {
+ let permissions: Array = [
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+ ];
+ let needGrantPermission = false
+ let accessManger = accessControl.createAtManager()
+ Logger.info("app permission get bundle info")
+ let bundleInfo = await bundle.getApplicationInfo(BUNDLE_NAME, 0, 100)
+ Logger.info(`app permission query permission ${bundleInfo.accessTokenId.toString()}`)
+ for (const permission of permissions) {
+ Logger.info(`app permission query grant status ${permission}`)
+ try {
+ let grantStatus = await accessManger.verifyAccessToken(bundleInfo.accessTokenId, permission)
+ if (grantStatus === PERMISSION_REJECT) {
+ needGrantPermission = true
+ break;
+ }
+ } catch (err) {
+ Logger.error(`app permission query grant status error ${permission} ${JSON.stringify(err)}`)
+ needGrantPermission = true
+ break;
+ }
+ }
+ if (needGrantPermission) {
+ Logger.info("app permission needGrantPermission")
+ try {
+ await this.context.requestPermissionsFromUser(permissions)
+ } catch (err) {
+ Logger.error(`app permission ${JSON.stringify(err)}`)
+ }
+ } else {
+ Logger.info("app permission already granted")
+ }
+ }
+ ```
+
+
+
+
+2. Implement the **onContinue()** API.
+
+ The **onContinue()** API is called by the initiator to save the UI component state variables and memory data and prepare for continuation. After the application completes the continuation preparation, the system must return either **OnContinueResult.AGREE(0)** to accept the continuation request or an error code to reject the request. If this API is not implemented, the system rejects the continuation request by default.
+
+ Modules to import:
+
+ ```javascript
+ import Ability from '@ohos.application.Ability';
+ import AbilityConstant from '@ohos.application.AbilityConstant';
+ ```
+
+ To implement ability continuation, you must implement this API and have the value **AGREE** returned.
+
+ You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request.
+
+ Example
+
+ ```javascript
+ onContinue(wantParam : {[key: string]: any}) {
+ Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
+ let workInput = AppStorage.Get('ContinueWork');
+ // Set the user input data into wantParam.
+ wantParam["work"] = workInput // set user input data into want params
+ Logger.info(`onContinue input = ${wantParam["input"]}`);
+ return AbilityConstant.OnContinueResult.AGREE
+ }
+ ```
+
+
+
+3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API.
+
+ The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored.
+
+ The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**.
+
+ After data restore is complete, call **restoreWindowStage** to trigger page restoration.
+
+
+
+ You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator.
+
+ Example
+
+ ```javascript
+ import Ability from '@ohos.application.Ability';
+ import distributedObject from '@ohos.data.distributedDataObject';
+
+ export default class MainAbility extends Ability {
+ storage : LocalStorag;
+
+ onCreate(want, launchParam) {
+ Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
+ if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
+ // Obtain the user data from the want parameter.
+ let workInput = want.parameters.work
+ Logger.info(`work input ${workInput}`)
+ AppStorage.SetOrCreate('ContinueWork', workInput)
+
+ this.storage = new LocalStorage();
+ this.context.restoreWindowStage(this.storage);
+ }
+ }
+ }
+ ```
+For a singleton ability, use **onNewWant()** to achieve the same implementation.
+
+
+
+### Data Continuation
+
+Use distributed objects.
+
+Distributed objects allow cross-device data synchronization like local variables. For two devices that form a Super Device, when data in the distributed data object of an application is added, deleted, or modified on a device, the data for the same application is also updated on the other device. Both devices can listen for the data changes and online and offline states of the other. For details, see [Distributed Data Object Development](../database/database-distributedobject-guidelines.md).
+
+In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device.
+
+- In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**.
+
+ ```javascript
+ import Ability from '@ohos.application.Ability';
+ import distributedObject from '@ohos.data.distributedDataObject';
+
+ var g_object = distributedObject.createDistributedObject({data:undefined});
+
+ export default class MainAbility extends Ability {
+ sessionId : string;
+
+ onContinue(wantParam : {[key: string]: any}) {
+ Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
+
+ if (g_object.__sessionId === undefined) {
+ this.sessionId = distributedObject.genSessionId()
+ Logger.info(`onContinue generate new sessionId`)
+ }
+ else {
+ this.sessionId = g_object.__sessionId;
+ }
+
+ wantParam["session"] = this.sessionId
+ g_object.data = AppStorage.Get('ContinueStudy');
+ Logger.info(`onContinue sessionId = ${this.sessionId}, name = ${g_object.data}`)
+ g_object.setSessionId(this.sessionId);
+ g_object.save(wantParam.targetDevice, (result, data)=>{
+ Logger.info("save callback");
+ Logger.info("save sessionId " + data.sessionId);
+ Logger.info("save version " + data.version);
+ Logger.info("save deviceId " + data.deviceId);
+ });
+ ```
+
+
+
+- The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated.
+
+ ```javascript
+ import Ability from '@ohos.application.Ability';
+ import distributedObject from '@ohos.data.distributedDataObject';
+
+ var g_object = distributedObject.createDistributedObject({data:undefined});
+
+ export default class MainAbility extends Ability {
+ storage : LocalStorag;
+
+
+ onCreate(want, launchParam) {
+ Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
+ if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
+ // Obtain the session ID of the distributed data object from the want parameter.
+ this.sessionId = want.parameters.session
+ Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`)
+
+ // Before fetching data from the remote device, reset g_object.data to undefined.
+ g_object.data = undefined;
+ // Set the session ID, so the target will fetch data from the remote device.
+ g_object.setSessionId(this.sessionId);
+
+ AppStorage.SetOrCreate('ContinueStudy', g_object.data)
+ this.storage = new LocalStorage();
+ this.context.restoreWindowStage(this.storage);
+ }
+
+ }
+ }
+ ```
+
+
+
+### More Information
+
+1. Timeout
+
+ - If the application to be continued is not installed on the target device, the system checks whether the application can be installed on it and waits for a response for 4 seconds. If no response is received within 4 seconds, the caller receives a timeout error code, which means that the application cannot be installed on the target device. If the application can be installed, the system prompts the consumer to install the application on the target device. The consumer can initiate the continuation again after the installation.
+ - If the application to be continued has been installed on the target device, the system waits for a response to the continuation request for 20 seconds. If no response is received within 20 seconds, the caller receives a timeout error code, which means that the continuation fails.
+
+2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required.
+
+
+
+### Restrictions
+
+1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/module-configuration-file.md).
+2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system.
+
+
+
+### Best Practice
+
+For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB.
+
+
\ No newline at end of file
diff --git a/en/application-dev/ability-deprecated/stage-ability.md b/en/application-dev/ability-deprecated/stage-ability.md
new file mode 100644
index 0000000000000000000000000000000000000000..97ba5cff5cc083563f1d0f78c7b499bff2cd2050
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-ability.md
@@ -0,0 +1,325 @@
+# Ability Development
+## When to Use
+Ability development in the [stage model](stage-brief.md) is significantly different from that in the FA model. The stage model requires you to declare the application package structure in the **module.json5** and **app.json5** files during application development. For details about the configuration file, see [Application Package Structure Configuration File](../quick-start/application-package-structure-stage.md). To develop an ability based on the stage model, implement the following logic:
+- Create an ability that supports screen viewing and human-machine interaction. You must implement the following scenarios: ability lifecycle callbacks, obtaining ability configuration, requesting permissions, and notifying environment changes.
+- Start an ability. You need to implement ability startup on the same device, on a remote device, or with a specified UI page.
+- Call abilities. For details, see [Call Development](stage-call.md).
+- Connect to and disconnect from a Service Extension ability. For details, see [Service Extension Ability Development](stage-serviceextension.md).
+- Continue the ability on another device. For details, see [Ability Continuation Development](stage-ability-continuation.md).
+
+### Launch Type
+An ability can be launched in the **standard**, **singleton**, or **specified** mode, as configured by **launchType** in the **module.json5** file. Depending on the launch type, the action performed when the ability is started differs, as described below.
+
+| Launch Type | Description |Action |
+| ----------- | ------- |---------------- |
+| standard | Standard mode | A new instance is started each time an ability starts.|
+| singleton | Singleton mode | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.|
+| specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.|
+
+By default, the singleton mode is used. The following is an example of the **module.json5** file:
+```json
+{
+ "module": {
+ "abilities": [
+ {
+ "launchType": "singleton",
+ }
+ ]
+ }
+}
+```
+## Creating an Ability
+### Available APIs
+The table below describes the APIs provided by the **AbilityStage** class, which has the **context** attribute. For details about the APIs, see [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md).
+
+**Table 1** AbilityStage APIs
+|API|Description|
+|:------|:------|
+|onCreate(): void|Called when an ability stage is created.|
+|onAcceptWant(want: Want): string|Called when a specified ability is started.|
+|onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.|
+
+The table below describes the APIs provided by the **Ability** class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md).
+
+**Table 2** Ability APIs
+
+|API|Description|
+|:------|:------|
+|onCreate(want: Want, param: AbilityConstant.LaunchParam): void|Called when an ability is created.|
+|onDestroy(): void|Called when the ability is destroyed.|
+|onWindowStageCreate(windowStage: window.WindowStage): void|Called when a **WindowStage** is created for the ability. You can use the **window.WindowStage** APIs to implement operations such as page loading.|
+|onWindowStageDestroy(): void|Called when the **WindowStage** is destroyed for the ability.|
+|onForeground(): void|Called when the ability is switched to the foreground.|
+|onBackground(): void|Called when the ability is switched to the background.|
+|onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void|Called when the ability launch type is set to **singleton**.|
+|onConfigurationUpdated(config: Configuration): void|Called when the configuration of the environment where the ability is running is updated.|
+### Implementing AbilityStage and Ability Lifecycle Callbacks
+To create Page abilities for an application in the stage model, you must implement the **AbilityStage** class and ability lifecycle callbacks, and use the **Window** class to set the pages. The sample code is as follows:
+1. Import the **AbilityStage** module.
+ ```
+ import AbilityStage from "@ohos.application.AbilityStage"
+ ```
+2. Implement the **AbilityStage** class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**.
+ ```ts
+ export default class MyAbilityStage extends AbilityStage {
+ onCreate() {
+ console.log("MyAbilityStage onCreate")
+ }
+ }
+ ```
+3. Import the **Ability** module.
+ ```js
+ import Ability from '@ohos.application.Ability'
+ ```
+4. Implement the lifecycle callbacks of the **Ability** class. The default relative path generated by the APIs is **entry\src\main\ets\MainAbility\MainAbility.ts**.
+
+ In the **onWindowStageCreate(windowStage)** API, use **loadContent** to set the application page to be loaded. For details about how to use the **Window** APIs, see [Window Development](../windowmanager/application-window-stage.md).
+ ```ts
+ export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log("MainAbility onCreate")
+ }
+
+ onDestroy() {
+ console.log("MainAbility onDestroy")
+ }
+
+ onWindowStageCreate(windowStage) {
+ console.log("MainAbility onWindowStageCreate")
+
+ windowStage.loadContent("pages/index").then(() => {
+ console.log("MainAbility load content succeed")
+ }).catch((error) => {
+ console.error("MainAbility load content failed with error: " + JSON.stringify(error))
+ })
+ }
+
+ onWindowStageDestroy() {
+ console.log("MainAbility onWindowStageDestroy")
+ }
+
+ onForeground() {
+ console.log("MainAbility onForeground")
+ }
+
+ onBackground() {
+ console.log("MainAbility onBackground")
+ }
+ }
+ ```
+### Obtaining AbilityStage and Ability Configurations
+Both the **AbilityStage** and **Ability** classes have the **context** attribute. An application can obtain the context of an **Ability** instance through **this.context** to obtain the configuration details.
+
+The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **AbilityStage** class. The sample code is as follows:
+
+```ts
+import AbilityStage from "@ohos.application.AbilityStage"
+export default class MyAbilityStage extends AbilityStage {
+ onCreate() {
+ console.log("MyAbilityStage onCreate")
+ let context = this.context
+ console.log("MyAbilityStage bundleCodeDir" + context.bundleCodeDir)
+
+ let currentHapModuleInfo = context.currentHapModuleInfo
+ console.log("MyAbilityStage hap module name" + currentHapModuleInfo.name)
+ console.log("MyAbilityStage hap module mainAbilityName" + currentHapModuleInfo.mainAbilityName)
+
+ let config = this.context.config
+ console.log("MyAbilityStage config language" + config.language)
+ }
+}
+```
+
+The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **Ability** class. The sample code is as follows:
+```ts
+import Ability from '@ohos.application.Ability'
+export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log("MainAbility onCreate")
+ let context = this.context
+ console.log("MainAbility bundleCodeDir" + context.bundleCodeDir)
+
+ let abilityInfo = this.context.abilityInfo;
+ console.log("MainAbility ability bundleName" + abilityInfo.bundleName)
+ console.log("MainAbility ability name" + abilityInfo.name)
+
+ let config = this.context.config
+ console.log("MainAbility config language" + config.language)
+ }
+}
+```
+### Requesting Permissions
+If an application needs to obtain user privacy information or use system capabilities, for example, obtaining location information or using the camera to take photos or record videos, it must request the respective permission from consumers. During application development, you need to specify the involved sensitive permissions, declare the required permissions in **module.json5**, and use the **requestPermissionsFromUser** API to request the permission from consumers in the form of a dialog box. The following uses the permission for calendar access as an example.
+
+Declare the required permission in the **module.json5** file.
+```json
+"requestPermissions": [
+ {
+ "name": "ohos.permission.READ_CALENDAR"
+ }
+]
+```
+Request the permission from consumers in the form of a dialog box:
+```ts
+let context = this.context
+let permissions: Array = ['ohos.permission.READ_CALENDAR']
+context.requestPermissionsFromUser(permissions).then((data) => {
+ console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
+}).catch((error) => {
+ console.log("Failed to request permission from user with error: " + JSON.stringify(error))
+})
+```
+### Notifying of Environment Changes
+Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single **Ability** instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. For details on the configuration, see [Configuration](../reference/apis/js-apis-configuration.md).
+
+For an application in the stage model, when the configuration changes, its abilities are not restarted, but the **onConfigurationUpdated(config: Configuration)** callback is triggered. If the application needs to perform processing based on the change, you can overwrite **onConfigurationUpdated**. Note that the **Configuration** object in the callback contains all the configurations of the current ability, not only the changed configurations.
+
+The following example shows the implementation of the **onConfigurationUpdated** callback in the **AbilityStage** class. The callback is triggered when the system language and color mode are changed.
+```ts
+import AbilityStage from '@ohos.application.AbilityStage'
+import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
+
+export default class MyAbilityStage extends AbilityStage {
+ onConfigurationUpdated(config) {
+ if (config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
+ console.log('colorMode changed to dark')
+ }
+ }
+}
+```
+
+The following example shows the implementation of the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change.
+```ts
+import Ability from '@ohos.application.Ability'
+import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
+
+export default class MainAbility extends Ability {
+ direction : number;
+
+ onCreate(want, launchParam) {
+ this.direction = this.context.config.direction
+ }
+
+ onConfigurationUpdated(config) {
+ if (this.direction !== config.direction) {
+ console.log(`direction changed to ${config.direction}`)
+ }
+ }
+}
+```
+## Starting an Ability
+### Available APIs
+The **Ability** class has the **context** attribute, which belongs to the **AbilityContext** class. The **AbilityContext** class has the **abilityInfo**, **currentHapModuleInfo**, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md).
+
+**Table 3** AbilityContext APIs
+|API|Description|
+|:------|:------|
+|startAbility(want: Want, callback: AsyncCallback\): void|Starts an ability.|
+|startAbility(want: Want, options?: StartOptions): Promise\|Starts an ability.|
+|startAbilityWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the account ID.|
+|startAbilityWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the account ID.|
+|startAbilityForResult(want: Want, callback: AsyncCallback\): void|Starts an ability with the returned result.|
+|startAbilityForResult(want: Want, options?: StartOptions): Promise\|Starts an ability with the returned result.|
+|startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the execution result and account ID.|
+|startAbilityForResultWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the execution result and account ID.|
+### Starting an Ability on the Same Device
+An application can obtain the context of an **Ability** instance through **this.context** and then use the **startAbility** API in the **AbilityContext** class to start the ability. The ability can be started by specifying **Want**, **StartOptions**, and **accountId**, and the operation result can be returned using a callback or **Promise** instance. The sample code is as follows:
+```ts
+let context = this.context
+var want = {
+ "deviceId": "",
+ "bundleName": "com.example.MyApplication",
+ "abilityName": "MainAbility"
+};
+context.startAbility(want).then(() => {
+ console.log("Succeed to start ability")
+}).catch((error) => {
+ console.error("Failed to start ability with error: "+ JSON.stringify(error))
+})
+```
+
+### Starting an Ability on a Remote Device
+>This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications.
+In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows:
+```ts
+let context = this.context
+var want = {
+ "deviceId": getRemoteDeviceId(),
+ "bundleName": "com.example.MyApplication",
+ "abilityName": "MainAbility"
+};
+context.startAbility(want).then(() => {
+ console.log("Succeed to start remote ability")
+}).catch((error) => {
+ console.error("Failed to start remote ability with error: " + JSON.stringify(error))
+})
+```
+Obtain the ID of a specified device from **DeviceManager**. The sample code is as follows:
+```ts
+import deviceManager from '@ohos.distributedHardware.deviceManager';
+function getRemoteDeviceId() {
+ if (typeof dmClass === 'object' && dmClass != null) {
+ var list = dmClass.getTrustedDeviceListSync();
+ if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
+ return;
+ }
+ console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
+ return list[0].deviceId;
+ } else {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
+ }
+}
+```
+Request the permission **ohos.permission.DISTRIBUTED_DATASYNC** from consumers. This permission is used for data synchronization. For details about the sample code for requesting the permission, see [Requesting Permissions](#requesting-permissions).
+### Starting an Ability with the Specified Page
+If the launch type of an ability is set to **singleton** and the ability has been started, the **onNewWant** callback is triggered when the ability is started again. You can pass start options through the **want**. For example, to start an ability with the specified page, use the **uri** or **parameters** parameter in the **want** to pass the page information. Currently, the ability in the stage model cannot directly use the **router** capability. You must pass the start options to the custom component and invoke the **router** method to display the specified page during the custom component lifecycle management. The sample code is as follows:
+
+When using **startAbility** to start an ability again, use the **uri** parameter in the **want** to pass the page information.
+```ts
+async function reStartAbility() {
+ try {
+ await this.context.startAbility({
+ bundleName: "com.sample.MyApplication",
+ abilityName: "MainAbility",
+ uri: "pages/second"
+ })
+ console.log('start ability succeed')
+ } catch (error) {
+ console.error(`start ability failed with ${error.code}`)
+ }
+}
+```
+
+Obtain the **want** parameter that contains the page information from the **onNewWant** callback of the ability.
+```ts
+import Ability from '@ohos.application.Ability'
+
+export default class MainAbility extends Ability {
+ onNewWant(want, launchParams) {
+ globalThis.newWant = want
+ }
+}
+```
+
+Obtain the **want** parameter that contains the page information from the custom component and process the route based on the URI.
+```ts
+import router from '@ohos.router'
+
+@Entry
+@Component
+struct Index {
+ newWant = undefined
+
+ onPageShow() {
+ console.info('Index onPageShow')
+ let newWant = globalThis.newWant
+ if (newWant.hasOwnProperty("uri")) {
+ router.push({ url: newWant.uri });
+ globalThis.newWant = undefined
+ }
+ }
+}
+```
+
+
\ No newline at end of file
diff --git a/en/application-dev/ability-deprecated/stage-brief.md b/en/application-dev/ability-deprecated/stage-brief.md
new file mode 100644
index 0000000000000000000000000000000000000000..2d5474e2c2f0e8328add287481b5ea47abcb2725
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-brief.md
@@ -0,0 +1,114 @@
+# Stage Model Overview
+
+## Design Ideas
+
+The stage model is designed to provide a better application development mode in the distributed environment.
+
+The following figure shows the design ideas of the stage model.
+
+
+
+The stage model is designed based on the following considerations:
+
+- Efficient management of application processes
+
+As the device memory becomes larger, the number of processes concurrently running in the system increases. If the number of concurrent processes reaches several hundreds, the overall power consumption and performance of the system will be adversely affected without effective management measures. To restrict the behavior of background processes, the stage model uses four measures: transient task, continuous task, agent task, and Work Scheduler task. With these measures, foreground processes will obtain guaranteed resources, thereby delivering a better user experience.
+
+- Native support for cross-device migration and multi-device collaboration
+
+OpenHarmony is a native distributed OS. Its application framework must be designed for easier component migration and collaboration across devices. The stage model achieves this design objective by providing features such as separation between ability and UI as well as integration of UI display and service capabilities.
+
+- Different window forms for various device types
+
+The stage model redefines the ability lifecycle. In terms of architecture, the component manager and window manager are decoupled. This facilitates adaptation between window forms and device types.
+
+## Basic Concepts
+
+The following figure shows the basic concepts in the stage model.
+
+
+
+- **HAP**: basic unit for building, distributing, and loading OpenHarmony applications. Each HAP corresponds to a module in the development state. In an application, **moduleName** uniquely identifies a module.
+- **Bundle**: an OpenHarmony application identified by **appid**. A bundle can contain multiple HAP files. Each application has a **bundleName**. However, **bundleName** must be used together with **appid** and other information to uniquely identify an application.
+- **AbilityStage**: runtime object of an HAP. It is created when the HAP is loaded to the process for the first time and is visible to developers in the runtime.
+- **Application**: runtime object of a bundle. It is invisible to developers in the runtime.
+- **Context**: base class that provides APIs in the runtime to obtain information such as the bundle name, module name, and path. The **Context** classes of the Ability and ExtensionAbility components inherit from this class.
+- **Ability**: provides lifecycle callbacks, holds the ability context, and supports cross-device component migration and multi-device collaboration.
+- **ExtensionAbility**: general name of scenario-based Extension abilities. The system defines multiple scenario-based **ExtensionAbility** classes, each of which has its own **ExtensionContext**.
+- **WindowStage**: local window manager.
+- **Window**: application window, which holds an ArkUI engine instance.
+- **ArkUI Page**: UI developed based on ArkUI.
+
+
+## Lifecycle
+
+The ability and ability stage are key objects in the application lifecycle.
+
+For details about the lifecycle differences between the stage model and FA model, see [Ability Framework Overview](ability-brief.md). This section focuses on the ability lifecycle transition and the scheduling relationships between the ability, ability stage, and window stage.
+
+
+
+To implement device adaptation and multi-window scalability, OpenHarmony decouples the component manager from the window manager.
+
+The ability lifecycle defined in the stage model includes only the creation, destruction, foreground, and background states. The gain focus and lose focus states that are closely related to UI are defined in the window stage. This implements weak coupling between the abilities and windows. On the service side, the window manager notifies the component manager of the foreground and background state changes, so the component manager only senses the foreground and background state changes but not the focus changes.
+
+There are two lifecycle states related to the window stage in **Ability**: **onWindowStageCreate** and **onWindowStageDestroy**. They are valid only for devices with the display capability. **onWindowStageCreate** is invoked when a window stage is created, where you can call **loadContent** to set pages to be loaded for the ability. **onWindowStageDestroy** is invoked when the window stage is destroyed, where you can release resources.
+
+
+## Ability Instances and Missions
+
+Abilities can be started in any of the following modes:
+
+* **Singleton**: For each type of ability, only one instance exists in the application process. **Ability1** in the figure below is started in singleton mode.
+* **Standard**: Each time **startAbility** is called, an instance of the specified ability type is created in the application process. **Ability2** in the figure below is started in standard mode.
+* **Specified**: Before creating an **Ability** instance, you can create a key for the instance. Each time **startAbility** is called, the system asks the application which ability instance (corresponding to a key) will be used. **Ability3** in the figure below is started in specified mode.
+
+Each **Ability** instance corresponds to a mission in **Recents**.
+
+The mission corresponding to an ability instance has a snapshot of the ability instance. After the ability instance is destroyed, the ability class information and snapshot are retained in the mission until the user deletes the information or the storage space reaches the upper limit.
+
+ 
+
+## ExtensionAbility Mechanism
+
+Different from the ability used for UI display, ExtensionAbility provides a restricted running environment.
+
+ExtensionAbility has the following features:
+
+- Its process runs independently from the main process but shares the same storage sandbox with the main process. There is no inter-process communication (IPC) between the ExtensionAbility process and the main process.
+
+- It has an independent context that provides scenario-specific APIs.
+
+- It is created by the system, rather than by applications.
+
+- The lifecycles of the ExtensionAbility component and process are managed by the system.
+
+The following figure uses the widget an example. **FormExtensionAbility** is the base class. You can inherit from this class to provide widget information. The lifecycle of the **FormExtensionAbility** instance and that of the ExtensionAbility process where the instance is located are managed by a system service named **FormManagerService**.
+
+
+
+## Process Model
+
+OpenHarmony forces strong control policies on application processes. No APIs are provided to configure multiple processes. All application processes are created and managed by the system.
+
+The processes of an application can be classified into three types:
+
+- Main process: runs the **UIAbility** component, UI, and service logic.
+
+- Extension process: runs classes derived from **ExtensionAbility** in the application. The lifecycle of this process is managed by a scenario-specific system service.
+
+- Render process: created for the WebView and used to load the WebView rendering library.
+
+ The following figure shows the process model of an application.
+
+ 
+
+
+
+## Application Package Structure
+
+For details about the project directory structure of the stage model, see [OpenHarmony Project Overview](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-project-overview-0000001218440650#section56487581904).
+
+For details about how to configure the application package structure of the stage model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-stage.md).
+
+
\ No newline at end of file
diff --git a/en/application-dev/ability-deprecated/stage-call.md b/en/application-dev/ability-deprecated/stage-call.md
new file mode 100644
index 0000000000000000000000000000000000000000..e447dc4fd89f99948ebb379de7010c4db9486488
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-call.md
@@ -0,0 +1,283 @@
+# Ability Call Development
+## When to Use
+Ability call is an extension of the ability capability. It enables an ability to be invoked by and communicate with external systems. The ability invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two abilities (caller ability and callee ability) through inter-process communication (IPC).
+
+The core API used for the ability call is **startAbilityByCall**, which differs from **startAbility** in the following ways:
+ - **startAbilityByCall** supports ability startup in the foreground and background, whereas **startAbility** supports ability startup in the foreground only.
+ - The caller ability can use the **Caller** object returned by **startAbilityByCall** to communicate with the callee ability, but **startAbility** does not provide the communication capability.
+
+Ability call is usually used in the following scenarios:
+- Communicating with the callee ability
+- Starting the callee ability in the background
+
+**Table 1** Terms used in the ability call
+|Term|Description|
+|:------|:------|
+|Caller ability|Ability that triggers the ability call.|
+|Callee ability|Ability invoked by the ability call.|
+|Caller |Object returned by **startAbilityByCall** and used by the caller ability to communicate with the callee ability.|
+|Callee |Object held by the callee ability to communicate with the caller ability.|
+|IPC |Inter-process communication.|
+
+The ability call process is as follows:
+ - The caller ability uses **startAbilityByCall** to obtain a **Caller** object and uses **call()** of the **Caller** object to send data to the callee ability.
+ - The callee ability, which holds a **Callee** object, uses **on()** of the **Callee** object to register a callback. This callback is invoked when the callee ability receives data from the caller ability.
+
+
+> **NOTE**
+> The launch type of the callee ability must be **singleton**.
+> Currently, only system applications can use the ability call.
+
+## Available APIs
+The table below describes the ability call APIs. For details, see [Ability](../reference/apis/js-apis-application-ability.md#caller).
+
+**Table 2** Ability call APIs
+|API|Description|
+|:------|:------|
+|startAbilityByCall(want: Want): Promise\|Starts an ability in the foreground (through the **want** configuration) or background (default) and obtains the **Caller** object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).|
+|on(method: string, callback: CalleeCallBack): void|Callback invoked when the callee ability registers a method.|
+|off(method: string): void|Callback invoked when the callee ability deregisters a method.|
+|call(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability.|
+|callWithResult(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.|
+|release(): void|Releases the **Caller** object.|
+|on(type: "release", callback: OnReleaseCallback): void|Callback invoked when the **Caller** object is released.|
+
+## How to Develop
+The procedure for developing the ability call is as follows:
+1. Create a callee ability.
+
+2. Access the callee ability.
+
+### Creating a Callee Ability
+For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener.
+**1. Configure the ability launch type.**
+
+ Set **launchType** of the callee ability to **singleton** in the **module.json5** file.
+
+|JSON Field|Description|
+|:------|:------|
+|"launchType"|Ability launch type. Set this parameter to **singleton**.|
+
+An example of the ability configuration is as follows:
+```json
+"abilities":[{
+ "name": ".CalleeAbility",
+ "srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
+ "launchType": "singleton",
+ "description": "$string:CalleeAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:CalleeAbility_label",
+ "visible": true
+}]
+```
+**2. Import the Ability module.**
+```ts
+import Ability from '@ohos.app.ability.UIAbility'
+```
+**3. Define the agreed sequenceable data.**
+
+ The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. The code snippet is as follows:
+```ts
+export default class MySequenceable {
+ num: number = 0
+ str: string = ""
+
+ constructor(num, string) {
+ this.num = num
+ this.str = string
+ }
+
+ marshalling(messageParcel) {
+ messageParcel.writeInt(this.num)
+ messageParcel.writeString(this.str)
+ return true
+ }
+
+ unmarshalling(messageParcel) {
+ this.num = messageParcel.readInt()
+ this.str = messageParcel.readString()
+ return true
+ }
+}
+```
+**4. Implement Callee.on and Callee.off.**
+
+ The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the ability and deregistered in **onDestroy**. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The code snippet is as follows:
+```ts
+const TAG: string = '[CalleeAbility]'
+const MSG_SEND_METHOD: string = 'CallSendMsg'
+
+function sendMsgCallback(data) {
+ console.log('CalleeSortFunc called')
+
+ // Obtain the sequenceable data sent by the caller ability.
+ let receivedData = new MySequenceable(0, '')
+ data.readSequenceable(receivedData)
+ console.log(`receiveData[${receivedData.num}, ${receivedData.str}]`)
+
+ // Process the data.
+ // Return the sequenceable data result to the caller ability.
+ return new MySequenceable(receivedData.num + 1, `send ${receivedData.str} succeed`)
+}
+
+export default class CalleeAbility extends Ability {
+ onCreate(want, launchParam) {
+ try {
+ this.callee.on(MSG_SEND_METHOD, sendMsgCallback)
+ } catch (error) {
+ console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
+ }
+ }
+
+ onDestroy() {
+ try {
+ this.callee.off(MSG_SEND_METHOD)
+ } catch (error) {
+ console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`)
+ }
+ }
+}
+```
+
+### Accessing the Callee Ability
+**1. Import the Ability module.**
+```ts
+import Ability from '@ohos.app.ability.UIAbility'
+```
+**2. Obtain the Caller object.**
+
+ The **context** attribute of the ability implements **startAbilityByCall** to obtain the **Caller** object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the **Caller** object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. The code snippet is as follows:
+```ts
+// Register the onRelease listener of the caller ability.
+private regOnRelease(caller) {
+ try {
+ caller.on("release", (msg) => {
+ console.log(`caller onRelease is called ${msg}`)
+ })
+ console.log('caller register OnRelease succeed')
+ } catch (error) {
+ console.log(`caller register OnRelease failed with ${error}`)
+ }
+}
+
+async onButtonGetCaller() {
+ try {
+ this.caller = await context.startAbilityByCall({
+ bundleName: 'com.samples.CallApplication',
+ abilityName: 'CalleeAbility'
+ })
+ if (this.caller === undefined) {
+ console.log('get caller failed')
+ return
+ }
+ console.log('get caller success')
+ this.regOnRelease(this.caller)
+ } catch (error) {
+ console.log(`get caller failed with ${error}`)
+ }
+}
+```
+ In the cross-device scenario, you need to specify the ID of the peer device. The code snippet is as follows:
+```ts
+async onButtonGetRemoteCaller() {
+ var caller = undefined
+ var context = this.context
+
+ context.startAbilityByCall({
+ deviceId: getRemoteDeviceId(),
+ bundleName: 'com.samples.CallApplication',
+ abilityName: 'CalleeAbility'
+ }).then((data) => {
+ if (data != null) {
+ caller = data
+ console.log('get remote caller success')
+ // Register the onRelease listener of the caller ability.
+ caller.on("release", (msg) => {
+ console.log(`remote caller onRelease is called ${msg}`)
+ })
+ console.log('remote caller register OnRelease succeed')
+ }
+ }).catch((error) => {
+ console.error(`get remote caller failed with ${error}`)
+ })
+}
+```
+ Obtain the ID of the peer device from **DeviceManager**. Note that the **getTrustedDeviceListSync** API is open only to system applications. The code snippet is as follows:
+```ts
+import deviceManager from '@ohos.distributedHardware.deviceManager';
+var dmClass;
+function getRemoteDeviceId() {
+ if (typeof dmClass === 'object' && dmClass != null) {
+ var list = dmClass.getTrustedDeviceListSync()
+ if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null")
+ return
+ }
+ console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId)
+ return list[0].deviceId
+ } else {
+ console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null")
+ }
+}
+```
+ In the cross-device scenario, your application must also apply for the data synchronization permission from end users. The code snippet is as follows:
+```ts
+requestPermission() {
+ let context = this.context
+ let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']
+ context.requestPermissionsFromUser(permissions).then((data) => {
+ console.log("Succeed to request permission from user with data: "+ JSON.stringify(data))
+ }).catch((error) => {
+ console.log("Failed to request permission from user with error: "+ JSON.stringify(error))
+ })
+}
+```
+**3. Send agreed sequenceable data.**
+
+ The sequenceable data can be sent to the callee ability with or without a return value. The method and sequenceable data must be consistent with those of the callee ability. The following example describes how to send data to the callee ability. The code snippet is as follows:
+```ts
+const MSG_SEND_METHOD: string = 'CallSendMsg'
+async onButtonCall() {
+ try {
+ let msg = new MySequenceable(1, 'origin_Msg')
+ await this.caller.call(MSG_SEND_METHOD, msg)
+ } catch (error) {
+ console.log(`caller call failed with ${error}`)
+ }
+}
+```
+
+ In the following, **CallWithResult** is used to send data **originMsg** to the callee ability and assign the data processed by the **CallSendMsg** method to **backMsg**. The code snippet is as follows:
+```ts
+const MSG_SEND_METHOD: string = 'CallSendMsg'
+originMsg: string = ''
+backMsg: string = ''
+async onButtonCallWithResult(originMsg, backMsg) {
+ try {
+ let msg = new MySequenceable(1, originMsg)
+ const data = await this.caller.callWithResult(MSG_SEND_METHOD, msg)
+ console.log('caller callWithResult succeed')
+
+ let result = new MySequenceable(0, '')
+ data.readSequenceable(result)
+ backMsg(result.str)
+ console.log(`caller result is [${result.num}, ${result.str}]`)
+ } catch (error) {
+ console.log(`caller callWithResult failed with ${error}`)
+ }
+}
+```
+**4. Release the Caller object.**
+
+ When the **Caller** object is no longer required, use **release()** to release it. The code snippet is as follows:
+```ts
+releaseCall() {
+ try {
+ this.caller.release()
+ this.caller = undefined
+ console.log('caller release succeed')
+ } catch (error) {
+ console.log(`caller release failed with ${error}`)
+ }
+}
+```
diff --git a/en/application-dev/ability-deprecated/stage-formextension.md b/en/application-dev/ability-deprecated/stage-formextension.md
new file mode 100644
index 0000000000000000000000000000000000000000..c45b33732a4f902391eb153c9f5304b071bc4f34
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-formextension.md
@@ -0,0 +1,415 @@
+# Stage Widget Development
+
+## Widget Overview
+
+A widget is a set of UI components used to display important information or operations for an application. It provides users with direct access to a desired application service, without requiring them to open the application.
+
+A widget displays brief information about an application on the UI of another application (host application, currently system applications only) and provides basic interactive functions such as opening a UI page or sending a message.
+
+Basic concepts:
+
+- Widget provider: an atomic service that controls what and how content is displayed in a widget and interacts with users.
+- Widget host: an application that displays the widget content and controls the position where the widget is displayed in the host application.
+- Widget Manager: a resident agent that manages widgets added to the system and provides functions such as periodic widget update.
+
+> **NOTE**
+>
+> The widget host and provider do not keep running all the time. The Widget Manager starts the widget provider to obtain widget information when a widget is added, deleted, or updated.
+
+You only need to develop widget content as the widget provider. The system automatically handles the work done by the widget host and Widget Manager.
+
+The widget provider controls the widget content to display, component layout, and click events bound to components.
+
+## When to Use
+
+Stage widget development refers to the development conducted by the widget provider based on the [stage model](stage-brief.md). As a widget provider, you need to carry out the following operations:
+
+- Develop the lifecycle callbacks in **FormExtension**.
+- Create a **FormBindingData** instance.
+- Update a widget through **FormProvider**.
+- Develop the widget UI page.
+
+## Available APIs
+
+The **FormExtension** class has the following APIs. For details, see [FormExtension](../reference/apis/js-apis-app-form-formExtensionAbility.md).
+
+**Table 1** FormExtension APIs
+
+| API | Description |
+| :----------------------------------------------------------- | :------------------------------------------- |
+| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a **Form** instance (widget) has been created. |
+| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.|
+| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. |
+| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. |
+| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. |
+| onDestroy(formId: string): void | Called to notify the widget provider that a **Form** instance (widget) has been destroyed. |
+| onConfigurationUpdated(config: Configuration): void; | Called when the configuration of the environment where the widget is running is updated. |
+
+The **FormExtension** class also has a member context, that is, the **FormExtensionContext** class. For details, see [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md).
+
+**Table 2** FormExtensionContext APIs
+
+| API | Description |
+| :----------------------------------------------------------- | :----------------------------------------------------------- |
+| startAbility(want: Want, callback: AsyncCallback<void>): void | Starts an ability. This API uses an asynchronous callback to return the result. (This is a system API and cannot be called by third-party applications.)|
+| startAbility(want: Want): Promise<void> | Starts an ability. This API uses a promise to return the result. (This is a system API and cannot be called by third-party applications.)|
+
+For details, see [FormProvider](../reference/apis/js-apis-application-formProvider.md).
+
+**Table 3** FormProvider APIs
+
+| API | Description |
+| :----------------------------------------------------------- | :------------------------------------------------ |
+| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. |
+| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.|
+| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. |
+| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. |
+
+## How to Develop
+
+### Creating a FormExtension Instance
+
+To create a widget in the stage model, implement the lifecycle callbacks of **FormExtension**. The sample code is as follows:
+
+1. Import the required modules.
+
+ ```javascript
+ import FormExtension from '@ohos.application.FormExtension'
+ import formBindingData from '@ohos.application.formBindingData'
+ import formInfo from '@ohos.application.formInfo'
+ import formProvider from '@ohos.application.formProvider'
+ ```
+
+2. Implement the lifecycle callbacks of **FormExtension**.
+
+ ```javascript
+ export default class FormAbility extends FormExtension {
+ onCreate(want) {
+ console.log('FormAbility onCreate');
+ // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
+ let obj = {
+ "title": "titleOnCreate",
+ "detail": "detailOnCreate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ return formData;
+ }
+ onCastToNormal(formId) {
+ // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
+ console.log('FormAbility onCastToNormal');
+ }
+ onUpdate(formId) {
+ // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
+ console.log('FormAbility onUpdate');
+ let obj = {
+ "title": "titleOnUpdate",
+ "detail": "detailOnUpdate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ formProvider.updateForm(formId, formData).catch((error) => {
+ console.log('FormAbility updateForm, error:' + JSON.stringify(error));
+ });
+ }
+ onVisibilityChange(newStatus) {
+ // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification.
+ console.log('FormAbility onVisibilityChange');
+ }
+ onEvent(formId, message) {
+ // If the widget supports event triggering, override this method and implement the trigger.
+ console.log('FormAbility onEvent');
+ }
+ onDestroy(formId) {
+ // Delete widget data.
+ console.log('FormAbility onDestroy');
+ }
+ onConfigurationUpdated(config) {
+ console.log('FormAbility onConfigurationUpdated, config:' + JSON.stringify(config));
+ }
+ }
+ ```
+
+### Configuring the Widget Configuration File
+
+- Configure Extension ability information under **extensionAbilities** in the **module.json5** file. The internal field structure is described as follows:
+
+ | Field | Description | Data Type | Default |
+ | ----------- | ------------------------------------------------------------ | ---------- | -------------------- |
+ | name | Name of the Extension ability. This field must be specified. | String | No |
+ | srcEntrance | Path of the Extension ability lifecycle code. This field must be specified.| String | No |
+ | description | Description of the Extension ability. The value can be a string or a resource index to descriptions in multiple languages.| String | Yes (initial value: left empty)|
+ | icon | Index of the Extension ability icon file. | String | Yes (initial value: left empty)|
+ | label | Descriptive information about the Extension ability presented externally. The value can be a string or a resource index to the description.| String | Yes (initial value: left empty)|
+ | type | Type of the Extension ability. In the current development scenario, set this field to **form**.| String | No |
+ | permissions | Permissions required for abilities of another application to call the current ability. | String array| Yes (initial value: left empty)|
+ | metadata | Metadata (configuration information) of the Extension ability.| Object | Yes (initial value: left empty) |
+
+ For a Form Extension ability, you must specify **metadata**. Specifically, set **name** to **ohos.extension.form** (fixed), and set **resource** to the index of the widget configuration information.
+
+ A configuration example is as follows:
+
+ ```json
+ "extensionAbilities": [{
+ "name": "FormAbility",
+ "srcEntrance": "./ets/FormAbility/FormAbility.ts",
+ "label": "$string:form_FormAbility_label",
+ "description": "$string:form_FormAbility_desc",
+ "type": "form",
+ "metadata": [{
+ "name": "ohos.extension.form",
+ "resource": "$profile:form_config"
+ }]
+ }]
+ ```
+
+- Configure the widget configuration information. **resource** in **metadata** specifies the index of the widget configuration information. For example, **$profile:form_config** means that **form_config.json** in the **resources/base/profile/** directory of the development view is used as the widget profile configuration file.
+
+ The internal field structure is described as follows:
+
+ | Field | Description | Data Type | Default |
+ | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ |
+ | name | Class name of a widget. The value is a string with a maximum of 127 bytes. | String | No |
+ | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) |
+ | src | Full path of the UI code corresponding to the widget. | String | No |
+ | window | Window-related configurations. | Object | Yes |
+ | isDefault | Whether the widget is a default one. Each ability has only one default widget. **true**: The widget is the default one. **false**: The widget is not the default one.| Boolean | No |
+ | colorMode | Color mode of the widget. Available values are as follows: **auto**: The widget adopts the auto-adaptive color mode. **dark**: The widget adopts the dark color mode. **light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)|
+ | supportDimensions | Grid styles supported by the widget. Available values are as follows: **1 * 2**: indicates a grid with one row and two columns. **2 * 2**: indicates a grid with two rows and two columns. **2 * 4**: indicates a grid with two rows and four columns. **4 * 4**: indicates a grid with four rows and four columns.| String array| No |
+ | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No |
+ | updateEnabled | Whether the widget can be updated periodically. Available values are as follows: **true**: The widget can be updated periodically, depending on the update way you select, either at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** is recommended. **false**: The widget cannot be updated periodically.| Boolean | No |
+ | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute. This parameter has a lower priority than **updateDuration**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) |
+ | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes. If the value is **0**, this field does not take effect. If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes. This parameter has a higher priority than **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) |
+ | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) |
+ | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) |
+ | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) |
+
+ A configuration example is as follows:
+
+ ```json
+ {
+ "forms": [{
+ "name": "widget",
+ "description": "This is a widget.",
+ "src": "./js/widget/pages/index/index",
+ "window": {
+ "autoDesignWidth": true,
+ "designWidth": 720
+ },
+ "isDefault": true,
+ "colorMode": "auto",
+ "supportDimensions": ["2*2"],
+ "defaultDimension": "2*2",
+ "updateEnabled": true,
+ "scheduledUpdateTime": "10:30",
+ "formConfigAbility": "ability://ohos.samples.FormApplication.MainAbility"
+ }]
+ }
+ ```
+
+
+### Persistently Storing Widget Data
+
+Mostly, the widget provider is started only when it needs to obtain information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting the widget.
+
+```javascript
+ onCreate(want) {
+ console.log('FormAbility onCreate');
+
+ let formId = want.parameters["ohos.extra.param.key.form_identity"];
+ let formName = want.parameters["ohos.extra.param.key.form_name"];
+ let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
+ // Persistently store widget data for subsequent use, such as widget instance retrieval or update.
+ // The storeFormInfo API is not implemented here.
+ storeFormInfo(formId, formName, tempFlag, want);
+
+ let obj = {
+ "title": "titleOnCreate",
+ "detail": "detailOnCreate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ return formData;
+ }
+```
+
+You should override **onDestroy** to delete widget data.
+
+```javascript
+ onDestroy(formId) {
+ console.log('FormAbility onDestroy');
+
+ // You need to implement the code for deleting the persistent widget data.
+ // The deleteFormInfo API is not implemented here.
+ deleteFormInfo(formId);
+ }
+```
+
+For details about the persistence method, see [Lightweight Data Store Development](../database/database-preference-guidelines.md).
+
+Note that the **Want** passed by the widget host to the widget provider contains a temporary flag, indicating whether the requested widget is a temporary one.
+
+- Normal widget: a widget that will be persistently used by the widget host
+
+- Temporary widget: a widget that is temporarily used by the widget host
+
+Data of a temporary widget is not persistently stored. If it is deleted from the Widget Manager due to exceptions, such as crash of the widget framework, the widget provider will not be notified of which widget is deleted, and still keeps the data. In light of this, the widget provider should implement data clearing. If the widget host successfully converts a temporary widget into a normal one, the widget provider should also process the widget ID and store the data persistently. This prevents the widget provider from deleting the widget data when clearing temporary widgets.
+
+### Updating Widget Data
+
+When a widget application initiates a data update upon a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The sample code is as follows:
+
+```javascript
+onUpdate(formId) {
+ // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
+ console.log('FormAbility onUpdate');
+ let obj = {
+ "title": "titleOnUpdate",
+ "detail": "detailOnUpdate"
+ };
+ let formData = formBindingData.createFormBindingData(obj);
+ // Call the updateForm method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged.
+ formProvider.updateForm(formId, formData).catch((error) => {
+ console.log('FormAbility updateForm, error:' + JSON.stringify(error));
+ });
+}
+```
+
+### Developing the Widget UI Page
+
+You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget.
+
+> **NOTE**
+>
+> Currently, only the JavaScript-based web-like development paradigm can be used to develop the widget UI.
+
+ - In the HML file:
+ ```html
+
+
+
+
+
+
+ {{title}}
+ {{detail}}
+
+
+
+ ```
+
+ - In the CSS file:
+
+ ```css
+.container {
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.bg-img {
+ flex-shrink: 0;
+ height: 100%;
+}
+
+.container-inner {
+ flex-direction: column;
+ justify-content: flex-end;
+ align-items: flex-start;
+ height: 100%;
+ width: 100%;
+ padding: 12px;
+}
+
+.title {
+ font-size: 19px;
+ font-weight: bold;
+ color: white;
+ text-overflow: ellipsis;
+ max-lines: 1;
+}
+
+.detail_text {
+ font-size: 16px;
+ color: white;
+ opacity: 0.66;
+ text-overflow: ellipsis;
+ max-lines: 1;
+ margin-top: 6px;
+}
+ ```
+
+ - In the JSON file:
+ ```json
+ {
+ "data": {
+ "title": "TitleDefault",
+ "detail": "TextDefault"
+ },
+ "actions": {
+ "routerEvent": {
+ "action": "router",
+ "abilityName": "MainAbility",
+ "params": {
+ "message": "add detail"
+ }
+ }
+ }
+ }
+ ```
+
+Now you've got a widget shown below.
+
+
+
+### Developing Widget Events
+
+You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows:
+
+1. Set **onclick** in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
+2. For the router event, set the following attributes:
+ - **action**: **"router"**.
+ - **abilityName**: target ability name, for example, **MainAbility**, which is the default main ability name in DevEco Studio for the stage model.
+ - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the stage model, you can obtain **want** and its **parameters** field.
+3. For the message event, set the following attributes:
+ - **action**: **"message"**.
+ - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**.
+
+The following is an example:
+
+ - In the HML file:
+ ```html
+
+
+
+
+
+
+ {{title}}
+ {{detail}}
+
+
+
+ ```
+
+ - In the JSON file:
+ ```json
+ {
+ "data": {
+ "title": "TitleDefault",
+ "detail": "TextDefault"
+ },
+ "actions": {
+ "routerEvent": {
+ "action": "router",
+ "abilityName": "MainAbility",
+ "params": {
+ "message": "add detail"
+ }
+ },
+ "messageEvent": {
+ "action": "message",
+ "params": {
+ "message": "add detail"
+ }
+ }
+ }
+ }
+ ```
diff --git a/en/application-dev/ability-deprecated/stage-serviceextension.md b/en/application-dev/ability-deprecated/stage-serviceextension.md
new file mode 100644
index 0000000000000000000000000000000000000000..98cae5914f7afa34c916c53f6bb423b590cf5070
--- /dev/null
+++ b/en/application-dev/ability-deprecated/stage-serviceextension.md
@@ -0,0 +1,75 @@
+# Service Extension Ability Development
+
+## When to Use
+`ExtensionAbility` is the base class of the new Extension component in the stage model. It is used to process missions without UIs. The lifecycle of an Extension ability is simple and does not involve foreground or background states. `ServiceExtensionAbility` is extended from `ExtensionAbility`.
+
+You can customize a class that inherits from `ServiceExtensionAbility` and override the lifecycle callbacks in the base class to perform service logic operations during the initialization, connection, and disconnection processes.
+
+## Available APIs
+
+**Table 1** ServiceExtensionAbility lifecycle APIs
+|API|Description|
+|:------|:------|
+|onCreate(want: Want): void|Called for the initialization when `startAbility` or `connectAbility` is invoked for a given ability for the first time.|
+|onRequest(want: Want, startId: number): void|Called each time `startAbility` is invoked for a given ability. The initial value of `startId` is `1`, and the value is incremented by one each time `startAbility` is invoked for that ability.|
+|onConnect(want: Want): rpc.RemoteObject|Called when `connectAbility` is invoked for a given ability. This callback is not invoked for repeated calling of `connectAbility` for a specific ability. However, it will be invoked unless `connectAbility` is called after the ability has been disconnected using `disconnectAbility`. The returned result is a `RemoteObject`.|
+|onDisconnect(want: Want): void|Called when `disconnectAbility` is called for a given ability. If the Extension ability is started by `connectAbility` and is not bound to other applications, the `onDestroy` callback will also be triggered to destroy the Extension ability.|
+|onDestroy(): void|Called when `terminateSelf` is invoked to terminate the ability.|
+
+
+## Constraints
+
+OpenHarmony does not support creation of a Service Extension ability for third-party applications.
+
+
+## How to Develop
+
+1. Declare the Service Extension ability in the `module.json5` file by setting its `type` attribute to `service`. The following is a configuration example of the `module.json5` file:
+
+
+ ```json
+ "extensionAbilities":[{
+ "name": "ServiceExtAbility",
+ "icon": "$media:icon",
+ "description": "service",
+ "type": "service",
+ "visible": true,
+ "srcEntrance": "./ets/ServiceExtAbility/ServiceExtAbility.ts"
+ }]
+ ```
+
+
+2. Customize a class that inherits from `ServiceExtensionAbility` in the .ts file in the directory where the Service Extension ability is defined (`entry\src\main\ets\ServiceExtAbility\ServiceExtAbility.ts` by default) and override the lifecycle callbacks of the base class. The code sample is as follows:
+
+ ```js
+ import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility'
+ import rpc from '@ohos.rpc'
+
+ class StubTest extends rpc.RemoteObject {
+ constructor(des) {
+ super(des);
+ }
+ onRemoteRequest(code, data, reply, option) {
+ }
+ }
+
+ class ServiceExtAbility extends ServiceExtensionAbility {
+ onCreate(want) {
+ console.log('onCreate, want:' + want.abilityName);
+ }
+ onRequest(want, startId) {
+ console.log('onRequest, want:' + want.abilityName);
+ }
+ onConnect(want) {
+ console.log('onConnect , want:' + want.abilityName);
+ return new StubTest("test");
+ }
+ onDisconnect(want) {
+ console.log('onDisconnect, want:' + want.abilityName);
+ }
+ onDestroy() {
+ console.log('onDestroy');
+ }
+ }
+ ```
+
diff --git a/en/application-dev/ability-deprecated/wantagent.md b/en/application-dev/ability-deprecated/wantagent.md
new file mode 100644
index 0000000000000000000000000000000000000000..4b1854d1a54a36f864b3dd4215040eb24db2e5f3
--- /dev/null
+++ b/en/application-dev/ability-deprecated/wantagent.md
@@ -0,0 +1,86 @@
+# WantAgent Development
+## When to Use
+The **WantAgent** class encapsulates want information that specifies a particular action, which can be starting an ability or publishing a common event. You can either call **wantAgent.trigger** to trigger a **WantAgent** directly or add a **WantAgent** to a notification so that it will be triggered when users tap the notification.
+
+## Available APIs
+| API | Description|
+| ---------------------------------------------------------------------------------------------- | ----------- |
+| getWantAgentInfo(info: WantAgentInfo, callback: AsyncCallback\) | Creates a **WantAgent** object. This API uses an asynchronous callback to return the result.|
+| getWantAgent(info: WantAgentInfo): Promise\ | Creates a **WantAgent** object. This API uses a promise to return the result.|
+| trigger(agent: WantAgent, triggerInfo: TriggerInfo, callback?: Callback\) | Triggers a **WantAgent** object.|
+
+## How to Develop
+1. Import the **WantAgent** module.
+
+ ```
+ import wantAgent from '@ohos.wantAgent';
+ ```
+
+2. Create a **WantAgentInfo** object that will be used for starting an ability. For details about the data types and parameters of **WantAgentInfo**, see [WantAgent](../reference/apis/js-apis-wantAgent.md#wantagentinfo).
+
+ ```
+ private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
+
+ // wantAgentInfo
+ var wantAgentInfo = {
+ wants: [
+ {
+ deviceId: "",
+ bundleName: "com.example.test",
+ abilityName: "com.example.test.MainAbility",
+ action: "",
+ entities: [],
+ uri: "",
+ parameters: {}
+ }
+ ],
+ operationType: wantAgent.OperationType.START_ABILITY,
+ requestCode: 0,
+ wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
+ }
+ ```
+
+3. Create a **WantAgentInfo** object for publishing a common event.
+
+ ```
+ private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
+
+ // wantAgentInfo
+ var wantAgentInfo = {
+ wants: [
+ {
+ action: "event_name", // Set the action name.
+ parameters: {}
+ }
+ ],
+ operationType: wantAgent.OperationType.SEND_COMMON_EVENT,
+ requestCode: 0,
+ wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
+ }
+ ```
+
+4. Create a **WantAgent** object and save the returned **wantAgentObj** for subsequent trigger operations.
+
+ ```
+ // Create a WantAgent object.
+ wantAgent.getWantAgent(wantAgentInfo, (err, wantAgentObj) => {
+ if (err.code) {
+ console.error("[WantAgent]getWantAgent err=" + JSON.stringify(err))
+ } else {
+ console.log("[WantAgent]getWantAgent success")
+ this.wantAgentObj = wantAgentObj
+ }
+ })
+ ```
+
+5. Trigger the **WantAgent** object.
+
+ ```
+ // Trigger the WantAgent object.
+ var triggerInfo = {
+ code:0
+ }
+ wantAgent.trigger(wantAgentObj, triggerInfo, (completeData) => {
+ console.log("[WantAgent]getWantAgent success, completeData: ", + JSON.stringify(completeData))
+ })
+ ```
diff --git a/en/application-dev/ability/Readme-EN.md b/en/application-dev/ability/Readme-EN.md
deleted file mode 100644
index 0589643e0f9426f76ac25d3616a41c3b54910e2a..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/Readme-EN.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Ability Development
-- [Ability Framework Overview](ability-brief.md)
-- [Context Usage](context-userguide.md)
-- FA Model
- - [FA Model Overview](fa-brief.md)
- - [Page Ability Development](fa-pageability.md)
- - [Service Ability Development](fa-serviceability.md)
- - [Data Ability Development](fa-dataability.md)
- - [FA Widget Development](fa-formability.md)
-- Stage Model
- - [Stage Model Overview](stage-brief.md)
- - [Ability Development](stage-ability.md)
- - [Service Extension Ability Development](stage-serviceextension.md)
- - [Ability Continuation Development](stage-ability-continuation.md)
- - [Ability Call Development](stage-call.md)
- - [Stage Widget Development](stage-formextension.md)
-- Other
- - [WantAgent Development](wantagent.md)
- - [Ability Assistant Usage](ability-assistant-guidelines.md)
- - [ContinuationManager Development](continuationmanager.md)
- - [Test Framework Usage](ability-delegator.md)
-
-
diff --git a/en/application-dev/ability/ability-assistant-guidelines.md b/en/application-dev/ability/ability-assistant-guidelines.md
deleted file mode 100644
index 4d7b0edb2b91ca07123ad7495f4d64fc2f525e1d..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/ability-assistant-guidelines.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Ability Assistant Usage
-
-The ability assistant enables you to start applications, atomic services, and test cases and debug applications. By using this tool, you can send commands in the hdc shell to perform various system operations, such as starting abilities, forcibly stopping processes, and printing ability information.
-
-## Query-related Commands
-
-- **help**
-
- Displays help information for the ability assistant.
-
- **Return value**
-
- Returns the help information.
-
- **Method**
-
- ```
- aa help
- ```
-
-## Ability-related Commands
-
-- **start**
-
- Starts an ability.
-
- | Name | Description |
- | --------- | -------------------------- |
- | -h/--help | Help information. |
- | -d | Device ID. This parameter is optional. |
- | -a | Ability name. This parameter is mandatory.|
- | -b | Bundle name. This parameter is mandatory. |
- | -D | Debugging mode. This parameter is optional. |
-
- **Return value**
-
- Returns "start ability successfully." if the ability is started; returns "error: failed to start ability." otherwise.
-
- **Method**
-
- ```
- aa start [-d ] -a -b [-D]
- ```
-
-- **stop-service**
-
- Stops a Service ability.
-
- | Name | Description |
- | --------- | ------------------------ |
- | -h/--help | Help information. |
- | -d | Device ID. This parameter is optional. |
- | -a | Ability name. This parameter is mandatory.|
- | -b | Bundle name. This parameter is mandatory. |
-
- **Return value**
-
- Returns "stop service ability successfully." if the Service ability is stopped; returns "error: failed to stop service ability." otherwise.
-
- **Method**
-
- ```
- aa stop-service [-d ] -a -b
- ```
-
-- **dump**
-
- Prints ability-related information.
-
- | Name | Level-2 Parameter | Description |
- | ----------------- | -------------------- | ------------------------------------------------------------ |
- | -h/--help | - | Prints help information. |
- | -a/--all | - | Prints ability information in all missions. |
- | -l/--mission-list | type (All logs are printed if this parameter is left unspecified.)| Prints mission stack information. The following values are available for **type**: - NORMAL - DEFAULT_STANDARD - DEFAULT_SINGLE - LAUNCHER |
- | -e/--extension | elementName | Prints extended component information. |
- | -u/--userId | UserId | Prints stack information of a specified user ID. This parameter must be used together with other parameters. Example commands: aa **dump -a -u 100** and **aa dump -d -u 100**. |
- | -d/--data | - | Prints Data ability information. |
- | -i/--ability | AbilityRecord ID | Prints detailed information about a specified ability. |
- | -c/--client | - | Prints detailed ability information. This parameter must be used together with other parameters. Example commands: **aa dump -a -c** and **aa dump -i 21 -c**. |
-
- **Method**
-
- ```
- aa dump -a
- ```
- 
- ```
- aa dump -l
- ```
- 
- ```
- aa dump -i 12
- ```
- 
-- **force-stop**
-
- Forcibly stops a process based on the bundle name.
-
- **Return value**
-
- Returns "force stop process successfully." if the process is forcibly stopped; returns "error: failed to force stop process." otherwise.
-
- **Method**
-
- ```
- aa force-stop
- ```
diff --git a/en/application-dev/ability/ability-brief.md b/en/application-dev/ability/ability-brief.md
deleted file mode 100644
index 0d2303bf4f84c2ddc6f34a13d28b02a3762893b0..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/ability-brief.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Ability Framework Overview
-
-An ability is the abstraction of a functionality that an application can provide. It is the minimum unit for the system to schedule applications. An application can contain one or more `Ability` instances.
-
-The ability framework model has two forms:
-
-- FA model, which applies to application development using API version 8 and earlier versions. In the FA model, there is Feature Ability (FA) and Particle Ability (PA). The FA supports Page abilities, and the PA supports Service, Data, and Form abilities.
-- Stage model, which is introduced since API version 9. In the stage model, there is `Ability` and `ExtensionAbility`. `ExtensionAbility` is further extended to `ServiceExtensionAbility`, `FormExtensionAbility`, `DataShareExtensionAbility`, and more.
-
-The stage model is designed to make it easier to develop complex applications in the distributed environment. The table below lists the design differences between the two models.
-
-| Item | FA Model | Stage Model |
-| -------------- | ------------------------------------------------------------ | -------------------------------------------------------- |
-| Development mode | Web-like APIs are provided. The UI development is the same as that of the stage model. | Object-oriented development mode is provided. The UI development is the same as that of the FA model. |
-| Engine instance | Each ability in a process exclusively uses a JS VM engine instance. | Multiple abilities in a process share one JS VM engine instance. |
-| Intra-process object sharing| Not supported. | Supported. |
-| Bundle description file | The `config.json` file is used to describe the HAP and component information. Each component must use a fixed file name.| The `module.json5` file is used to describe the HAP and component information. The entry file name can be specified.|
-| Component | Four types of components are provided: Page ability (used for UI page display), Service ability (used to provide services), Data ability (used for data sharing), and Form ability (used to provide widgets).| Two types of components are provided: Ability (used for UI page display) and Extension (scenario-based service extension). |
-
-In addition, the following differences exist in the development process:
-
-* Different ability types
-
- 
-
-* Different ability lifecycles
-
- 
-
-For details about the two models, see [FA Model Overview](fa-brief.md) and [Stage Model Overview](stage-brief.md).
diff --git a/en/application-dev/ability/ability-delegator.md b/en/application-dev/ability/ability-delegator.md
deleted file mode 100644
index 5fd0293efde6d6d264be28b6c30123e7697bee6b..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/ability-delegator.md
+++ /dev/null
@@ -1,181 +0,0 @@
-# Test Framework Usage
-
-## Overview
-The delegator test framework provides a self-test environment for OpenHarmony applications. Using this framework, you can start an ability, schedule its lifecycle, listen for its state changes, run a shell command, and print the test result.
-
-## Constraints
-
-The APIs provided by the test framework can be used only in the test HAP. They take effect only after the test framework is started.
-
-
-## Starting the Test Framework
-
-The test framework can be started in either of the following ways:
-
-- Method 1: Run the `aa test` command.
-- Method 2: Use DevEco Studio.
-
-### Running aa test
-
-To start the test framework, specify the **TestRunner** and the package name or module name of the HAP where the **TestRunner** is located.
-
-An example command in the FA model is as follows:
-
-```javascript
-aa test -b BundleName -p com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
-```
-
-An example command in the stage model is as follows:
-```javascript
-aa test -b BundleName -m com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20
-```
-| Parameter | Mandatory| Description |
-| --------------- | -------- | ------------------------------------------------------------ |
-| -b | Yes | Bundle name of the HAP where the **TestRunner** is located. |
-| -p | Yes | Package name of the HAP where the **TestRunner** is located. This parameter is used by the FA model. |
-| -m | Yes | Module name of the HAP where the **TestRunner** is located. This parameter is used by the stage model. |
-| -s unittest | Yes | Name of the **TestRunner** to be used. The TestRunner name must be the same as the file name. |
-| -w | No | Timeout interval of a test case, in seconds. If this parameter is not specified or is set to a value less than or equal to **0**, the test framework exits only after **finishTest** is invoked.|
-| -s \\ | No | **-s** can be followed by any key-value pair obtained through **AbilityDelegatorArgs.parameters**. For example, in **-s classname myTest**, **-s classname** is the key and **myTest** is the value.|
-| -D | No | Debug mode for starting the tested application.|
-| -h | No | Help information.|
-
-### Using DevEco Studio
-
-For details about how to use DevEco Studio to start the test framework, see [OpenHarmony Test Framework](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453#section1034420367508).
-
-## Introduction to TestRunner
-
-**TestRunner** is the entry class of the test framework test process. When the test process is started, the system calls related APIs in **TestRunner**. You need to inherit this class and override the **onPrepare** and **onRun** APIs. When creating an application template, DevEco Studio initializes the default **TestRunner** and starts the default **TestAbility** in the **onRun** API. You can modify the test code of **TestAbility** or override **onPrepare** and **onRun** in **TestRunner** to implement your own test code. For details, see [TestRunner](../reference/apis/js-apis-testRunner.md).
-
-## Introduction to AbilityDelegatorRegistry
-
-**AbilityDelegatorRegistry** is the **AbilityDelegator** repository class provided by the test framework. You can use **AbilityDelegatorRegistry** to obtain an **AbilityDelegator** instance and the input and generated parameters **AbilityDelegatorArgs** during the test. You can use **AbilityDelegator** to invoke the function set provided by the test framework for testing and verification. For details, see [AbilityDelegatorRegistry](../reference/apis/js-apis-abilityDelegatorRegistry.md).
-
-## Introduction to AbilityDelegatorArgs
-
-**AbilityDelegatorArgs** is a test parameter class provided by the test framework. You can use **AbilityDelegatorArgs** to obtain the parameters passed and generated during the test. For details, see [AbilityDelegatorArgs](../reference/apis/js-apis-application-abilityDelegatorArgs.md).
-
-## Introduction to AbilityMonitor
-
-**AbilityMonitor** is provided by the test framework for binding to and listening for abilities. You can use **AbilityMonitor** to bind to an **Ability** instance and add **AbilityMonitor** to the listening list. When **AbilityMonitor** is bound to an ability, the creation and lifecycle changes of the ability will trigger the related callback in **AbilityMonitor**. You can test and verify the ability in these callbacks. For details, see [AbilityMonitor](../reference/apis/js-apis-application-abilityMonitor.md).
-
-**Example**
-
-```javascript
-import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
-
-function onAbilityCreateCallback(data) {
- console.info("onAbilityCreateCallback");
-}
-
-var monitor = {
- abilityName: "abilityname",
- onAbilityCreate: onAbilityCreateCallback
-}
-
-var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
-abilityDelegator.addAbilityMonitor(monitor).then(() => {
- console.info("addAbilityMonitor promise");
-});
-```
-
-## Introduction to AbilityDelegator
-
-**AbilityDelegator** is a main function class of the test framework. It provides the functions of starting an ability, obtaining an **Ability** instance, scheduling the ability lifecycle, listening for the ability state, and printing test results.
-
-**Modules to Import**
-
-```javascript
-import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
-```
-
-```javascript
-var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
-```
-
-### Starting an Ability and Listening for the Ability State
-
-Use **AbilityDelegator** and **AbilityMonitor** to start an ability, obtain an **Ability** instance, and listen for the ability state.
-
-**Example**
-
-```javascript
-var abilityDelegator;
-var ability;
-var timeout = 100;
-
-function onAbilityCreateCallback(data) {
- console.info("onAbilityCreateCallback");
-}
-
-var monitor = {
- abilityName: "abilityname",
- onAbilityCreate: onAbilityCreateCallback
-}
-
-abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
-abilityDelegator.waitAbilityMonitor(monitor, timeout, (err, data) => {
- ability = data;
- console.info("waitAbilityMonitor callback");
-});
-
-var want = {
- bundleName: "bundleName",
- abilityName: "abilityName"
-};
-abilityDelegator.startAbility(want, (err, data) => {
- console.info("startAbility callback");
-});
-```
-
-### Scheduling the Ability Lifecycle
-
-**AbilityDelegator** provides APIs to display and schedule the ability lifecycle and supports the foreground and background. It works with **AbilityMonitor** to listen for the ability lifecycle. For details, see [AbilityDelegator](../reference/apis/js-apis-application-abilityDelegator.md).
-
-### Running a Shell Command
-
-**AbilityDelegator** provides APIs to run shell commands in the test environment.
-
-**Example**
-
-```javascript
-var abilityDelegator;
-var cmd = "cmd";
-abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
-abilityDelegator.executeShellCommand(cmd, (err, data) => {
- console.info("executeShellCommand callback");
-});
-```
-
-### Printing Log Information
-
-**AbilityDelegator** provides APIs for printing log information. You can call any API in the test code to print process logs to the unit test console.
-
-**Example**
-
-```javascript
-var abilityDelegator;
-var msg = "msg";
-
-abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
-abilityDelegator.print(msg, (err) => {
- console.info("print callback");
-});
-```
-
-### Finishing the Test and Printing Log Information
-
-**AbilityDelegator** provides the APIs for actively finishing the test. You can call any API in test code to finish the test and print logs to the unit test console.
-
-**Example**
-
-```javascript
-var abilityDelegator;
-var msg = "msg";
-
-abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
-abilityDelegator.finishTest(msg, 0, (err) => {
- console.info("finishTest callback");
-});
-```
diff --git a/en/application-dev/ability/context-userguide.md b/en/application-dev/ability/context-userguide.md
deleted file mode 100644
index d3e681244166cafecff86575dd1850db4ebf7f90..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/context-userguide.md
+++ /dev/null
@@ -1,312 +0,0 @@
-# Context Usage
-
-## Context Overview
-
-**Context** provides the capability of obtaining contextual information of an application.
-
-The OpenHarmony application framework has two models: Feature Ability (FA) model and stage model. Correspondingly, there are two sets of context mechanisms. **application/BaseContext** is a common context base class. It uses the **stageMode** attribute to specify whether the context is used for the stage model.
-
-- FA model
-
- Only the methods in **app/Context** can be used for the context in the FA model. Both the application-level context and ability-level context are instances of this type. If an ability-level method is invoked in the application-level context, an error occurs. Therefore, you must pay attention to the actual meaning of the **Context** instance.
-
-- Stage model
-
- The stage model has the following types of contexts: **application/Context**, **application/ApplicationContext**, **application/AbilityStageContext**, **application/ExtensionContext**, **application/AbilityContext**, and **application/FormExtensionContext**. For details about these contexts and how to use them, see [Context in the Stage Model](#context-in-the-stage-model).
-
-
-
-## Context in the FA Model
-
-Only the methods in **app/Context** can be used for the context in the FA model.
-
-The FA model has only one context definition. All capabilities in the context are provided through methods. The context uses these methods to extend the capabilities of the FA.
-
-**d.ts statement**
-
-https://gitee.com/openharmony/interface_sdk-js/blob/master/api/app/context.d.ts
-
-**Example**
-
-```javascript
-import featureAbility from '@ohos.ability.featureAbility'
-export default {
- onCreate() {
- // Obtain the context and call related APIs.
- let context = featureAbility.getContext();
- context.getBundleName((data, bundleName)=>{
- console.info("ability bundleName:" + bundleName)
- });
- console.info('Application onCreate')
- },
- onDestroy() {
- console.info('Application onDestroy')
- },
-}
-```
-
-### Common Context-related Methods in the FA Model
-The following context-related methods are available in the FA model:
-```javascript
-setDisplayOrientation(orientation: bundle.DisplayOrientation, callback: AsyncCallback): void
-setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise;
-```
-The methods are used to set the display orientation of the current ability.
-
-**Example**
-```javascript
-import featureAbility from '@ohos.ability.featureAbility'
-import bundle from '../@ohos.bundle';
-
-export default {
- onCreate() {
- // Obtain the context and call related APIs.
- let context = featureAbility.getContext();
- context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => {
- console.log("Set display orientation.")
- })
- console.info('Application onCreate')
- },
- onDestroy() {
- console.info('Application onDestroy')
- },
-}
-```
-
-## Context in the Stage Model
-
-The following describes the contexts provided by the stage model in detail.
-
-### application/Context
-
-**application/Context** is the base class context that provides basic application information such as **resourceManager**, **applicationInfo**, **cacheDir**, and **area**. It also provides basic application methods such as **createBundleContext**.
-
-**d.ts statement**
-
-https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/Context.d.ts
-
-### application/ApplicationContext
-
-**application/ApplicationContext** is an application-level context. In addition to the capabilities provided by the base class context, the application-level context provides **registerAbilityLifecycleCallback** and **unregisterAbilityLifecycleCallback** to monitor the ability lifecycle in a process.
-
-**How to Obtain**
-
-Obtain the context by calling **context.getApplicationContext()** in **Ability**.
-
-**Example**
-
-```javascript
-import AbilityStage from "@ohos.application.AbilityStage";
-
-var lifecycleid;
-
-export default class MyAbilityStage extends AbilityStage {
- onCreate() {
- console.log("MyAbilityStage onCreate")
- let AbilityLifecycleCallback = {
- onAbilityCreate(ability){
- console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability));
- },
- onWindowStageCreate(ability, windowStage){
- console.log("AbilityLifecycleCallback onWindowStageCreate ability:" + JSON.stringify(ability));
- console.log("AbilityLifecycleCallback onWindowStageCreate windowStage:" + JSON.stringify(windowStage));
- },
- onWindowStageActive(ability, windowStage){
- console.log("AbilityLifecycleCallback onWindowStageActive ability:" + JSON.stringify(ability));
- console.log("AbilityLifecycleCallback onWindowStageActive windowStage:" + JSON.stringify(windowStage));
- },
- onWindowStageInactive(ability, windowStage){
- console.log("AbilityLifecycleCallback onWindowStageInactive ability:" + JSON.stringify(ability));
- console.log("AbilityLifecycleCallback onWindowStageInactive windowStage:" + JSON.stringify(windowStage));
- },
- onWindowStageDestroy(ability, windowStage){
- console.log("AbilityLifecycleCallback onWindowStageDestroy ability:" + JSON.stringify(ability));
- console.log("AbilityLifecycleCallback onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));
- },
- onAbilityDestroy(ability){
- console.log("AbilityLifecycleCallback onAbilityDestroy ability:" + JSON.stringify(ability));
- },
- onAbilityForeground(ability){
- console.log("AbilityLifecycleCallback onAbilityForeground ability:" + JSON.stringify(ability));
- },
- onAbilityBackground(ability){
- console.log("AbilityLifecycleCallback onAbilityBackground ability:" + JSON.stringify(ability));
- },
- onAbilityContinue(ability){
- console.log("AbilityLifecycleCallback onAbilityContinue ability:" + JSON.stringify(ability));
- }
- }
- // 1. Obtain applicationContext through the context attribute.
- let applicationContext = this.context.getApplicationContext();
- // 2. Use applicationContext to register and listen for the ability lifecycle in the application.
- lifecycleid = applicationContext.registerAbilityLifecycleCallback(AbilityLifecycleCallback);
- console.log("registerAbilityLifecycleCallback number: " + JSON.stringify(lifecycleid));
- }
- onDestroy() {
- let applicationContext = this.context.getApplicationContext();
- applicationContext.unregisterAbilityLifecycleCallback(lifecycleid, (error, data) => {
- console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error));
- });
- }
-}
-```
-
-**d.ts statement**
-
-https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ApplicationContext.d.ts
-
-### application/AbilityStageContext
-
-**application/AbilityStageContext** is the context for the HAP file. In addition to those provided by the base class **application/Context**, this context contains **HapModuleInfo** and **Configuration**.
-
-**How to Obtain**
-
-Obtain the context from the **context** attribute in **AbilityStage**.
-
-**Example**
-
-```javascript
-export default class MyAbilityStage extends AbilityStage {
- onCreate() {
- // The context attribute is of the AbilityStageContext type.
- console.log('HapModuleInfo is ' + this.context.currentHapModuleInfo);
- }
-}
-```
-
-**d.ts statement**
-
-https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityStageContext.d.ts
-
-### application/AbilityContext
-
-In the stage model, each ability has a context attribute.
-
-**Ability** provides methods to manage the ability lifecycle, and **AbilityContext** provides methods to operate abilities (such as **startAbility** and **connectAbility**).
-
-**How to Obtain**
-
-Obtain the context from the **context** attribute in **Ability**.
-
-**Example**
-
-```javascript
-import Ability from '@ohos.application.Ability'
-
-export default class MainAbility extends Ability {
- onCreate(want, launchParam) {
- console.log("[Demo] MainAbility onCreate")
- globalThis.abilityWant = want;
- }
-
- onDestroy() {
- console.log("[Demo] MainAbility onDestroy")
- }
-
- onWindowStageCreate(windowStage) {
- // Set the main page for this ability when the main window is created.
- console.log("[Demo] MainAbility onWindowStageCreate")
-
- // Obtain AbilityContext and print the ability information.
- let context = this.context;
- console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName)
-
- windowStage.setUIContent(this.context, "pages/index", null)
- }
-
- onWindowStageDestroy() {
- // Release the UI related resources when the main window is destroyed.
- console.log("[Demo] MainAbility onWindowStageDestroy")
- }
-
- onForeground() {
- // The ability is switched to run in the foreground.
- console.log("[Demo] MainAbility onForeground")
- }
-
- onBackground() {
- // The ability is switched to run in the background.
- console.log("[Demo] MainAbility onBackground")
- }
-};
-```
-
-### application/FormExtensionContext
-
-For details, see [FormExtensionContext](../reference/apis/js-apis-formextensioncontext.md).
-
-### Obtaining the Context on an eTS Page
-
-In the stage model, in the `onWindowStageCreate` lifecycle of an ability, you can call `SetUIContent` of `WindowStage` to load an eTS page. In some scenarios, you need to obtain the context on the page to call related APIs.
-
-**How to Obtain**
-
-Use the API described in the table below to obtain the context associated with an eTS page.
-
-| API | Description |
-| :------------------------------------ | :--------------------------- |
-| getContext(component: Object): Object | Obtains the `Context` object associated with a component on the page.|
-
-**Example**
-
-```ts
-// MainAbility.ts
-import Ability from '@ohos.application.Ability'
-
-export default class MainAbility extends Ability {
- onCreate(want, launchParam) {
- console.log("[Demo] MainAbility onCreate")
- }
-
- onDestroy() {
- console.log("[Demo] MainAbility onDestroy")
- }
-
- onWindowStageCreate(windowStage) {
- // Load the index page and pass the current Context object.
- windowStage.setUIContent(this.context, "pages/index", null)
- }
-
- onWindowStageDestroy() {}
-
- onForeground() {}
-
- onBackground() {}
-};
-```
-
-```ts
-// pages/index.ets
-import context from '@ohos.application.context'
-
-type Context = context.Context
-
-@Entry
-@Component
-struct Index {
- build() {
- Row() {
- Column() {
- Text('GetContext')
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- // Obtain the Context object associated with the current component.
- var context : Context = getContext(this) as Context
- console.info("CacheDir:" + context.cacheDir)
- })
- }
- .width('100%')
- }
- .height('100%')
- }
-}
-```
-
-## Common Incorrect Usage
-
-**Error 1: Use globalThis to obtain the context in the stage model.**
-
-**Reason**
-
-In the FA model, each ability instance has a JS VM instance. Therefore, a global ability instance can be obtained from the **global** object of the JS engine. In the stage model, where all the processes of an application share a JS VM instance, there is no global ability instance, and using **globalThis** may cause an error or crash.
diff --git a/en/application-dev/ability/continuationmanager.md b/en/application-dev/ability/continuationmanager.md
deleted file mode 100644
index a1f5a66478cd53aeabe03ed9be21e08596cb2b6b..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/continuationmanager.md
+++ /dev/null
@@ -1,253 +0,0 @@
-# ContinuationManager Development
-
-> **NOTE**
->
-> Currently, the **ContinuationManager** module is not available for application development. Its APIs are mainly used to start the device selection module.
-
-## When to Use
-Users are using two or more devices to experience an all-scenario, multi-device lifestyle. Each type of device has its unique advantages and disadvantages specific to scenarios. The ability continuation capability breaks boundaries of devices and enables multi-device collaboration, achieving precise control, universal coordination, and seamless hops of user applications.
-
-As the entry of the ability continuation capability, **continuationManager** is used to start the device selection module for the user to select the target device. After a device is selected, information about the selected device is returned to the user. The user can then initiate cross-device continuation or collaboration based on the device information.
-
-
-
-## Available APIs
-| API | Description|
-| ---------------------------------------------------------------------------------------------- | ----------- |
-| register(callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API does not involve any filter parameters and uses an asynchronous callback to return the result.|
-| register(options: ContinuationExtraParams, callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API uses an asynchronous callback to return the result.|
-| register(options?: ContinuationExtraParams): Promise\ | Registers the continuation management service and obtains a token. This API uses a promise to return the result.|
-| on(type: "deviceConnect", token: number, callback: Callback\>): void | Subscribes to device connection events. This API uses an asynchronous callback to return the result.|
-| on(type: "deviceDisconnect", token: number, callback: Callback\>): void | Subscribes to device disconnection events. This API uses an asynchronous callback to return the result.|
-| off(type: "deviceConnect", token: number): void | Unsubscribes from device connection events.|
-| off(type: "deviceDisconnect", token: number): void | Unsubscribes from device disconnection events.|
-| startDeviceManager(token: number, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API does not involve any filter parameters and uses an asynchronous callback to return the result.|
-| startDeviceManager(token: number, options: ContinuationExtraParams, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API uses an asynchronous callback to return the result.|
-| startDeviceManager(token: number, options?: ContinuationExtraParams): Promise\ | Starts the device selection module to show the list of available devices. This API uses a promise to return the result.|
-| updateConnectStatus(token: number, deviceId: string, status: DeviceConnectState, callback: AsyncCallback\): void | Instructs the device selection module to update the device connection state. This API uses an asynchronous callback to return the result.|
-| updateConnectStatus(token: number, deviceId: string, status: DeviceConnectState): Promise\ | Instructs the device selection module to update the device connection state. This API uses a promise to return the result.|
-| unregister(token: number, callback: AsyncCallback\): void | Deregisters the continuation management service. This API uses an asynchronous callback to return the result.|
-| unregister(token: number): Promise\ | Deregisters the continuation management service. This API uses a promise to return the result.|
-
-## How to Develop
-1. Import the **continuationManager** module.
-
- ```ts
- import continuationManager from '@ohos.continuation.continuationManager';
- ```
-
-2. Apply for permissions required for cross-device continuation or collaboration operations.
-
- The permission application operation varies according to the ability model in use. In the FA mode, add the required permission in the `config.json` file, as follows:
-
- ```json
- {
- "module": {
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
- }
- }
- ```
-
- This permission must also be granted by the user through a dialog box when the application is started for the first time. The sample code is as follows:
-
- ```ts
- import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
- import bundle from '@ohos.bundle';
-
- async function requestPermission() {
- let permissions: Array = [
- "ohos.permission.DISTRIBUTED_DATASYNC"
- ];
- let needGrantPermission: boolean = false;
- let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
- let applicationInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', 0, 100);
- for (let i = 0; i < permissions.length; i++) {
- let result = await atManager.verifyAccessToken(applicationInfo.accessTokenId, permissions[i]);
- // Check whether the permission is granted.
- if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
- needGrantPermission = true;
- break;
- }
- }
- // If the permission is not granted, call requestPermissionsFromUser to apply for the permission.
- if (needGrantPermission) {
- await featureAbility.getContext().requestPermissionsFromUser(permissions, 1);
- } else {
- console.info('app permission already granted');
- }
- }
- ```
-
- In the stage model, add the required permission in the `module.json5` file. The sample code is as follows:
-
- ```json
- {
- "module": {
- "requestPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
- }
- }
- ```
-
- ```ts
- import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
- import bundle from '@ohos.bundle';
-
- async function requestPermission() {
- let permissions: Array = [
- "ohos.permission.DISTRIBUTED_DATASYNC"
- ];
- let needGrantPermission: boolean = false;
- let atManger: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
- let applicationInfo = await bundle.getApplicationInfo('ohos.samples.continuationmanager', 0, 100);
- for (const permission of permissions) {
- try {
- let grantStatus = await atManger.verifyAccessToken(applicationInfo.accessTokenId, permission);
- // Check whether the permission is granted.
- if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
- needGrantPermission = true;
- break;
- }
- } catch (err) {
- console.error('app permission query grant status error' + JSON.stringify(err));
- needGrantPermission = true;
- break;
- }
- }
- // If the permission is not granted, call requestPermissionsFromUser to apply for the permission.
- if (needGrantPermission) {
- try {
- await globalThis.abilityContext.requestPermissionsFromUser(permissions);
- } catch (err) {
- console.error('app permission request permissions error' + JSON.stringify(err));
- }
- } else {
- console.info('app permission already granted');
- }
- }
- ```
-
-3. Register the continuation management service and obtain a token.
-
- The sample code is as follows:
-
- ```ts
- let token: number = -1; // Used to save the token returned after the registration. The token will be used when listening for device connection/disconnection events, starting the device selection module, and updating the device connection state.
-
- continuationManager.register().then((data) => {
- console.info('register finished, ' + JSON.stringify(data));
- token = data; // Obtain a token and assign a value to the token variable.
- }).catch((err) => {
- console.error('register failed, cause: ' + JSON.stringify(err));
- });
- ```
-
-4. Listen for the device connection/disconnection state.
-
- The sample code is as follows:
-
- ```ts
- let remoteDeviceId: string = ""; // Used to save the information about the remote device selected by the user, which will be used for cross-device continuation or collaboration.
-
- // The token parameter is the token obtained during the registration.
- continuationManager.on("deviceConnect", token, (continuationResults) => {
- console.info('registerDeviceConnectCallback len: ' + continuationResults.length);
- if (continuationResults.length <= 0) {
- console.info('no selected device');
- return;
- }
- remoteDeviceId = continuationResults[0].id; // Assign the deviceId of the first selected remote device to the remoteDeviceId variable.
-
- // Pass the remoteDeviceId parameter to want.
- let want = {
- deviceId: remoteDeviceId,
- bundleName: 'ohos.samples.continuationmanager',
- abilityName: 'MainAbility'
- };
- // To initiate multi-device collaboration, you must obtain the ohos.permission.DISTRIBUTED_DATASYNC permission.
- globalThis.abilityContext.startAbility(want).then((data) => {
- console.info('StartRemoteAbility finished, ' + JSON.stringify(data));
- }).catch((err) => {
- console.error('StartRemoteAbility failed, cause: ' + JSON.stringify(err));
- });
- });
- ```
-
- The preceding multi-device collaboration operation is performed across devices in the stage model. For details about this operation in the FA model, see [Page Ability Development](https://gitee.com/openharmony/docs/blob/master/en/application-dev/ability/fa-pageability.md).
-
- You can also instruct the device selection module to update the device connection state. The sample code is as follows:
-
- ```ts
- // Set the device connection state.
- let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.CONNECTED;
-
- // The token parameter is the token obtained during the registration, and the remoteDeviceId parameter is the remoteDeviceId obtained.
- continuationManager.updateConnectStatus(token, remoteDeviceId, deviceConnectStatus).then((data) => {
- console.info('updateConnectStatus finished, ' + JSON.stringify(data));
- }).catch((err) => {
- console.error('updateConnectStatus failed, cause: ' + JSON.stringify(err));
- });
- ```
-
- Listen for the device disconnection state so that the user can stop cross-device continuation or collaboration in time. The sample code is as follows:
-
- ```ts
- // The token parameter is the token obtained during the registration.
- continuationManager.on("deviceDisconnect", token, (deviceIds) => {
- console.info('onDeviceDisconnect len: ' + deviceIds.length);
- if (deviceIds.length <= 0) {
- console.info('no unselected device');
- return;
- }
-
- // Update the device connection state.
- let unselectedDeviceId: string = deviceIds[0]; // Assign the deviceId of the first deselected remote device to the unselectedDeviceId variable.
- let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.DISCONNECTING; // Device disconnected.
-
- // The token parameter is the token obtained during the registration, and the unselectedDeviceId parameter is the unselectedDeviceId obtained.
- continuationManager.updateConnectStatus(token, unselectedDeviceId, deviceConnectStatus).then((data) => {
- console.info('updateConnectStatus finished, ' + JSON.stringify(data));
- }).catch((err) => {
- console.error('updateConnectStatus failed, cause: ' + JSON.stringify(err));
- });
- });
- ```
-
-5. Start the device selection module to show the list of available devices on the network.
-
- The sample code is as follows:
-
- ```ts
- // Filter parameters.
- let continuationExtraParams = {
- deviceType: ["00E"], // Device type.
- continuationMode: continuationManager.ContinuationMode.COLLABORATION_SINGLE // Single-choice mode of the device selection module.
- };
-
- // The token parameter is the token obtained during the registration.
- continuationManager.startDeviceManager(token, continuationExtraParams).then((data) => {
- console.info('startDeviceManager finished, ' + JSON.stringify(data));
- }).catch((err) => {
- console.error('startDeviceManager failed, cause: ' + JSON.stringify(err));
- });
- ```
-
-6. If you do not need to perform cross-device migration or collaboration operations, you can deregister the continuation management service, by passing the token obtained during the registration.
-
- The sample code is as follows:
-
- ```ts
- // The token parameter is the token obtained during the registration.
- continuationManager.unregister(token).then((data) => {
- console.info('unregister finished, ' + JSON.stringify(data));
- }).catch((err) => {
- console.error('unregister failed, cause: ' + JSON.stringify(err));
- });
- ```
diff --git a/en/application-dev/ability/fa-brief.md b/en/application-dev/ability/fa-brief.md
deleted file mode 100644
index b89c15504376f326629dd2b3dd537e1633d986d0..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/fa-brief.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# FA Model Overview
-
-## Overall Architecture
-The development of an OpenHarmony application is essentially the development of one or more abilities. By scheduling abilities and managing their lifecycle, OpenHarmony implements application scheduling.
-
-The Feature Ability (FA) model applies to application development using API version 8 and earlier versions. In this model, there are Page, Service, Data, and Form abilities.
-- The Page ability implements the ArkUI and provides the capability of interacting with users.
-- The Service ability does not have a UI. It runs in the background and provides custom services for other abilities to invoke.
-- The Data ability does not have a UI. It runs in the background and enables other abilities to insert, delete, and query data.
-- The Form ability provides a widget, which is a UI display mode.
-
-## Lifecycle
-
-Among all abilities, the Page ability has the most complex lifecycle, because it has a UI and acts as a touchpoint for interacting with users.
-**The following figure shows the lifecycle of the Page ability.**
-
-
-
-The other abilities do not involve the foreground/background switchover and the **onShow** callback.
-You can override the lifecycle callbacks in **app.js/app.ets** to process application logic.
-
-Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks.
-
-
-## Process and Thread Model
-An application exclusively uses an independent process, and an ability exclusively uses an independent thread. When an ability is started for the first time, an application process as well as a thread for this ability is created. After the application is started, other abilities in the application are started, and a thread is created for every of these started abilities. Each ability is bound to an independent JSRuntime instance. In this way, abilities are isolated from each other.
-
-
diff --git a/en/application-dev/ability/fa-dataability.md b/en/application-dev/ability/fa-dataability.md
deleted file mode 100644
index 36eda5d9210681106a9476bdc87de28f4d06406c..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/fa-dataability.md
+++ /dev/null
@@ -1,308 +0,0 @@
-# Data Ability Development
-
-## When to Use
-
-A Data ability helps applications manage access to data stored by themselves and other applications. It also provides APIs for sharing data with other applications either on the same device or across devices.
-
-Data ability providers can customize data access-related APIs such as data inserting, deleting, updating, and querying, as well as file opening, and share data with other applications through these open APIs.
-
-## URI Introduction
-
-A Uniform Resource Identifier (URI) is used to identify a specific data item, such as a table in the database or a file on the disk. URIs used in OpenHarmony comply with the commonly used URI standard. A URI consists of the components:
-
-
-
-- **scheme**: name of the scheme used by the Data ability. The value is fixed at **dataability**.
-- **authority**: device ID. To access data on a remote device, set this component to the ID of the remote device. To access data on the local device, leave this component empty.
-- **path**: location of the specific resource to access.
-- **query**: query parameters.
-- **fragment**: subordinate resources to access.
-
-Example URIs:
-
-- Cross-device communication: **dataability://***device_id***/***com.domainname.dataability.persondata***/***person***/***10*
-- Local-device communication: **dataability:///***com.domainname.dataability.persondata***/***person***/***10*
-
-> **NOTE**
->
-> In the case of local-device communication, **device_id** is empty, and therefore, there are three slashes (/) after **dataability:**.
-
-## Available APIs
-
-**Table 1** Data ability lifecycle APIs
-|API|Description|
-|:------|:------|
-|onInitialized?(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).|
-|update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Updates data in the database.|
-|query?(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Queries data in the database.|
-|delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Deletes one or more data records from the database.|
-|normalizeUri?(uri: string, callback: AsyncCallback\): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.|
-|batchInsert?(uri: string, valueBuckets: Array\, callback: AsyncCallback\): void|Inserts multiple data records into the database.|
-|denormalizeUri?(uri: string, callback: AsyncCallback\): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.|
-|insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\): void|Inserts a data record into the database.|
-|openFile?(uri: string, mode: string, callback: AsyncCallback\): void|Opens a file.|
-|getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback\>): void|Obtains the MIME type of a file.|
-|getType?(uri: string, callback: AsyncCallback\): void|Obtains the MIME type matching the data specified by the URI.|
-|executeBatch?(ops: Array\, callback: AsyncCallback\>): void|Operates data in the database in batches.|
-|call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback\): void|Calls a custom API.|
-
-
-## How to Develop
-### Creating a Data Ability
-
-1. To meet the basic requirements of the database storage service, implement the **Insert**, **Query**, **Update**, and **Delete** APIs in the **Data** class. The **BatchInsert** and **ExecuteBatch** APIs have already implemented the traversal logic, but not batch data processing.
-
- The following code snippet shows how to create a Data ability:
-
- ```javascript
- import dataAbility from '@ohos.data.dataAbility'
- import dataRdb from '@ohos.data.rdb'
-
- const TABLE_NAME = 'book'
- const STORE_CONFIG = { name: 'book.db' }
- const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)'
- let rdbStore: dataRdb.RdbStore = undefined
-
- export default {
- onInitialized(abilityInfo) {
- console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName)
- dataRdb.getRdbStore(STORE_CONFIG, 1, (err, store) => {
- console.info('DataAbility getRdbStore callback')
- store.executeSql(SQL_CREATE_TABLE, [])
- rdbStore = store
- });
- },
- insert(uri, valueBucket, callback) {
- console.info('DataAbility insert start')
- rdbStore.insert(TABLE_NAME, valueBucket, callback)
- },
- batchInsert(uri, valueBuckets, callback) {
- console.info('DataAbility batch insert start')
- for (let i = 0;i < valueBuckets.length; i++) {
- console.info('DataAbility batch insert i=' + i)
- if (i < valueBuckets.length - 1) {
- rdbStore.insert(TABLE_NAME, valueBuckets[i], (err: any, num: number) => {
- console.info('DataAbility batch insert ret=' + num)
- })
- } else {
- rdbStore.insert(TABLE_NAME, valueBuckets[i], callback)
- }
- }
- },
- query(uri, columns, predicates, callback) {
- console.info('DataAbility query start')
- let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
- rdbStore.query(rdbPredicates, columns, callback)
- },
- update(uri, valueBucket, predicates, callback) {
- console.info('DataAbilityupdate start')
- let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
- rdbStore.update(valueBucket, rdbPredicates, callback)
- },
- delete(uri, predicates, callback) {
- console.info('DataAbilitydelete start')
- let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
- rdbStore.delete(rdbPredicates, callback)
- }
- };
- ```
-
-2. Configure the submodule.
-
- | JSON Field| Description |
- | ------------ | ------------------------------------------------------------ |
- | "name" | Ability name, corresponding to the **Data** class name derived from **Ability**. |
- | "type" | Ability type, which is **Data** for a Data ability. |
- | "uri" | URI used for communication. |
- | "visible" | Whether the Data ability is visible to other applications. When this parameter is set to **true**, the Data ability can communicate with other applications.|
-
- **config.json configuration example**
-
- ```json
- "abilities":[{
- "srcPath": "DataAbility",
- "name": ".DataAbility",
- "icon": "$media:icon",
- "srcLanguage": "ets",
- "description": "$string:description_dataability",
- "type": "data",
- "visible": true,
- "uri": "dataability://ohos.samples.etsdataability.DataAbility"
- }]
- ```
-
-### Accessing a Data ability
-#### Development Preparations
-
-Import the basic dependency packages and obtain the URI string for communicating with the Data submodule.
-
-The basic dependency packages include:
-- @ohos.ability.featureAbility
-- @ohos.data.dataAbility
-- @ohos.data.rdb
-
-#### Data Ability API Development
-
-
-1. Create a Data ability helper.
-
- For details about the APIs provided by **DataAbilityHelper**, see [DataAbilityHelper Module](../reference/apis/js-apis-dataAbilityHelper.md).
- ```js
- // Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/).
- import featureAbility from '@ohos.ability.featureAbility'
- import ohos_data_ability from '@ohos.data.dataAbility'
- import ohos_data_rdb from '@ohos.data.rdb'
-
- var urivar = "dataability:///com.ix.DataAbility"
- var DAHelper = featureAbility.acquireDataAbilityHelper(
- urivar
- );
- ```
-2. Construct RDB data.
- ```js
- var valuesBucket = {"name": "gaolu"}
- var da = new ohos_data_ability.DataAbilityPredicates()
- var valArray =new Array("value1");
- var cars = new Array({"batchInsert1" : "value1",});
- ```
-3. Use **insert** to insert data to the Data submodule.
- ```js
- // Callback mode:
- DAHelper.insert(
- urivar,
- valuesBucket,
- (error, data) => {
- console.log("DAHelper insert result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var datainsert = await DAHelper.insert(
- urivar,
- valuesBucket
- );
- ```
-4. Use **delete** to delete data from the Data submodule.
- ```js
- // Callback mode:
- DAHelper.delete(
- urivar,
- da,
- (error, data) => {
- console.log("DAHelper delete result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var datadelete = await DAHelper.delete(
- urivar,
- da,
- );
- ```
-5. Use **update** to update data in the Data submodule.
- ```js
- // Callback mode:
- DAHelper.update(
- urivar
- valuesBucket,
- da,
- (error, data) => {
- console.log("DAHelper update result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var dataupdate = await DAHelper.update(
- urivar,
- valuesBucket,
- da,
- );
- ```
-6. Use **query** to query data in the Data submodule.
- ```js
- // Callback mode:
- DAHelper.query(
- urivar,
- valArray,
- da,
- (error, data) => {
- console.log("DAHelper query result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var dataquery = await DAHelper.query(
- urivar,
- valArray,
- da
- );
- ```
-7. Use **batchInsert** to insert data in batches to the Data submodule.
- ```js
- // Callback mode:
- DAHelper.batchInsert(
- urivar,
- cars,
- (error, data) => {
- console.log("DAHelper batchInsert result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var databatchInsert = await DAHelper.batchInsert(
- urivar,
- cars
- );
- ```
-8. Use **executeBatch** to process data in batches in the Data submodule.
- ```js
- // Callback mode:
- DAHelper.executeBatch(
- urivar,
- [
- {
- uri: urivar,
- type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
- valuesBucket: {"executeBatch" : "value1",},
- predicates: da,
- expectedCount:0,
- predicatesBackReferences: null,
- interrupted:true,
- }
- ],
- (error, data) => {
- console.log("DAHelper executeBatch result: " + data)
- }
- );
- ```
-
- ```js
- // Promise mode:
- var dataexecuteBatch = await DAHelper.executeBatch(
- urivar,
- [
- {
- uri: urivar,
- type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
- valuesBucket:
- {
- "executeBatch" : "value1",
- },
- predicates: da,
- expectedCount:0,
- predicatesBackReferences: null,
- interrupted:true,
- }
- ]
- );
- ```
diff --git a/en/application-dev/ability/fa-formability.md b/en/application-dev/ability/fa-formability.md
deleted file mode 100644
index c1cadebe652dbd9f195e96ed1dec221df0eff849..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/fa-formability.md
+++ /dev/null
@@ -1,404 +0,0 @@
-# FA Widget Development
-
-## Widget Overview
-A widget is a set of UI components used to display important information or operations for an application. It provides users with direct access to a desired application service, without requiring them to open the application.
-
-A widget displays brief information about an application on the UI of another application (host application, currently system applications only) and provides basic interactive functions such as opening a UI page or sending a message.
-
-Basic concepts:
-- Widget provider: an atomic service that controls what and how content is displayed in a widget and interacts with users.
-- Widget host: an application that displays the widget content and controls the position where the widget is displayed in the host application.
-- Widget Manager: a resident agent that manages widgets added to the system and provides functions such as periodic widget update.
-
-> **NOTE**
->
-> The widget host and provider do not keep running all the time. The Widget Manager starts the widget provider to obtain widget information when a widget is added, deleted, or updated.
-
-You only need to develop widget content as the widget provider. The system automatically handles the work done by the widget host and Widget Manager.
-
-The widget provider controls the widget content to display, component layout, and click events bound to components.
-
-## Development Overview
-
-In FA widget development, you need to carry out the following operations as a widget provider based on the [Feature Ability (FA) model](fa-brief.md).
-
-- Develop the lifecycle callbacks in **LifecycleForm**.
-- Create a **FormBindingData** instance.
-- Update a widget through **FormProvider**.
-- Develop the widget UI pages.
-
-## Available APIs
-
-The table below describes the lifecycle callbacks provided in **LifecycleForm**.
-
-**Table 1** LifecycleForm APIs
-
-| API | Description |
-| :----------------------------------------------------------- | :------------------------------------------- |
-| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a **Form** instance (widget) has been created. |
-| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.|
-| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. |
-| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. |
-| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. |
-| onDestroy(formId: string): void | Called to notify the widget provider that a **Form** instance (widget) has been destroyed. |
-| onAcquireFormState?(want: Want): formInfo.FormState | Called when the widget provider receives the status query result of a widget. |
-
-For details about the **FormProvider** APIs, see [FormProvider](../reference/apis/js-apis-formprovider.md).
-
-**Table 2** FormProvider APIs
-
-| API | Description |
-| :----------------------------------------------------------- | :------------------------------------------------ |
-| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. |
-| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.|
-| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. |
-| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. |
-
-## How to Develop
-
-### Creating LifecycleForm
-
-To create a widget in the FA model, you need to implement the lifecycles of **LifecycleForm**. The sample code is as follows:
-
-1. Import the required modules.
-
- ```javascript
- import formBindingData from '@ohos.application.formBindingData'
- import formInfo from '@ohos.application.formInfo'
- import formProvider from '@ohos.application.formProvider'
- ```
-
-2. Implement the lifecycle callbacks of **LifecycleForm**.
-
- ```javascript
- export default {
- onCreate(want) {
- console.log('FormAbility onCreate');
- // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
- let obj = {
- "title": "titleOnCreate",
- "detail": "detailOnCreate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- return formData;
- },
- onCastToNormal(formId) {
- // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
- console.log('FormAbility onCastToNormal');
- },
- onUpdate(formId) {
- // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
- console.log('FormAbility onUpdate');
- let obj = {
- "title": "titleOnUpdate",
- "detail": "detailOnUpdate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- formProvider.updateForm(formId, formData).catch((error) => {
- console.log('FormAbility updateForm, error:' + JSON.stringify(error));
- });
- },
- onVisibilityChange(newStatus) {
- // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification.
- console.log('FormAbility onVisibilityChange');
- },
- onEvent(formId, message) {
- // If the widget supports event triggering, override this method and implement the trigger.
- console.log('FormAbility onEvent');
- },
- onDestroy(formId) {
- // Delete widget data.
- console.log('FormAbility onDestroy');
- },
- onAcquireFormState(want) {
- console.log('FormAbility onAcquireFormState');
- return formInfo.FormState.READY;
- },
- }
- ```
-
-### Configuring the Widget Configuration File
-
-Configure the **config.json** file for the widget.
-
-- The **js** module in the **config.json** file provides the JavaScript resources of the widget. The internal structure is described as follows:
-
- | Field| Description | Data Type| Default |
- | -------- | ------------------------------------------------------------ | -------- | ------------------------ |
- | name | Name of a JavaScript component. The default value is **default**. | String | No |
- | pages | Route information about all pages in the JavaScript component, including the page path and page name. The value is an array, in which each element represents a page. The first element in the array represents the home page of the JavaScript FA.| Array | No |
- | window | Window-related configurations. | Object | Yes |
- | type | Type of the JavaScript component. Available values are as follows: **normal**: indicates that the JavaScript component is an application instance. **form**: indicates that the JavaScript component is a widget instance.| String | Yes (initial value: **normal**)|
- | mode | Development mode of the JavaScript component. | Object | Yes (initial value: left empty) |
-
- A configuration example is as follows:
-
- ```json
- "js": [{
- "name": "widget",
- "pages": ["pages/index/index"],
- "window": {
- "designWidth": 720,
- "autoDesignWidth": true
- },
- "type": "form"
- }]
- ```
-
-- The **abilities** module in the **config.json** file corresponds to the **LifecycleForm** of the widget. The internal structure is described as follows:
-
- | Field | Description | Data Type | Default |
- | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ |
- | name | Class name of the widget. The value is a string with a maximum of 127 bytes. | String | No |
- | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) |
- | isDefault | Whether the widget is a default one. Each ability has only one default widget. **true**: The widget is the default one. **false**: The widget is not the default one.| Boolean | No |
- | type | Type of the widget. Available values are as follows: **JS**: indicates a JavaScript-programmed widget. | String | No |
- | colorMode | Color mode of the widget. Available values are as follows: **auto**: The widget adopts the auto-adaptive color mode. **dark**: The widget adopts the dark color mode. **light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)|
- | supportDimensions | Grid styles supported by the widget. Available values are as follows: **1 * 2**: indicates a grid with one row and two columns. **2 * 2**: indicates a grid with two rows and two columns. **2 * 4**: indicates a grid with two rows and four columns. **4 * 4**: indicates a grid with four rows and four columns.| String array| No |
- | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No |
- | updateEnabled | Whether the widget can be updated periodically. Available values are as follows: **true**: The widget can be updated periodically, depending on the update way you select, either at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** is preferentially recommended. **false**: The widget cannot be updated periodically.| Boolean | No |
- | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute. This parameter has a lower priority than **updateDuration**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) |
- | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes. If the value is **0**, this field does not take effect. If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes. This parameter has a higher priority than **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) |
- | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) |
- | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) |
- | jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No |
- | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) |
- | customizeData | Custom information about the widget. | Object array | Yes (initial value: left empty) |
-
- A configuration example is as follows:
-
- ```json
- "abilities": [{
- "name": "FormAbility",
- "description": "This is a FormAbility",
- "formsEnabled": true,
- "icon": "$media:icon",
- "label": "$string:form_FormAbility_label",
- "srcPath": "FormAbility",
- "type": "service",
- "srcLanguage": "ets",
- "formsEnabled": true,
- "forms": [{
- "colorMode": "auto",
- "defaultDimension": "2*2",
- "description": "This is a widget.",
- "formVisibleNotify": true,
- "isDefault": true,
- "jsComponentName": "widget",
- "name": "widget",
- "scheduledUpdateTime": "10:30",
- "supportDimensions": ["2*2"],
- "type": "JS",
- "updateEnabled": true
- }]
- }]
- ```
-
-
-### Persistently Storing Widget Data
-
-Mostly, the widget provider is started only when it needs to obtain information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget.
-
-```javascript
- onCreate(want) {
- console.log('FormAbility onCreate');
-
- let formId = want.parameters["ohos.extra.param.key.form_identity"];
- let formName = want.parameters["ohos.extra.param.key.form_name"];
- let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
- // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
- // The storeFormInfo API is not implemented here.
- storeFormInfo(formId, formName, tempFlag, want);
-
- let obj = {
- "title": "titleOnCreate",
- "detail": "detailOnCreate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- return formData;
- }
-```
-
-You should override **onDestroy** to delete widget data.
-
-```javascript
- onDestroy(formId) {
- console.log('FormAbility onDestroy');
-
- // You need to implement the code for deleting the persistent widget instance.
- // The deleteFormInfo API is not implemented here.
- deleteFormInfo(formId);
- }
-```
-
-For details about the persistence method, see [Lightweight Data Store Development](../database/database-preference-guidelines.md).
-
-Note that the **Want** passed by the widget host to the widget provider contains a flag that indicates whether the requested widget is a temporary one.
-
-- Normal widget: a widget that will be persistently used by the widget host
-
-- Temporary widget: a widget that is temporarily used by the widget host
-
-Data of a temporary widget is not persistently stored. If the widget framework is killed and restarted, data of a temporary widget will be deleted. However, the widget provider is not notified of which widget is deleted, and still keeps the data. Therefore, the widget provider should implement data clearing. In addition, the widget host may convert a temporary widget into a normal one. If the conversion is successful, the widget provider should process the widget ID and store the data persistently. This prevents the widget provider from deleting persistent data when clearing temporary widgets.
-
-### Updating Widget Data
-
-When a widget application initiates a data update upon a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows:
-
-```javascript
-onUpdate(formId) {
- // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
- console.log('FormAbility onUpdate');
- let obj = {
- "title": "titleOnUpdate",
- "detail": "detailOnUpdate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- // Call the updateForm method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged.
- formProvider.updateForm(formId, formData).catch((error) => {
- console.log('FormAbility updateForm, error:' + JSON.stringify(error));
- });
-}
-```
-
-### Developing Widget UI Pages
-
-You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget.
-
-> **NOTE**
->
-> Currently, only the JavaScript-based web-like development paradigm can be used to develop the widget UI.
-
- - In the HML file:
- ```html
-
-
-
-
-
-
- {{title}}
- {{detail}}
-
-
-
- ```
-
- - In the CSS file:
-
- ```css
-.container {
- flex-direction: column;
- justify-content: center;
- align-items: center;
-}
-
-.bg-img {
- flex-shrink: 0;
- height: 100%;
-}
-
-.container-inner {
- flex-direction: column;
- justify-content: flex-end;
- align-items: flex-start;
- height: 100%;
- width: 100%;
- padding: 12px;
-}
-
-.title {
- font-size: 19px;
- font-weight: bold;
- color: white;
- text-overflow: ellipsis;
- max-lines: 1;
-}
-
-.detail_text {
- font-size: 16px;
- color: white;
- opacity: 0.66;
- text-overflow: ellipsis;
- max-lines: 1;
- margin-top: 6px;
-}
- ```
-
- - In the JSON file:
- ```json
- {
- "data": {
- "title": "TitleDefault",
- "detail": "TextDefault"
- },
- "actions": {
- "routerEvent": {
- "action": "router",
- "abilityName": "com.example.entry.MainAbility",
- "params": {
- "message": "add detail"
- }
- }
- }
- }
- ```
-
-Now you've got a widget shown below.
-
-
-
-### Developing Widget Events
-
-You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows:
-
-1. Set **onclick** in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
-2. For the router event, set the following attributes:
- - **action**: **"router"**.
- - **abilityName**: target ability name, for example, **com.example.entry.MainAbility**, which is the default main ability name in DevEco Studio for the FA model.
- - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field.
-3. For the message event, set the following attributes:
- - **action**: **"message"**.
- - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**.
-
-The code snippet is as follows:
-
- - In the HML file:
- ```html
-
-
-
-
-
-
- {{title}}
- {{detail}}
-
-
-
- ```
-
- - In the JSON file:
- ```json
- {
- "data": {
- "title": "TitleDefault",
- "detail": "TextDefault"
- },
- "actions": {
- "routerEvent": {
- "action": "router",
- "abilityName": "com.example.entry.MainAbility",
- "params": {
- "message": "add detail"
- }
- },
- "messageEvent": {
- "action": "message",
- "params": {
- "message": "add detail"
- }
- }
- }
- }
- ```
\ No newline at end of file
diff --git a/en/application-dev/ability/fa-pageability.md b/en/application-dev/ability/fa-pageability.md
deleted file mode 100644
index 3a2629a79996660f48dfc247b9a560ea1abe09b4..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/fa-pageability.md
+++ /dev/null
@@ -1,219 +0,0 @@
-# Page Ability Development
-
-## Overview
-### Concepts
-The Page ability implements the ArkUI and provides the capability of interacting with developers. When you create an ability in DevEco Studio, DevEco Studio automatically creates template code. The capabilities related to the Page ability are implemented through the **featureAbility**, and the lifecycle callbacks are implemented through the callbacks in **app.js** or **app.ets**.
-
-### Page Ability Lifecycle
-
-**Ability lifecycle**
-
-The Page ability lifecycle defines all states of a Page ability, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**.
-
-The following figure shows the lifecycle state transition of the Page ability.
-
-
-
-
-Description of ability lifecycle states:
-
- - **UNINITIALIZED**: The Page ability is not initialized. This is a temporary state, from which a Page ability changes directly to the **INITIAL** state upon its creation.
-
- - **INITIAL**: The Page ability is initialized but not running. The Page ability enters the **INACTIVE** state after it is started.
-
- - **INACTIVE**: The Page ability is visible but does not gain focus.
-
- - **ACTIVE**: The Page ability runs in the foreground and has focus.
-
- - **BACKGROUND**: The Page ability runs in the background. After being re-activated, the Page ability enters the **ACTIVE** state. After being destroyed, the Page ability enters the **INITIAL** state.
-
-**The following figure shows the relationship between lifecycle callbacks and lifecycle states of the Page ability.**
-
-
-
-You can override the lifecycle callbacks provided by the Page ability in the **app.js** or **app.ets** file. Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks.
-
-### Launch Type
-The ability supports two launch types: singleton and multi-instance.
-You can specify the launch type by setting **launchType** in the **config.json** file.
-
-**Table 1** Introduction to startup mode
-
-| Launch Type | Description |Description |
-| ----------- | ------- |---------------- |
-| standard | Multi-instance | A new instance is started each time an ability starts.|
-| singleton | Singleton | Only one instance exists in the system. If an instance already exists when an ability is started, that instance is reused.|
-
-By default, **singleton** is used.
-
-
-## Development Guidelines
-### Available APIs
-
-**Table 2** APIs provided by featureAbility
-
-| API | Description |
-| --------------------------------------------------- | --------------- |
-| void startAbility(parameter: StartAbilityParameter) | Starts an ability. |
-| Context getContext(): | Obtains the application context.|
-| void terminateSelf() | Terminates the ability. |
-| bool hasWindowFocus() | Checks whether the ability has focus. |
-
-
-### Starting a Local Page Ability
-
-**Modules to Import**
-
-```js
- import featureAbility from '@ohos.ability.featureAbility'
-```
-
-**Example**
-
-```javascript
- import featureAbility from '@ohos.ability.featureAbility'
- featureAbility.startAbility({
- want:
- {
- action: "",
- entities: [""],
- type: "",
- deviceId: "",
- bundleName: "com.example.myapplication",
- /* In the FA model, abilityName consists of package and ability name. */
- abilityName: "com.example.entry.secondAbility",
- uri: ""
- },
- },
- );
-```
-
-### Starting a Remote Page Ability
->Note
->
->This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications.
-
-**Modules to Import**
-
-```
- import featureAbility from '@ohos.ability.featureAbility'
- import deviceManager from '@ohos.distributedHardware.deviceManager';
-```
-
-**Example**
-```ts
- function onStartRemoteAbility() {
- console.info('onStartRemoteAbility begin');
- let params;
- let wantValue = {
- bundleName: 'ohos.samples.etsDemo',
- abilityName: 'ohos.samples.etsDemo.RemoteAbility',
- deviceId: getRemoteDeviceId(),
- parameters: params
- };
- console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
- featureAbility.startAbility({
- want: wantValue
- }).then((data) => {
- console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
- });
- console.info('onStartRemoteAbility end');
- }
-```
-
-Obtain **deviceId** from **DeviceManager**. The sample code is as follows:
-
-```ts
- import deviceManager from '@ohos.distributedHardware.deviceManager';
- let dmClass;
- function getRemoteDeviceId() {
- if (typeof dmClass === 'object' && dmClass != null) {
- let list = dmClass.getTrustedDeviceListSync();
- if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
- return;
- }
- console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
- return list[0].deviceId;
- } else {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
- }
- }
-```
-
-In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows:
-
-```ts
- import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
- import bundle from '@ohos.bundle';
- async function RequestPermission() {
- console.info('RequestPermission begin');
- let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"];
- let bundleFlag = 0;
- let tokenID = undefined;
- let userID = 100;
- let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
- tokenID = appInfo.accessTokenId;
- let atManager = abilityAccessCtrl.createAtManager();
- let requestPermissions: Array = [];
- for (let i = 0;i < array.length; i++) {
- let result = await atManager.verifyAccessToken(tokenID, array[i]);
- console.info("verifyAccessToken result:" + JSON.stringify(result));
- if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
- requestPermissions.push(array[i]);
- }
- }
- console.info("requestPermissions:" + JSON.stringify(requestPermissions));
- if (requestPermissions.length == 0 || requestPermissions == []) {
- return;
- }
- let context = featureAbility.getContext();
- context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
- console.info("data:" + JSON.stringify(data));
- console.info("data requestCode:" + data.requestCode);
- console.info("data permissions:" + data.permissions);
- console.info("data authResults:" + data.authResults);
- });
- console.info('RequestPermission end');
- }
-```
-
-### Lifecycle APIs
-
-**Table 3** Lifecycle callbacks
-
-| API | Description |
-| ------------ | ------------------------------------------------------------ |
-| onShow() | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.|
-| onHide() | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible to users.|
-| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for application exit, such as recycling resources and clearing the cache.|
-| onCreate() | Called when the ability is created for the first time. You can initialize the application in this callback.|
-| onInactive() | Called when the ability loses focus. An ability loses focus when it is about to enter the background state.|
-| onActive() | Called when the ability is switched to the foreground and gains focus. |
-
-**Example**
-
-You need to override the lifecycle callbacks except **onCreate()** and **onDestroy()** in **app.js** or **app.ets**. The **onCreate()** and **onDestroy()** callbacks are automatically generated in the template code provided by DevEco Studio.
-
-```javascript
-export default {
- onCreate() {
- console.info('Application onCreate')
- },
- onDestroy() {
- console.info('Application onDestroy')
- },
- onShow(){
- console.info('Application onShow')
- },
- onHide(){
- console.info('Application onHide')
- },
- onInactive(){
- console.info('Application onInactive')
- },
- onActive(){
- console.info('Application onActive')
- },
-}
-```
diff --git a/en/application-dev/ability/fa-serviceability.md b/en/application-dev/ability/fa-serviceability.md
deleted file mode 100644
index 48270359d9d49f9ea7d7111b021cd8b81da3df82..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/fa-serviceability.md
+++ /dev/null
@@ -1,400 +0,0 @@
-# Service Ability Development
-
-## When to Use
-A Service ability is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. Service abilities can be started by other applications or abilities and can remain running in the background even after the user switches to another application.
-
-## Available APIs
-
-**Table 1** Service ability lifecycle APIs
-|API|Description|
-|:------|:------|
-|onStart?(): void|Called to initialize a Service ability being created. This callback is invoked only once in the entire lifecycle of a Service ability. The **Want** object passed to this callback must be null.|
-|onCommand?(want: Want, startId: number): void|Called every time a Service ability is created on a client. You can collect calling statistics and perform initialization operations in this callback.|
-|onConnect?(want: Want): rpc.RemoteObject|Called when another ability is connected to the Service ability.|
-|onDisconnect?(want: Want): void|Called when another ability is disconnected from the Service ability.|
-|onStop?(): void|Called when the Service ability is being destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners.|
-
-## How to Develop
-
-### Creating and Registering a Service Ability
-
-1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests.
-
- ```javascript
- export default {
- onStart() {
- console.log('ServiceAbility onStart');
- },
- onCommand(want, startId) {
- console.log('ServiceAbility onCommand');
- },
- onConnect(want) {
- console.log('ServiceAbility OnConnect');
- return new FirstServiceAbilityStub('test');
- },
- onDisconnect(want) {
- console.log('ServiceAbility OnDisConnect');
- },
- onStop() {
- console.log('ServiceAbility onStop');
- },
- }
- ```
-
-2. Register a Service ability.
-
- Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**.
-
- ```javascript
- {
- "module": {
- "abilities": [
- {
- "name": ".ServiceAbility",
- "type": "service",
- "visible": true
- ...
- }
- ]
- ...
- }
- ...
- }
- ```
-
-
-
-### Starting a Service Ability
-
-The **Ability** class provides the **startAbility()** API for you to start another Service ability by passing a **Want** object.
-
-To set information about the target Service ability, you can first construct a **Want** object with the **bundleName** and **abilityName** parameters specified. The meanings of the parameters are as follows:
-
-- **bundleName** indicates the name of the bundle to which the target ability belongs.
-- **abilityName** indicates the target ability name.
-
-The following code snippet shows how to start a Service ability running on the local device:
-
-```javascript
-import featureAbility from '@ohos.ability.featureAbility';
-let promise = featureAbility.startAbility(
- {
- want:
- {
- bundleName: "com.jstest.service",
- abilityName: "com.jstest.service.ServiceAbility",
- },
- }
-);
-```
-
-After the preceding code is executed, the **startAbility()** API is called to start the Service ability.
-- If the Service ability is not running, the system calls **onStart()** to initialize the Service ability, and then calls **onCommand()** on the Service ability.
-- If the Service ability is running, the system directly calls **onCommand()** on the Service ability.
-
-The following code snippet shows how to start a Service ability running on the remote device. For details about **getRemoteDeviceId()**, see [Connecting to a Remote Service Ability](#connecting-to-a-remote-service-ability-applying-only-to-system-applications).
-
-```javascript
-import featureAbility from '@ohos.ability.featureAbility';
-let promise = featureAbility.startAbility(
- {
- want:
- {
- deviceId: getRemoteDeviceId(), // Remote device ID
- bundleName: "com.jstest.service",
- abilityName: "com.jstest.service.ServiceAbility",
- },
- }
-);
-```
-
-
-### Stopping a Service Ability
-
-Once created, the Service ability keeps running in the background. The system does not stop or destroy it unless memory resources must be reclaimed.
-
-### Connecting to a Local Service Ability
-
-If you need to connect a Service ability to a Page ability or to a Service ability in another application, you must first implement the **IAbilityConnection** API for the connection. A Service ability allows other abilities to connect to it through **connectAbility()**.
-
-
-You can use either of the following methods to connect to a Service ability:
-
-1. Using the IDL to automatically generate code
-
- Use OpenHarmony Interface Definition Language (IDL) to automatically generate the corresponding client, server, and **IRemoteObject** code. For details, see “Development Using TS" in [OpenHarmony IDL Specifications and User Guide](../IDL/idl-guidelines.md).
-
-2. Writing code in the corresponding file
-
- When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails.
-
- The following code snippet shows how to implement the callbacks:
-
- ```javascript
- import prompt from '@system.prompt'
-
- var option = {
- onConnect: function onConnectCallback(element, proxy) {
- console.log(`onConnectLocalService onConnectDone`)
- if (proxy === null) {
- prompt.showToast({
- message: "Connect service failed"
- })
- return
- }
- let data = rpc.MessageParcel.create()
- let reply = rpc.MessageParcel.create()
- let option = new rpc.MessageOption()
- data.writeInterfaceToken("connect.test.token")
- proxy.sendRequest(0, data, reply, option)
- prompt.showToast({
- message: "Connect service success"
- })
- },
- onDisconnect: function onDisconnectCallback(element) {
- console.log(`onConnectLocalService onDisconnectDone element:${element}`)
- prompt.showToast({
- message: "Disconnect service success"
- })
- },
- onFailed: function onFailedCallback(code) {
- console.log(`onConnectLocalService onFailed errCode:${code}`)
- prompt.showToast({
- message: "Connect local service onFailed"
- })
- }
- }
- ```
-
- The following code snippet shows how to connect to a local Service ability:
-
- ```javascript
- import featureAbility from '@ohos.ability.featureAbility';
- let connId = featureAbility.connectAbility(
- {
- bundleName: "com.jstest.service",
- abilityName: "com.jstest.service.ServiceAbility",
- },
- {
- onConnect: onConnectCallback,
- onDisconnect: onDisconnectCallback,
- onFailed: onFailedCallback,
- },
- );
- ```
-
- When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**.
-
- The following code snippet shows how the Service ability instance returns itself to the calling ability:
-
- ```javascript
- import rpc from "@ohos.rpc";
-
- class FirstServiceAbilityStub extends rpc.RemoteObject {
- constructor(des: any) {
- if (typeof des === 'string') {
- super(des)
- } else {
- return
- }
- }
-
- onRemoteRequest(code: number, data: any, reply: any, option: any) {
- console.log(printLog + ` onRemoteRequest called`)
- if (code === 1) {
- let string = data.readString()
- console.log(printLog + ` string=${string}`)
- let result = Array.from(string).sort().join('')
- console.log(printLog + ` result=${result}`)
- reply.writeString(result)
- } else {
- console.log(printLog + ` unknown request code`)
- }
- return true;
- }
- ```
-
-### Connecting to a Remote Service Ability
-
->**NOTE**
->
->This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications.
-
-If you need to connect a Service ability to a Page ability or another Service ability on a remote device, you must first implement the **IAbilityConnection** interface for the connection. A Service ability allows abilities on another device to connect to it through **connectAbility()**.
-
-When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails.
-
-The following code snippet shows how to implement the callbacks:
-
-```ts
-import prompt from '@system.prompt'
-
-var option = {
- onConnect: function onConnectCallback(element, proxy) {
- console.log(`onConnectRemoteService onConnectDone`)
- if (proxy === null) {
- prompt.showToast({
- message: "Connect service failed"
- })
- return
- }
- let data = rpc.MessageParcel.create()
- let reply = rpc.MessageParcel.create()
- let option = new rpc.MessageOption()
- data.writeInterfaceToken("connect.test.token")
- proxy.sendRequest(0, data, reply, option)
- prompt.showToast({
- message: "Connect service success"
- })
- },
- onDisconnect: function onDisconnectCallback(element) {
- console.log(`onConnectRemoteService onDisconnectDone element:${element}`)
- prompt.showToast({
- message: "Disconnect service success"
- })
- },
- onFailed: function onFailedCallback(code) {
- console.log(`onConnectRemoteService onFailed errCode:${code}`)
- prompt.showToast({
- message: "Connect local service onFailed"
- })
- }
-}
-```
-
-The **Want** of the target Service ability must contain the remote **deviceId**, which can be obtained from **DeviceManager**. The sample code is as follows:
-
-```ts
-import deviceManager from '@ohos.distributedHardware.deviceManager';
-
-// For details about the implementation of dmClass, see the implementation in Distributed Demo in Samples.
-let dmClass;
-
-function getRemoteDeviceId() {
- if (typeof dmClass === 'object' && dmClass != null) {
- let list = dmClass.getTrustedDeviceListSync();
- if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
- return;
- }
- console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
- return list[0].deviceId;
- } else {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
- }
-}
-```
-
-The following code snippet shows how to connect to a remote Service ability:
-
-```ts
-import featureAbility from '@ohos.ability.featureAbility';
-let connId = featureAbility.connectAbility(
- {
- deviceId: getRemoteDeviceId(),
- bundleName: "ohos.samples.etsDemo",
- abilityName: "ohos.samples.etsDemo.ServiceAbility",
- },
- {
- onConnect: onConnectCallback,
- onDisconnect: onDisconnectCallback,
- onFailed: onFailedCallback,
- },
-);
-```
-In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows:
-
-```ts
-import abilityAccessCtrl from "@ohos.abilityAccessCtrl";
-import bundle from '@ohos.bundle';
-async function RequestPermission() {
- console.info('RequestPermission begin');
- let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"];
- let bundleFlag = 0;
- let tokenID = undefined;
- let userID = 100;
- let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID);
- tokenID = appInfo.accessTokenId;
- let atManager = abilityAccessCtrl.createAtManager();
- let requestPermissions: Array = [];
- for (let i = 0;i < array.length; i++) {
- let result = await atManager.verifyAccessToken(tokenID, array[i]);
- console.info("verifyAccessToken result:" + JSON.stringify(result));
- if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
- } else {
- requestPermissions.push(array[i]);
- }
- }
- console.info("requestPermissions:" + JSON.stringify(requestPermissions));
- if (requestPermissions.length == 0 || requestPermissions == []) {
- return;
- }
- let context = featureAbility.getContext();
- context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{
- console.info("data:" + JSON.stringify(data));
- });
- console.info('RequestPermission end');
-}
-```
-
-When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**.
-
-The following code snippet shows how the Service ability instance returns itself to the calling ability:
-
-```ts
-import rpc from "@ohos.rpc";
-
-class FirstServiceAbilityStub extends rpc.RemoteObject {
- constructor(des: any) {
- if (typeof des === 'string') {
- super(des)
- } else {
- return
- }
- }
-
- onRemoteRequest(code: number, data: any, reply: any, option: any) {
- console.log(printLog + ` onRemoteRequest called`)
- if (code === 1) {
- let string = data.readString()
- console.log(printLog + ` string=${string}`)
- let result = Array.from(string).sort().join('')
- console.log(printLog + ` result=${result}`)
- reply.writeString(result)
- } else {
- console.log(printLog + ` unknown request code`)
- }
- return true;
- }
-}
-
-export default {
- onStart() {
- console.info('ServiceAbility onStart');
- },
- onStop() {
- console.info('ServiceAbility onStop');
- },
- onConnect(want) {
- console.log("ServiceAbility onConnect");
- try {
- let value = JSON.stringify(want);
- console.log("ServiceAbility want:" + value);
- } catch(error) {
- console.log("ServiceAbility error:" + error);
- }
- return new FirstServiceAbilityStub("first ts service stub");
- },
- onDisconnect(want) {
- console.log("ServiceAbility onDisconnect");
- let value = JSON.stringify(want);
- console.log("ServiceAbility want:" + value);
- },
- onCommand(want, startId) {
- console.info('ServiceAbility onCommand');
- let value = JSON.stringify(want);
- console.log("ServiceAbility want:" + value);
- console.log("ServiceAbility startId:" + startId);
- }
-};
-```
diff --git a/en/application-dev/ability/figures/contextIntroduction.png b/en/application-dev/ability/figures/contextIntroduction.png
deleted file mode 100644
index 7345a1a5a6a3471782e9399129c98f3d529bbfd5..0000000000000000000000000000000000000000
Binary files a/en/application-dev/ability/figures/contextIntroduction.png and /dev/null differ
diff --git a/en/application-dev/ability/figures/favsstage.png b/en/application-dev/ability/figures/favsstage.png
deleted file mode 100644
index 45f6b0ef255b01730dc42023430391e1141291c2..0000000000000000000000000000000000000000
Binary files a/en/application-dev/ability/figures/favsstage.png and /dev/null differ
diff --git a/en/application-dev/ability/figures/lifecycle.png b/en/application-dev/ability/figures/lifecycle.png
deleted file mode 100644
index 694238d99c7e70d16d6bd1a37c86bcd599a9b2f3..0000000000000000000000000000000000000000
Binary files a/en/application-dev/ability/figures/lifecycle.png and /dev/null differ
diff --git a/en/application-dev/ability/figures/stageabilitylifecyclecallback.png b/en/application-dev/ability/figures/stageabilitylifecyclecallback.png
deleted file mode 100644
index 9e17ed71f1dc9d118a490109c1e5181d738e63db..0000000000000000000000000000000000000000
Binary files a/en/application-dev/ability/figures/stageabilitylifecyclecallback.png and /dev/null differ
diff --git a/en/application-dev/ability/stage-ability-continuation.md b/en/application-dev/ability/stage-ability-continuation.md
deleted file mode 100644
index 701b730a833a7b97f00398746cddae4d2856a248..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-ability-continuation.md
+++ /dev/null
@@ -1,311 +0,0 @@
-# Ability Continuation Development
-
-## When to Use
-
-Ability continuation is to continue the current mission of an application, including the UI component state variables and distributed objects, on another device. The UI component state variables are used to synchronize UI data, and the distributed objects are used to synchronize memory data.
-
-## Available APIs
-
-The following table lists the APIs used for ability continuation. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md).
-
-**Table 1** Ability continuation APIs
-
-|API| Description|
-|:------ | :------|
-| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for continuation. The return value indicates whether the continuation request is accepted. The value **AGREE** means that the continuation request is accepted, **REJECT** means that the continuation request is rejected, and **MISMATCH** means a version mismatch.|
-| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance ability scenario.|
-| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton ability scenario.|
-
-
-
-**Figure 1** Ability continuation development
-
-
-
-In effect, ability continuation is a cross-device ability startup that carries data. When a continuation action is initiated, the system on device A calls back **onContinue()** of the application. You must implement storage of the current data in this API. Then, the system initiates a cross-device ability startup on device B and transmits the data to device B. The system on device B calls back **onCreate()** or **onNewWant()**. You must implement restoration of the transmitted data in this API.
-
-## How to Develop
-
-The code snippets provided below are all from [Sample](https://gitee.com/openharmony/ability_dmsfwk/tree/master/services/dtbschedmgr/test/samples/continuationManualTestSuite).
-
-### Application Continuation
-
-1. Modify the configuration file.
-
- - Configure the application to support ability continuation.
-
- Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on another device.
-
- ```javascript
- {
- "module": {
- "abilities": [
- {
- "continuable": true
- }
- ]
- }
- }
- ```
-
-
-
-
- - Configure the application startup type.
-
- If **launchType** is set to **standard** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md).
-
- Configure a multi-instance application as follows:
-
- ```javascript
- {
- "module": {
- "abilities": [
- {
- "launchType": "standard"
- }
- ]
- }
- }
- ```
-
- Configure a singleton application as follows or retain the default settings of **launchType**:
-
- ```javascript
- {
- "module": {
- "abilities": [
- {
- "launchType": "singleton"
- }
- ]
- }
- }
- ```
-
-
-
- - Apply for the distributed permissions.
-
- Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application.
-
- ```javascript
- "requestPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- },
- ```
-
-
-
- This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class:
-
- ```javascript
- requestPermissions = async () => {
- let permissions: Array = [
- "ohos.permission.DISTRIBUTED_DATASYNC"
- ];
- let needGrantPermission = false
- let accessManger = accessControl.createAtManager()
- Logger.info("app permission get bundle info")
- let bundleInfo = await bundle.getApplicationInfo(BUNDLE_NAME, 0, 100)
- Logger.info(`app permission query permission ${bundleInfo.accessTokenId.toString()}`)
- for (const permission of permissions) {
- Logger.info(`app permission query grant status ${permission}`)
- try {
- let grantStatus = await accessManger.verifyAccessToken(bundleInfo.accessTokenId, permission)
- if (grantStatus === PERMISSION_REJECT) {
- needGrantPermission = true
- break;
- }
- } catch (err) {
- Logger.error(`app permission query grant status error ${permission} ${JSON.stringify(err)}`)
- needGrantPermission = true
- break;
- }
- }
- if (needGrantPermission) {
- Logger.info("app permission needGrantPermission")
- try {
- await this.context.requestPermissionsFromUser(permissions)
- } catch (err) {
- Logger.error(`app permission ${JSON.stringify(err)}`)
- }
- } else {
- Logger.info("app permission already granted")
- }
- }
- ```
-
-
-
-
-2. Implement the **onContinue()** API.
-
- The **onContinue()** API is called by the initiator to save the UI component state variables and memory data and prepare for continuation. After the application completes the continuation preparation, the system must return either **OnContinueResult.AGREE(0)** to accept the continuation request or an error code to reject the request. If this API is not implemented, the system rejects the continuation request by default.
-
- Modules to import:
-
- ```javascript
- import Ability from '@ohos.application.Ability';
- import AbilityConstant from '@ohos.application.AbilityConstant';
- ```
-
- To implement ability continuation, you must implement this API and have the value **AGREE** returned.
-
- You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request.
-
- Example
-
- ```javascript
- onContinue(wantParam : {[key: string]: any}) {
- Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
- let workInput = AppStorage.Get('ContinueWork');
- // Set the user input data into wantParam.
- wantParam["work"] = workInput // set user input data into want params
- Logger.info(`onContinue input = ${wantParam["input"]}`);
- return AbilityConstant.OnContinueResult.AGREE
- }
- ```
-
-
-
-3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API.
-
- The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored.
-
- The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**.
-
- After data restore is complete, call **restoreWindowStage** to trigger page restoration.
-
-
-
- You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator.
-
- Example
-
- ```javascript
- import Ability from '@ohos.application.Ability';
- import distributedObject from '@ohos.data.distributedDataObject';
-
- export default class MainAbility extends Ability {
- storage : LocalStorag;
-
- onCreate(want, launchParam) {
- Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
- if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
- // Obtain the user data from the want parameter.
- let workInput = want.parameters.work
- Logger.info(`work input ${workInput}`)
- AppStorage.SetOrCreate('ContinueWork', workInput)
-
- this.storage = new LocalStorage();
- this.context.restoreWindowStage(this.storage);
- }
- }
- }
- ```
-For a singleton ability, use **onNewWant()** to achieve the same implementation.
-
-
-
-### Data Continuation
-
-Use distributed objects.
-
-Distributed objects allow cross-device data synchronization like local variables. For two devices that form a Super Device, when data in the distributed data object of an application is added, deleted, or modified on a device, the data for the same application is also updated on the other device. Both devices can listen for the data changes and online and offline states of the other. For details, see [Distributed Data Object Development](../database/database-distributedobject-guidelines.md).
-
-In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device.
-
-- In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**.
-
- ```javascript
- import Ability from '@ohos.application.Ability';
- import distributedObject from '@ohos.data.distributedDataObject';
-
- var g_object = distributedObject.createDistributedObject({data:undefined});
-
- export default class MainAbility extends Ability {
- sessionId : string;
-
- onContinue(wantParam : {[key: string]: any}) {
- Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
-
- if (g_object.__sessionId === undefined) {
- this.sessionId = distributedObject.genSessionId()
- Logger.info(`onContinue generate new sessionId`)
- }
- else {
- this.sessionId = g_object.__sessionId;
- }
-
- wantParam["session"] = this.sessionId
- g_object.data = AppStorage.Get('ContinueStudy');
- Logger.info(`onContinue sessionId = ${this.sessionId}, name = ${g_object.data}`)
- g_object.setSessionId(this.sessionId);
- g_object.save(wantParam.targetDevice, (result, data)=>{
- Logger.info("save callback");
- Logger.info("save sessionId " + data.sessionId);
- Logger.info("save version " + data.version);
- Logger.info("save deviceId " + data.deviceId);
- });
- ```
-
-
-
-- The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated.
-
- ```javascript
- import Ability from '@ohos.application.Ability';
- import distributedObject from '@ohos.data.distributedDataObject';
-
- var g_object = distributedObject.createDistributedObject({data:undefined});
-
- export default class MainAbility extends Ability {
- storage : LocalStorag;
-
-
- onCreate(want, launchParam) {
- Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
- if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
- // Obtain the session ID of the distributed data object from the want parameter.
- this.sessionId = want.parameters.session
- Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`)
-
- // Before fetching data from the remote device, reset g_object.data to undefined.
- g_object.data = undefined;
- // Set the session ID, so the target will fetch data from the remote device.
- g_object.setSessionId(this.sessionId);
-
- AppStorage.SetOrCreate('ContinueStudy', g_object.data)
- this.storage = new LocalStorage();
- this.context.restoreWindowStage(this.storage);
- }
-
- }
- }
- ```
-
-
-
-### More Information
-
-1. Timeout
-
- - If the application to be continued is not installed on the target device, the system checks whether the application can be installed on it and waits for a response for 4 seconds. If no response is received within 4 seconds, the caller receives a timeout error code, which means that the application cannot be installed on the target device. If the application can be installed, the system prompts the consumer to install the application on the target device. The consumer can initiate the continuation again after the installation.
- - If the application to be continued has been installed on the target device, the system waits for a response to the continuation request for 20 seconds. If no response is received within 20 seconds, the caller receives a timeout error code, which means that the continuation fails.
-
-2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required.
-
-
-
-### Restrictions
-
-1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/stage-structure.md).
-2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system.
-
-
-
-### Best Practice
-
- For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB.
diff --git a/en/application-dev/ability/stage-ability.md b/en/application-dev/ability/stage-ability.md
deleted file mode 100644
index fcd7a5dcfdde6547237f34f83dbb9bf2488d2255..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-ability.md
+++ /dev/null
@@ -1,323 +0,0 @@
-# Ability Development
-## When to Use
-Ability development in the [stage model](stage-brief.md) is significantly different from that in the FA model. The stage model requires you to declare the application package structure in the `module.json5` and `app.json5` files during application development. For details about the configuration file, see [Application Package Structure Configuration File](../quick-start/stage-structure.md). To develop an ability based on the stage model, implement the following logic:
-- Create an ability that supports screen viewing and human-machine interaction. You must implement the following scenarios: ability lifecycle callbacks, obtaining ability configuration, requesting permissions, and notifying environment changes.
-- Start an ability. You need to implement ability startup on the same device, on a remote device, or with a specified UI page.
-- Call abilities. For details, see [Call Development](stage-call.md).
-- Connect to and disconnect from a Service Extension ability. For details, see [Service Extension Ability Development](stage-serviceextension.md).
-- Continue the ability on another device. For details, see [Ability Continuation Development](stage-ability-continuation.md).
-
-### Launch Type
-An ability can be launched in the **standard**, **singleton**, or **specified** mode, as configured by `launchType` in the `module.json5` file. Depending on the launch type, the action performed when the ability is started differs, as described below.
-
-| Launch Type | Description |Action |
-| ----------- | ------- |---------------- |
-| standard | Multi-instance | A new instance is started each time an ability starts.|
-| singleton | Singleton | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.|
-| specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.|
-
-By default, the singleton mode is used. The following is an example of the `module.json5` file:
-```json
-{
- "module": {
- "abilities": [
- {
- "launchType": "singleton",
- }
- ]
- }
-}
-```
-## Creating an Ability
-### Available APIs
-The table below describes the APIs provided by the `AbilityStage` class, which has the `context` attribute. For details about the APIs, see [AbilityStage](../reference/apis/js-apis-application-abilitystage.md).
-
-**Table 1** AbilityStage APIs
-|API|Description|
-|:------|:------|
-|onCreate(): void|Called when an ability stage is created.|
-|onAcceptWant(want: Want): string|Called when a specified ability is started.|
-|onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.|
-
-The table below describes the APIs provided by the `Ability` class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md).
-
-**Table 2** Ability APIs
-
-|API|Description|
-|:------|:------|
-|onCreate(want: Want, param: AbilityConstant.LaunchParam): void|Called when an ability is created.|
-|onDestroy(): void|Called when the ability is destroyed.|
-|onWindowStageCreate(windowStage: window.WindowStage): void|Called when a `WindowStage` is created for the ability. You can use the `window.WindowStage` APIs to implement operations such as page loading.|
-|onWindowStageDestroy(): void|Called when the `WindowStage` is destroyed for the ability.|
-|onForeground(): void|Called when the ability is switched to the foreground.|
-|onBackground(): void|Called when the ability is switched to the background.|
-|onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void|Called when the ability launch type is set to `singleton`.|
-|onConfigurationUpdated(config: Configuration): void|Called when the configuration of the environment where the ability is running is updated.|
-### Implementing AbilityStage and Ability Lifecycle Callbacks
-To create Page abilities for an application in the stage model, you must implement the `AbilityStage` class and ability lifecycle callbacks, and use the `Window` APIs to set the pages. The sample code is as follows:
-1. Import the `AbilityStage` module.
- ```
- import AbilityStage from "@ohos.application.AbilityStage"
- ```
-2. Implement the `AbilityStage` class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**.
- ```ts
- export default class MyAbilityStage extends AbilityStage {
- onCreate() {
- console.log("MyAbilityStage onCreate")
- }
- }
- ```
-3. Import the `Ability` module.
- ```js
- import Ability from '@ohos.application.Ability'
- ```
-4. Implement the lifecycle callbacks of the `Ability` class. The default relative path generated by the APIs is **entry\src\main\ets\MainAbility\MainAbility.ts**.
-
- In the `onWindowStageCreate(windowStage)` API, use `loadContent` to set the application page to be loaded. For details about how to use the `Window` APIs, see [Window Development](../windowmanager/application-window-stage.md).
- ```ts
- export default class MainAbility extends Ability {
- onCreate(want, launchParam) {
- console.log("MainAbility onCreate")
- }
-
- onDestroy() {
- console.log("MainAbility onDestroy")
- }
-
- onWindowStageCreate(windowStage) {
- console.log("MainAbility onWindowStageCreate")
-
- windowStage.loadContent("pages/index").then(() => {
- console.log("MainAbility load content succeed")
- }).catch((error) => {
- console.error("MainAbility load content failed with error: " + JSON.stringify(error))
- })
- }
-
- onWindowStageDestroy() {
- console.log("MainAbility onWindowStageDestroy")
- }
-
- onForeground() {
- console.log("MainAbility onForeground")
- }
-
- onBackground() {
- console.log("MainAbility onBackground")
- }
- }
- ```
-### Obtaining AbilityStage and Ability Configurations
-Both the `AbilityStage` and `Ability` classes have the `context` attribute. An application can obtain the context of an `Ability` instance through `this.context` to obtain the configuration details.
-
-The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the `context` attribute in the `AbilityStage` class. The sample code is as follows:
-
-```ts
-import AbilityStage from "@ohos.application.AbilityStage"
-export default class MyAbilityStage extends AbilityStage {
- onCreate() {
- console.log("MyAbilityStage onCreate")
- let context = this.context
- console.log("MyAbilityStage bundleCodeDir" + context.bundleCodeDir)
-
- let currentHapModuleInfo = context.currentHapModuleInfo
- console.log("MyAbilityStage hap module name" + currentHapModuleInfo.name)
- console.log("MyAbilityStage hap module mainAbilityName" + currentHapModuleInfo.mainAbilityName)
-
- let config = this.context.config
- console.log("MyAbilityStage config language" + config.language)
- }
-}
-```
-
-The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the `context` attribute in the `Ability` class. The sample code is as follows:
-```ts
-import Ability from '@ohos.application.Ability'
-export default class MainAbility extends Ability {
- onCreate(want, launchParam) {
- console.log("MainAbility onCreate")
- let context = this.context
- console.log("MainAbility bundleCodeDir" + context.bundleCodeDir)
-
- let abilityInfo = this.context.abilityInfo;
- console.log("MainAbility ability bundleName" + abilityInfo.bundleName)
- console.log("MainAbility ability name" + abilityInfo.name)
-
- let config = this.context.config
- console.log("MainAbility config language" + config.language)
- }
-}
-```
-### Requesting Permissions
-If an application needs to obtain user privacy information or use system capabilities, for example, obtaining location information or using the camera to take photos or record videos, it must request the respective permission from consumers. During application development, you need to specify the involved sensitive permissions, declare the required permissions in `module.json5`, and use the `requestPermissionsFromUser` API to request the permission from consumers in the form of a dialog box. The following uses the permission for calendar access as an example.
-
-Declare the required permission in the `module.json5` file.
-```json
-"requestPermissions": [
- {
- "name": "ohos.permission.READ_CALENDAR"
- }
-]
-```
-Request the permission from consumers in the form of a dialog box:
-```ts
-let context = this.context
-let permissions: Array = ['ohos.permission.READ_CALENDAR']
-context.requestPermissionsFromUser(permissions).then((data) => {
- console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
-}).catch((error) => {
- console.log("Failed to request permission from user with error: " + JSON.stringify(error))
-})
-```
-### Notifying of Environment Changes
-Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single `Ability` instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. For details on the configuration, see [Configuration](../reference/apis/js-apis-configuration.md).
-
-For an application in the stage model, when the configuration changes, its abilities are not restarted, but the `onConfigurationUpdated(config: Configuration)` callback is triggered. If the application needs to perform processing based on the change, you can overwrite `onConfigurationUpdated`. Note that the `Configuration` object in the callback contains all the configurations of the current ability, not only the changed configurations.
-
-The following example shows the implementation of the `onConfigurationUpdated` callback in the `AbilityStage` class. The callback is triggered when the system language and color mode are changed.
-```ts
-import Ability from '@ohos.application.Ability'
-import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
-
-export default class MyAbilityStage extends AbilityStage {
- onConfigurationUpdated(config) {
- if (config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
- console.log('colorMode changed to dark')
- }
- }
-}
-```
-
-The following example shows the implementation of the `onConfigurationUpdated` callback in the `Ability` class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change.
-```ts
-import Ability from '@ohos.application.Ability'
-import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
-
-export default class MainAbility extends Ability {
- direction : number;
-
- onCreate(want, launchParam) {
- this.direction = this.context.config.direction
- }
-
- onConfigurationUpdated(config) {
- if (this.direction !== config.direction) {
- console.log(`direction changed to ${config.direction}`)
- }
- }
-}
-```
-## Starting an Ability
-### Available APIs
-The `Ability` class has the `context` attribute, which belongs to the `AbilityContext` class. The `AbilityContext` class has the `abilityInfo`, `currentHapModuleInfo`, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md).
-
-**Table 3** AbilityContext APIs
-|API|Description|
-|:------|:------|
-|startAbility(want: Want, callback: AsyncCallback\): void|Starts an ability.|
-|startAbility(want: Want, options?: StartOptions): Promise\|Starts an ability.|
-|startAbilityWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the account ID.|
-|startAbilityWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the account ID.|
-|startAbilityForResult(want: Want, callback: AsyncCallback\): void|Starts an ability with the returned result.|
-|startAbilityForResult(want: Want, options?: StartOptions): Promise\|Starts an ability with the returned result.|
-|startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the execution result and account ID.|
-|startAbilityForResultWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the execution result and account ID.|
-### Starting an Ability on the Same Device
-An application can obtain the context of an `Ability` instance through `this.context` and then use the `startAbility` API in the `AbilityContext` class to start the ability. The ability can be started by specifying `Want`, `StartOptions`, and `accountId`, and the operation result can be returned using a callback or `Promise` instance. The sample code is as follows:
-```ts
-let context = this.context
-var want = {
- "deviceId": "",
- "bundleName": "com.example.MyApplication",
- "abilityName": "MainAbility"
-};
-context.startAbility(want).then(() => {
- console.log("Succeed to start ability")
-}).catch((error) => {
- console.error("Failed to start ability with error: "+ JSON.stringify(error))
-})
-```
-
-### Starting an Ability on a Remote Device
->This feature applies only to system applications, since the `getTrustedDeviceListSync` API of the `DeviceManager` class is open only to system applications.
-In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows:
-```ts
-let context = this.context
-var want = {
- "deviceId": getRemoteDeviceId(),
- "bundleName": "com.example.MyApplication",
- "abilityName": "MainAbility"
-};
-context.startAbility(want).then(() => {
- console.log("Succeed to start remote ability")
-}).catch((error) => {
- console.error("Failed to start remote ability with error: " + JSON.stringify(error))
-})
-```
-Obtain the ID of a specified device from `DeviceManager`. The sample code is as follows:
-```ts
-import deviceManager from '@ohos.distributedHardware.deviceManager';
-function getRemoteDeviceId() {
- if (typeof dmClass === 'object' && dmClass != null) {
- var list = dmClass.getTrustedDeviceListSync();
- if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null");
- return;
- }
- console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
- return list[0].deviceId;
- } else {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
- }
-}
-```
-Request the permission `ohos.permission.DISTRIBUTED_DATASYNC` from consumers. This permission is used for data synchronization. For details about the sample code for requesting the permission, see [Requesting Permissions](##requesting-permissions).
-### Starting an Ability with the Specified Page
-If the launch type of an ability is set to `singleton` and the ability has been started, the `onNewWant` callback is triggered when the ability is started again. You can pass start options through the `want`. For example, to start an ability with the specified page, use the `uri` or `parameters` parameter in the `want` to pass the page information. Currently, the ability in the stage model cannot directly use the `router` capability. You must pass the start options to the custom component and invoke the `router` method to display the specified page during the custom component lifecycle management. The sample code is as follows:
-
-When using `startAbility` to start an ability again, use the `uri` parameter in the `want` to pass the page information.
-```ts
-async function reStartAbility() {
- try {
- await this.context.startAbility({
- bundleName: "com.sample.MyApplication",
- abilityName: "MainAbility",
- uri: "pages/second"
- })
- console.log('start ability succeed')
- } catch (error) {
- console.error(`start ability failed with ${error.code}`)
- }
-}
-```
-
-Obtain the `want` parameter that contains the page information from the `onNewWant` callback of the ability.
-```ts
-import Ability from '@ohos.application.Ability'
-
-export default class MainAbility extends Ability {
- onNewWant(want, launchParams) {
- globalThis.newWant = want
- }
-}
-```
-
-Obtain the `want` parameter that contains the page information from the custom component and process the route based on the URI.
-```ts
-import router from '@ohos.router'
-
-@Entry
-@Component
-struct Index {
- newWant = undefined
-
- onPageShow() {
- console.info('Index onPageShow')
- let newWant = globalThis.newWant
- if (newWant.hasOwnProperty("uri")) {
- router.push({ uri: newWant.uri });
- globalThis.newWant = undefined
- }
- }
-}
-```
diff --git a/en/application-dev/ability/stage-brief.md b/en/application-dev/ability/stage-brief.md
deleted file mode 100644
index 0b4bfe8e3ec2943528e3bd2e8b640dea4ffbd070..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-brief.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# Stage Model Overview
-
-## Design Ideas
-
-The stage model is designed to make it easier to develop complex applications in the distributed environment.
-
-The following figure shows the design ideas of the stage model.
-
-
-
-The stage model is designed based on the following considerations:
-
-- **Balance between application capabilities and overall system power consumption**
-
- On a running device, resources are preferentially guaranteed for foreground applications, on the prerequisites that the overall power consumption requirements of the system are met. The stage model balances the application capabilities and overall system power consumption through ability and UI separation, strict background control, scenario-based service mechanism, and single-process model.
-
-- **Native support for component continuation and collaboration**
-
- OpenHarmony natively supports distributed deployment. Therefore, its application framework must be designed for easier component migration and collaboration. The stage model achieves this design objective by providing features such as separation between ability and UI as well as integration of UI display and service capabilities.
-
-- **Support for multiple device types and window forms**
-
- To support multiple device types and facilitate the implementation of different window forms, the component manager and window manager must be decoupled at the architecture layer for easier tailoring. To achieve this goal, the stage model redefines the ability lifecycle and implements unidirectional dependency for the component manager and window manager.
-
-
-## Basic Concepts
-
-The following figure shows the basic concepts in the stage model.
-
-
-
-- **HAP**: Harmony Ability Package, also called module, which is the basic unit for building, distributing, and loading OpenHarmony applications. Each HAP has a unique name, which is called **moduleName**, in an application.
-- **Bundle**: an OpenHarmony application identified by **appid**. A bundle can contain multiple HAP files. Each application has a **bundleName**. However, **bundleName** must be used together with **appid** and other information to uniquely identify an application.
-- **AbilityStage**: runtime class of an HAP. It is created when the HAP is loaded to the process for the first time and is visible to developers in the runtime.
-- **Application**: runtime class of a bundle, which is invisible to developers in the runtime.
-- **Context**: base class that the context classes of **Ability** and **ExtensionAbility** classes inherit. This class provides various capabilities that can be invoked by developers in the runtime, and various information such as the bundle name, module name, and path.
-- **Ability**: class that provides lifecycle callbacks, holds the **AbilityContext** class, and supports component continuation and collaboration.
-- **ExtensionAbility**: general name of scenario-based service extension abilities. The system defines multiple scenario-based **ExtensionAbility** classes, each of which has its own **ExtensionContext**.
-- **WindowStage**: local window manager.
-- **Window**: basic unit managed by the window manager. It has an ArkUI engine instance.
-- **ArkUI Page**: ArkUI development framework page.
-
-
-## Lifecycle
-
-The ability and ability stage lifecycles are the rudiments of the basic process of an application. For details about how these lifecycles differ from those in the FA model, see [Ability Framework Overview](ability-brief.md). This section focuses on the ability lifecycle transition and the scheduling relationships between the ability, ability stage, and window stage.
-
-
-
-To implement device-specific tailoring and multi-window scalability, OpenHarmony decouples the component manager from the window manager. The ability lifecycle defined in the stage model includes only the creation, destruction, foreground, and background states. The gain focus and lose focus states that are closely related to UI content are defined in the window stage. This implements weak coupling between the abilities and windows. On the service side, the window manager notifies the component manager of the foreground and background changes, so the component manager only senses the foreground and background changes but not the focus changes.
-
-
-## Ability Instances and Missions
-
-Abilities can be started in any of the following modes:
-
-+ **Singleton**: For each type of ability, only one instance exists in the application process. **Ability1** in the figure below is started in singleton mode.
-
-+ **Standard**: Each time **startAbility** is called, an instance of the specified ability type is created in the application process. **Ability2** in the figure below is started in standard mode.
-
-+ **Specified**: Before creating an **AbilityRecord**, you can create a key for the instance. Each time **startAbility** is called, the system asks the application which ability instance (corresponding to a key) will be used. **Ability3** in the figure below is started in specified mode.
-
-Each ability instance corresponds to a mission in **Launcher Recent**.
-
-The mission corresponding to an ability instance has a snapshot of the ability instance. After the ability instance is destroyed, the ability class information and snapshot are retained in the mission until the user deletes the information or the storage space reaches the upper limit.
-
- 
-
-## ExtensionAbility Mechanism
-
-Different from the ability used for page display, the extension ability provides a restricted service running environment. It has the following features:
-
-- Its process runs independently from the main process and shares the same storage sandbox with the main process. There is no inter-process communication (IPC) between the process and the main process.
-
-- It has an independent context that provides scenario-specific APIs.
-
-- It is created by the system, rather than by applications.
-
-- The lifecycles of the extension ability and process are managed by the system.
-
-The following figure uses the widget scenario as an example. You can inherit from the **FormExtensionAbility** base class to provide the widget details. The lifecycle of the **FormExtensionAbility** instance and that of the extension ability process where the instance is located are managed by **FormManagerService**, which is a system service.
-
-
-
-## Process Model
-
-All OpenHarmony applications are designed to meet the single-process model. In the single-process model, all processes in the application are created and managed by the system. Each application supports a maximum of three types of processes:
-
-- Main process: runs all ability components, pages, and service logic.
-
-- Extension process: runs classes derived from **ExtensionAbility** in the application. The lifecycle of this process is managed by a scenario-specific system service.
-
-- Render process: created for the WebView and used to load the WebView rendering library.
-
- The following figure shows the process model of an application.
-
- 
diff --git a/en/application-dev/ability/stage-call.md b/en/application-dev/ability/stage-call.md
deleted file mode 100644
index 390e1b6c3ce5393956d0a7801f362ab7f49578a4..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-call.md
+++ /dev/null
@@ -1,284 +0,0 @@
-# Ability Call Development
-## When to Use
-Ability call is an extension of the ability capability. It enables an ability to be invoked by and communicate with external systems. The ability invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two abilities (caller ability and callee ability) through inter-process communication (IPC).
-
-The core API used for the ability call is `startAbilityByCall`, which differs from `startAbility` in the following ways:
- - `startAbilityByCall` supports ability startup in the foreground and background, whereas `startAbility` supports ability startup in the foreground only.
- - The caller ability can use the `Caller` object returned by `startAbilityByCall` to communicate with the callee ability, but `startAbility` does not provide the communication capability.
-
-Ability call is usually used in the following scenarios:
-- Communicating with the callee ability
-- Starting the callee ability in the background
-
-**Table 1** Terms used in the ability call
-|Term|Description|
-|:------|:------|
-|Caller ability|Ability that triggers the ability call.|
-|Callee ability|Ability invoked by the ability call.|
-|Caller |Object returned by `startAbilityByCall` and used by the caller ability to communicate with the callee ability.|
-|Callee |Object held by the callee ability to communicate with the caller ability.|
-|IPC |Inter-process communication.|
-
-The ability call process is as follows:
- - The caller ability uses `startAbilityByCall` to obtain a `Caller` object and uses `call()` of the `Caller` object to send data to the callee ability.
- - The callee ability, which holds a `Callee` object, uses `on()` of the `Callee` object to register a callback. This callback is invoked when the callee ability receives data from the caller ability.
-
-
-> **NOTE**
-> The launch type of the callee ability must be `singleton`.
-> Currently, only system applications can use the ability call.
-
-## Available APIs
-The table below describes the ability call APIs. For details, see [Ability](../reference/apis/js-apis-application-ability.md#caller).
-
-**Table 2** Ability call APIs
-|API|Description|
-|:------|:------|
-|startAbilityByCall(want: Want): Promise\|Starts an ability in the foreground (through the `want` configuration) or background (default) and obtains the `Caller` object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-service-extension-context.md#serviceextensioncontextstartabilitybycall).|
-|on(method: string, callback: CalleeCallBack): void|Callback invoked when the callee ability registers a method.|
-|off(method: string): void|Callback invoked when the callee ability deregisters a method.|
-|call(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability.|
-|callWithResult(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.|
-|release(): void|Releases the `Caller` object.|
-|onRelease(callback: OnReleaseCallBack): void|Callback invoked when the `Caller` object is released.|
-
-## How to Develop
-The procedure for developing the ability call is as follows:
-1. Create a callee ability.
-2. Access the callee ability.
-> **NOTE**
->
-> The code snippets provided in the **How to Develop** section are used to show specific development steps. They may not be able to run independently.
-### Creating a Callee Ability
-For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use `on()` to register a listener. When data does not need to be received, use `off()` to deregister the listener.
-**1. Configure the ability launch type.**
-
- Set `launchType` of the callee ability to `singleton` in the `module.json5` file.
-
-|JSON Field|Description|
-|:------|:------|
-|"launchType"|Ability launch type. Set this parameter to `singleton`.|
-
-An example of the ability configuration is as follows:
-```json
-"abilities":[{
- "name": ".CalleeAbility",
- "srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
- "launchType": "singleton",
- "description": "$string:CalleeAbility_desc",
- "icon": "$media:icon",
- "label": "$string:CalleeAbility_label",
- "visible": true
-}]
-```
-**2. Import the Ability module.**
-```ts
-import Ability from '@ohos.application.Ability'
-```
-**3. Define the agreed sequenceable data.**
-
- The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. The code snippet is as follows:
-```ts
-export default class MySequenceable {
- num: number = 0
- str: string = ""
-
- constructor(num, string) {
- this.num = num
- this.str = string
- }
-
- marshalling(messageParcel) {
- messageParcel.writeInt(this.num)
- messageParcel.writeString(this.str)
- return true
- }
-
- unmarshalling(messageParcel) {
- this.num = messageParcel.readInt()
- this.str = messageParcel.readString()
- return true
- }
-}
-```
-**4. Implement `Callee.on` and `Callee.off`.**
-
- The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the `MSG_SEND_METHOD` listener is registered in `onCreate` of the ability and deregistered in `onDestroy`. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The code snippet is as follows:
-```ts
-const TAG: string = '[CalleeAbility]'
-const MSG_SEND_METHOD: string = 'CallSendMsg'
-
-function sendMsgCallback(data) {
- console.log('CalleeSortFunc called')
-
- // Obtain the sequenceable data sent by the caller ability.
- let receivedData = new MySequenceable(0, '')
- data.readSequenceable(receivedData)
- console.log(`receiveData[${receivedData.num}, ${receivedData.str}]`)
-
- // Process the data.
- // Return the sequenceable data result to the caller ability.
- return new MySequenceable(receivedData.num + 1, `send ${receivedData.str} succeed`)
-}
-
-export default class CalleeAbility extends Ability {
- onCreate(want, launchParam) {
- try {
- this.callee.on(MSG_SEND_METHOD, sendMsgCallback)
- } catch (error) {
- console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
- }
- }
-
- onDestroy() {
- try {
- this.callee.off(MSG_SEND_METHOD)
- } catch (error) {
- console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`)
- }
- }
-}
-```
-
-### Accessing the Callee Ability
-**1. Import the Ability module.**
-```ts
-import Ability from '@ohos.application.Ability'
-```
-**2. Obtain the `Caller` object.**
-
- The `context` attribute of the ability implements `startAbilityByCall` to obtain the `Caller` object for communication. The following example uses `this.context` to obtain the `context` attribute of the ability, uses `startAbilityByCall` to start the callee ability, obtain the `Caller` object, and register the `onRelease` listener of the caller ability. You need to implement processing based on service requirements. The code snippet is as follows:
-```ts
-// Register the onRelease listener of the caller ability.
-private regOnRelease(caller) {
- try {
- caller.onRelease((msg) => {
- console.log(`caller onRelease is called ${msg}`)
- })
- console.log('caller register OnRelease succeed')
- } catch (error) {
- console.log(`caller register OnRelease failed with ${error}`)
- }
-}
-
-async onButtonGetCaller() {
- try {
- this.caller = await context.startAbilityByCall({
- bundleName: 'com.samples.CallApplication',
- abilityName: 'CalleeAbility'
- })
- if (this.caller === undefined) {
- console.log('get caller failed')
- return
- }
- console.log('get caller success')
- this.regOnRelease(this.caller)
- } catch (error) {
- console.log(`get caller failed with ${error}`)
- }
-}
-```
- In the cross-device scenario, you need to specify the ID of the peer device. The code snippet is as follows:
-```ts
-async onButtonGetRemoteCaller() {
- var caller = undefined
- var context = this.context
-
- context.startAbilityByCall({
- deviceId: getRemoteDeviceId(),
- bundleName: 'com.samples.CallApplication',
- abilityName: 'CalleeAbility'
- }).then((data) => {
- if (data != null) {
- caller = data
- console.log('get remote caller success')
- // Register the onRelease listener of the caller ability.
- caller.onRelease((msg) => {
- console.log(`remote caller onRelease is called ${msg}`)
- })
- console.log('remote caller register OnRelease succeed')
- }
- }).catch((error) => {
- console.error(`get remote caller failed with ${error}`)
- })
-}
-```
- Obtain the ID of the peer device from `DeviceManager`. Note that the `getTrustedDeviceListSync` API is open only to system applications. The code snippet is as follows:
-```ts
-import deviceManager from '@ohos.distributedHardware.deviceManager';
-var dmClass;
-function getRemoteDeviceId() {
- if (typeof dmClass === 'object' && dmClass != null) {
- var list = dmClass.getTrustedDeviceListSync()
- if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null")
- return
- }
- console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId)
- return list[0].deviceId
- } else {
- console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null")
- }
-}
-```
- In the cross-device scenario, your application must also apply for the data synchronization permission from end users. The code snippet is as follows:
-```ts
-requestPermission() {
- let context = this.context
- let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']
- context.requestPermissionsFromUser(permissions).then((data) => {
- console.log("Succeed to request permission from user with data: "+ JSON.stringify(data))
- }).catch((error) => {
- console.log("Failed to request permission from user with error: "+ JSON.stringify(error))
- })
-}
-```
-**3. Send agreed sequenceable data.**
-
- The sequenceable data can be sent to the callee ability with or without a return value. The method and sequenceable data must be consistent with those of the callee ability. The following example describes how to send data to the callee ability. The code snippet is as follows:
-```ts
-const MSG_SEND_METHOD: string = 'CallSendMsg'
-async onButtonCall() {
- try {
- let msg = new MySequenceable(1, 'origin_Msg')
- await this.caller.call(MSG_SEND_METHOD, msg)
- } catch (error) {
- console.log(`caller call failed with ${error}`)
- }
-}
-```
-
- In the following, `CallWithResult` is used to send data `originMsg` to the callee ability and assign the data processed by the `CallSendMsg` method to `backMsg`. The code snippet is as follows:
-```ts
-const MSG_SEND_METHOD: string = 'CallSendMsg'
-originMsg: string = ''
-backMsg: string = ''
-async onButtonCallWithResult(originMsg, backMsg) {
- try {
- let msg = new MySequenceable(1, originMsg)
- const data = await this.caller.callWithResult(MSG_SEND_METHOD, msg)
- console.log('caller callWithResult succeed')
-
- let result = new MySequenceable(0, '')
- data.readSequenceable(result)
- backMsg(result.str)
- console.log(`caller result is [${result.num}, ${result.str}]`)
- } catch (error) {
- console.log(`caller callWithResult failed with ${error}`)
- }
-}
-```
-**4. Release the `Caller` object.**
-
- When the `Caller` object is no longer required, use `release()` to release it. The code snippet is as follows:
-```ts
-releaseCall() {
- try {
- this.caller.release()
- this.caller = undefined
- console.log('caller release succeed')
- } catch (error) {
- console.log(`caller release failed with ${error}`)
- }
-}
-```
diff --git a/en/application-dev/ability/stage-formextension.md b/en/application-dev/ability/stage-formextension.md
deleted file mode 100644
index fa90f267c13c0fa002233f585ca7c6b3c9904637..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-formextension.md
+++ /dev/null
@@ -1,415 +0,0 @@
-# Stage Widget Development
-
-## Widget Overview
-
-A widget is a set of UI components used to display important information or operations for an application. It provides users with direct access to a desired application service, without requiring them to open the application.
-
-A widget displays brief information about an application on the UI of another application (host application, currently system applications only) and provides basic interactive functions such as opening a UI page or sending a message.
-
-Basic concepts:
-
-- Widget provider: an atomic service that controls what and how content is displayed in a widget and interacts with users.
-- Widget host: an application that displays the widget content and controls the position where the widget is displayed in the host application.
-- Widget Manager: a resident agent that manages widgets added to the system and provides functions such as periodic widget update.
-
-> **NOTE**
->
-> The widget host and provider do not keep running all the time. The Widget Manager starts the widget provider to obtain widget information when a widget is added, deleted, or updated.
-
-You only need to develop widget content as the widget provider. The system automatically handles the work done by the widget host and Widget Manager.
-
-The widget provider controls the widget content to display, component layout, and click events bound to components.
-
-## When to Use
-
-Stage widget development refers to the development conducted by the widget provider based on the [stage model](stage-brief.md). As a widget provider, you need to carry out the following operations:
-
-- Develop the lifecycle callbacks in **FormExtension**.
-- Create a **FormBindingData** instance.
-- Update a widget through **FormProvider**.
-- Develop the widget UI page.
-
-## Available APIs
-
-The **FormExtension** class has the following APIs. For details, see [FormExtension](../reference/apis/js-apis-formextension.md).
-
-**Table 1** FormExtension APIs
-
-| API | Description |
-| :----------------------------------------------------------- | :------------------------------------------- |
-| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a **Form** instance (widget) has been created. |
-| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.|
-| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. |
-| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. |
-| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. |
-| onDestroy(formId: string): void | Called to notify the widget provider that a **Form** instance (widget) has been destroyed. |
-| onConfigurationUpdated(config: Configuration): void; | Called when the configuration of the environment where the widget is running is updated. |
-
-The **FormExtension** class also has a member context, that is, the **FormExtensionContext** class. For details, see [FormExtensionContext](../reference/apis/js-apis-formextensioncontext.md).
-
-**Table 2** FormExtensionContext APIs
-
-| API | Description |
-| :----------------------------------------------------------- | :----------------------------------------------------------- |
-| startAbility(want: Want, callback: AsyncCallback<void>): void | Starts an ability. This API uses an asynchronous callback to return the result. (This is a system API and cannot be called by third-party applications.)|
-| startAbility(want: Want): Promise<void> | Starts an ability. This API uses a promise to return the result. (This is a system API and cannot be called by third-party applications.)|
-
-For details about the **FormProvider** APIs, see [FormProvider](../reference/apis/js-apis-formprovider.md).
-
-**Table 3** FormProvider APIs
-
-| API | Description |
-| :----------------------------------------------------------- | :------------------------------------------------ |
-| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. |
-| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.|
-| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. |
-| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. |
-
-## How to Develop
-
-### Creating a FormExtension Instance
-
-To create a widget in the stage model, implement the lifecycle callbacks of **FormExtension**. The sample code is as follows:
-
-1. Import the required modules.
-
- ```javascript
- import FormExtension from '@ohos.application.FormExtension'
- import formBindingData from '@ohos.application.formBindingData'
- import formInfo from '@ohos.application.formInfo'
- import formProvider from '@ohos.application.formProvider'
- ```
-
-2. Implement the lifecycle callbacks of **FormExtension**.
-
- ```javascript
- export default class FormAbility extends FormExtension {
- onCreate(want) {
- console.log('FormAbility onCreate');
- // Persistently store widget information for subsequent use, such as widget instance retrieval or update.
- let obj = {
- "title": "titleOnCreate",
- "detail": "detailOnCreate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- return formData;
- }
- onCastToNormal(formId) {
- // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
- console.log('FormAbility onCastToNormal');
- }
- onUpdate(formId) {
- // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
- console.log('FormAbility onUpdate');
- let obj = {
- "title": "titleOnUpdate",
- "detail": "detailOnUpdate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- formProvider.updateForm(formId, formData).catch((error) => {
- console.log('FormAbility updateForm, error:' + JSON.stringify(error));
- });
- }
- onVisibilityChange(newStatus) {
- // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification.
- console.log('FormAbility onVisibilityChange');
- }
- onEvent(formId, message) {
- // If the widget supports event triggering, override this method and implement the trigger.
- console.log('FormAbility onEvent');
- }
- onDestroy(formId) {
- // Delete widget data.
- console.log('FormAbility onDestroy');
- }
- onConfigurationUpdated(config) {
- console.log('FormAbility onConfigurationUpdated, config:' + JSON.stringify(config));
- }
- }
- ```
-
-### Configuring the Widget Configuration File
-
-- Configure Extension ability information under **extensionAbilities** in the **module.json5** file. The internal field structure is described as follows:
-
- | Field | Description | Data Type | Default |
- | ----------- | ------------------------------------------------------------ | ---------- | -------------------- |
- | name | Name of the Extension ability. This field must be specified. | String | No |
- | srcEntrance | Path of the Extension ability lifecycle code. This field must be specified.| String | No |
- | description | Description of the Extension ability. The value can be a string or a resource index to descriptions in multiple languages.| String | Yes (initial value: left empty)|
- | icon | Index of the Extension ability icon file. | String | Yes (initial value: left empty)|
- | label | Descriptive information about the Extension ability presented externally. The value can be a string or a resource index to the description.| String | Yes (initial value: left empty)|
- | type | Type of the Extension ability. In the current development scenario, set this field to **form**.| String | No |
- | permissions | Permissions required for abilities of another application to call the current ability. | String array| Yes (initial value: left empty)|
- | metadata | Metadata (configuration information) of the Extension ability.| Object | Yes (initial value: left empty) |
-
- For a Form Extension ability, you must specify **metadata**. Specifically, set **name** to **ohos.extension.form** (fixed), and set **resource** to the index of the widget configuration information.
-
- A configuration example is as follows:
-
- ```json
- "extensionAbilities": [{
- "name": "FormAbility",
- "srcEntrance": "./ets/FormAbility/FormAbility.ts",
- "label": "$string:form_FormAbility_label",
- "description": "$string:form_FormAbility_desc",
- "type": "form",
- "metadata": [{
- "name": "ohos.extension.form",
- "resource": "$profile:form_config"
- }]
- }]
- ```
-
-- Configure the widget configuration information. **resource** in **metadata** specifies the index of the widget configuration information. For example, **$profile:form_config** means that **form_config.json** in the **resources/base/profile/** directory of the development view is used as the widget profile configuration file.
-
- The internal field structure is described as follows:
-
- | Field | Description | Data Type | Default |
- | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ |
- | name | Class name of a widget. The value is a string with a maximum of 127 bytes. | String | No |
- | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) |
- | src | Full path of the UI code corresponding to the widget. | String | No |
- | window | Window-related configurations. | Object | Yes |
- | isDefault | Whether the widget is a default one. Each ability has only one default widget. **true**: The widget is the default one. **false**: The widget is not the default one.| Boolean | No |
- | colorMode | Color mode of the widget. Available values are as follows: **auto**: The widget adopts the auto-adaptive color mode. **dark**: The widget adopts the dark color mode. **light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)|
- | supportDimensions | Grid styles supported by the widget. Available values are as follows: **1 * 2**: indicates a grid with one row and two columns. **2 * 2**: indicates a grid with two rows and two columns. **2 * 4**: indicates a grid with two rows and four columns. **4 * 4**: indicates a grid with four rows and four columns.| String array| No |
- | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No |
- | updateEnabled | Whether the widget can be updated periodically. Available values are as follows: **true**: The widget can be updated periodically, depending on the update way you select, either at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** is recommended. **false**: The widget cannot be updated periodically.| Boolean | No |
- | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute. This parameter has a lower priority than **updateDuration**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) |
- | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes. If the value is **0**, this field does not take effect. If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes. This parameter has a higher priority than **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) |
- | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) |
- | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) |
- | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) |
-
- A configuration example is as follows:
-
- ```json
- {
- "forms": [{
- "name": "widget",
- "description": "This is a widget.",
- "src": "./js/widget/pages/index/index",
- "window": {
- "autoDesignWidth": true,
- "designWidth": 720
- },
- "isDefault": true,
- "colorMode": "auto",
- "supportDimensions": ["2*2"],
- "defaultDimension": "2*2",
- "updateEnabled": true,
- "scheduledUpdateTime": "10:30",
- "formConfigAbility": "ability://ohos.samples.FormApplication.MainAbility"
- }]
- }
- ```
-
-
-### Persistently Storing Widget Data
-
-Mostly, the widget provider is started only when it needs to obtain information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting the widget.
-
-```javascript
- onCreate(want) {
- console.log('FormAbility onCreate');
-
- let formId = want.parameters["ohos.extra.param.key.form_identity"];
- let formName = want.parameters["ohos.extra.param.key.form_name"];
- let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
- // Persistently store widget data for subsequent use, such as widget instance retrieval or update.
- // The storeFormInfo API is not implemented here.
- storeFormInfo(formId, formName, tempFlag, want);
-
- let obj = {
- "title": "titleOnCreate",
- "detail": "detailOnCreate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- return formData;
- }
-```
-
-You should override **onDestroy** to delete widget data.
-
-```javascript
- onDestroy(formId) {
- console.log('FormAbility onDestroy');
-
- // You need to implement the code for deleting the persistent widget data.
- // The deleteFormInfo API is not implemented here.
- deleteFormInfo(formId);
- }
-```
-
-For details about the persistence method, see [Lightweight Data Store Development](../database/database-preference-guidelines.md).
-
-Note that the **Want** passed by the widget host to the widget provider contains a temporary flag, indicating whether the requested widget is a temporary one.
-
-- Normal widget: a widget that will be persistently used by the widget host
-
-- Temporary widget: a widget that is temporarily used by the widget host
-
-Data of a temporary widget is not persistently stored. If it is deleted from the Widget Manager due to exceptions, such as crash of the widget framework, the widget provider will not be notified of which widget is deleted, and still keeps the data. In light of this, the widget provider should implement data clearing. If the widget host successfully converts a temporary widget into a normal one, the widget provider should also process the widget ID and store the data persistently. This prevents the widget provider from deleting the widget data when clearing temporary widgets.
-
-### Updating Widget Data
-
-When a widget application initiates a data update upon a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The sample code is as follows:
-
-```javascript
-onUpdate(formId) {
- // To support scheduled update, periodic update, or update requested by the widget host, override this method for widget data update.
- console.log('FormAbility onUpdate');
- let obj = {
- "title": "titleOnUpdate",
- "detail": "detailOnUpdate"
- };
- let formData = formBindingData.createFormBindingData(obj);
- // Call the updateForm method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged.
- formProvider.updateForm(formId, formData).catch((error) => {
- console.log('FormAbility updateForm, error:' + JSON.stringify(error));
- });
-}
-```
-
-### Developing the Widget UI Page
-
-You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget.
-
-> **NOTE**
->
-> Currently, only the JavaScript-based web-like development paradigm can be used to develop the widget UI.
-
- - In the HML file:
- ```html
-
-
-
-
-
-
- {{title}}
- {{detail}}
-
-
-
- ```
-
- - In the CSS file:
-
- ```css
-.container {
- flex-direction: column;
- justify-content: center;
- align-items: center;
-}
-
-.bg-img {
- flex-shrink: 0;
- height: 100%;
-}
-
-.container-inner {
- flex-direction: column;
- justify-content: flex-end;
- align-items: flex-start;
- height: 100%;
- width: 100%;
- padding: 12px;
-}
-
-.title {
- font-size: 19px;
- font-weight: bold;
- color: white;
- text-overflow: ellipsis;
- max-lines: 1;
-}
-
-.detail_text {
- font-size: 16px;
- color: white;
- opacity: 0.66;
- text-overflow: ellipsis;
- max-lines: 1;
- margin-top: 6px;
-}
- ```
-
- - In the JSON file:
- ```json
- {
- "data": {
- "title": "TitleDefault",
- "detail": "TextDefault"
- },
- "actions": {
- "routerEvent": {
- "action": "router",
- "abilityName": "MainAbility",
- "params": {
- "message": "add detail"
- }
- }
- }
- }
- ```
-
-Now you've got a widget shown below.
-
-
-
-### Developing Widget Events
-
-You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows:
-
-1. Set **onclick** in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
-2. For the router event, set the following attributes:
- - **action**: **"router"**.
- - **abilityName**: target ability name, for example, **MainAbility**, which is the default main ability name in DevEco Studio for the stage model.
- - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the stage model, you can obtain **want** and its **parameters** field.
-3. For the message event, set the following attributes:
- - **action**: **"message"**.
- - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**.
-
-The following is an example:
-
- - In the HML file:
- ```html
-
-
-
-
-
-
- {{title}}
- {{detail}}
-
-
-
- ```
-
- - In the JSON file:
- ```json
- {
- "data": {
- "title": "TitleDefault",
- "detail": "TextDefault"
- },
- "actions": {
- "routerEvent": {
- "action": "router",
- "abilityName": "MainAbility",
- "params": {
- "message": "add detail"
- }
- },
- "messageEvent": {
- "action": "message",
- "params": {
- "message": "add detail"
- }
- }
- }
- }
- ```
\ No newline at end of file
diff --git a/en/application-dev/ability/stage-serviceextension.md b/en/application-dev/ability/stage-serviceextension.md
deleted file mode 100644
index 0d634ebe67ef9e332f658a0efb0f7ffdb0e1f2b7..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/stage-serviceextension.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Service Extension Ability Development
-
-## When to Use
-`ExtensionAbility` is the base class of the new Extension component in the stage model. It is used to process missions without UIs. The lifecycle of an Extension ability is simple and does not involve foreground or background states. `ServiceExtensionAbility` is extended from `ExtensionAbility`.
-
-You can customize a class that inherits from `ServiceExtensionAbility` and override the lifecycle callbacks in the base class to perform service logic operations during the initialization, connection, and disconnection processes.
-
-## Available APIs
-
-**Table 1** ServiceExtensionAbility lifecycle APIs
-|API|Description|
-|:------|:------|
-|onCreate(want: Want): void|Called for the initialization when `startAbility` or `connectAbility` is invoked for a given ability for the first time.|
-|onRequest(want: Want, startId: number): void|Called each time `startAbility` is invoked for a given ability. The initial value of `startId` is `1`, and the value is incremented by one each time `startAbility` is invoked for that ability.|
-|onConnect(want: Want): rpc.RemoteObject|Called when `connectAbility` is invoked for a given ability. This callback is not invoked for repeated calling of `connectAbility` for a specific ability. However, it will be invoked unless `connectAbility` is called after the ability has been disconnected using `disconnectAbility`. The returned result is a `RemoteObject`.|
-|onDisconnect(want: Want): void|Called when `disconnectAbility` is called for a given ability. If the Extension ability is started by `connectAbility` and is not bound to other applications, the `onDestroy` callback will also be triggered to destroy the Extension ability.|
-|onDestroy(): void|Called when `terminateSelf` is invoked to terminate the ability.|
-
-
-## Constraints
-
-OpenHarmony does not support creation of a Service Extension ability for third-party applications.
-
-
-## How to Develop
-
-1. Declare the Service Extension ability in the `module.json5` file by setting its `type` attribute to `service`. The following is a configuration example of the `module.json5` file:
-
-
- ```json
- "extensionAbilities":[{
- "name": "ServiceExtAbility",
- "icon": "$media:icon",
- "description": "service",
- "type": "service",
- "visible": true,
- "srcEntrance": "./ets/ServiceExtAbility/ServiceExtAbility.ts"
- }]
- ```
-
-
-2. Customize a class that inherits from `ServiceExtensionAbility` in the .ts file in the directory where the Service Extension ability is defined (`entry\src\main\ets\ServiceExtAbility\ServiceExtAbility.ts` by default) and override the lifecycle callbacks of the base class. The code sample is as follows:
-
- ```js
- import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility'
- import rpc from '@ohos.rpc'
-
- class StubTest extends rpc.RemoteObject {
- constructor(des) {
- super(des);
- }
- onRemoteRequest(code, data, reply, option) {
- }
- }
-
- class ServiceExtAbility extends ServiceExtensionAbility {
- onCreate(want) {
- console.log('onCreate, want:' + want.abilityName);
- }
- onRequest(want, startId) {
- console.log('onRequest, want:' + want.abilityName);
- }
- onConnect(want) {
- console.log('onConnect , want:' + want.abilityName);
- return new StubTest("test");
- }
- onDisconnect(want) {
- console.log('onDisconnect, want:' + want.abilityName);
- }
- onDestroy() {
- console.log('onDestroy');
- }
- }
- ```
\ No newline at end of file
diff --git a/en/application-dev/ability/wantagent.md b/en/application-dev/ability/wantagent.md
deleted file mode 100644
index 5a85bab15b8422aaabb0a173ad888126e08fc038..0000000000000000000000000000000000000000
--- a/en/application-dev/ability/wantagent.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# WantAgent Development
-## When to Use
-The **WantAgent** class encapsulates want information that specifies a particular action, which can be starting an ability or publishing a common event. You can either call **wantAgent.trigger** to trigger a **WantAgent** directly or add a **WantAgent** to a notification so that it will be triggered when users tap the notification.
-
-
-
-## Available APIs
-| API | Description|
-| ---------------------------------------------------------------------------------------------- | ----------- |
-| getWantAgentInfo(info: WantAgentInfo, callback: AsyncCallback\) | Creates a **WantAgent** object. This API uses an asynchronous callback to return the result.|
-| getWantAgent(info: WantAgentInfo): Promise\ | Creates a **WantAgent** object. This API uses a promise to return the result.|
-| trigger(agent: WantAgent, triggerInfo: TriggerInfo, callback?: Callback\) | Triggers a **WantAgent** object.|
-
-## How to Develop
-1. Import the **WantAgent** module.
-
- ```
- import wantAgent from '@ohos.wantAgent';
- ```
-
-2. Create a **WantAgentInfo** object that will be used for starting an ability. For details about the data types and parameters of **WantAgentInfo**, see [WantAgent](../reference/apis/js-apis-wantAgent.md#wantagentinfo).
-
- ```
- private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
-
- // wantAgentInfo
- var wantAgentInfo = {
- wants: [
- {
- deviceId: "",
- bundleName: "com.example.test",
- abilityName: "com.example.test.MainAbility",
- action: "",
- entities: [],
- uri: "",
- parameters: {}
- }
- ],
- operationType: wantAgent.OperationType.START_ABILITY,
- requestCode: 0,
- wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
- }
- ```
-
-3. Create a **WantAgentInfo** object for publishing a common event.
-
- ```
- private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
-
- // wantAgentInfo
- var wantAgentInfo = {
- wants: [
- {
- action: "event_name", // Set the action name.
- parameters: {}
- }
- ],
- operationType: wantAgent.OperationType.SEND_COMMON_EVENT,
- requestCode: 0,
- wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
- }
- ```
-
-4. Create a **WantAgent** object and save the returned **wantAgentObj** for subsequent trigger operations.
-
- ```
- // Create a WantAgent object.
- wantAgent.getWantAgent(wantAgentInfo, (err, wantAgentObj) => {
- if (err.code) {
- console.error("[WantAgent]getWantAgent err=" + JSON.stringify(err))
- } else {
- console.log("[WantAgent]getWantAgent success")
- this.wantAgentObj = wantAgentObj
- }
- })
- ```
-
-5. Trigger the **WantAgent** object.
-
- ```
- // Trigger the WantAgent object.
- var triggerInfo = {
- code:0
- }
- wantAgent.trigger(wantAgentObj, triggerInfo, (completeData) => {
- console.log("[WantAgent]getWantAgent success, completeData: ", + JSON.stringify(completeData))
- })
- ```
diff --git a/en/application-dev/application-models/Readme-EN.md b/en/application-dev/application-models/Readme-EN.md
new file mode 100644
index 0000000000000000000000000000000000000000..a9473b7f6c2d0fb75e160cafdd1fb94b43633fa7
--- /dev/null
+++ b/en/application-dev/application-models/Readme-EN.md
@@ -0,0 +1,2 @@
+# Application Models
+
diff --git a/en/application-dev/application-test/Readme.md b/en/application-dev/application-test/Readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..7d465c149d73288be0687b15269152b743509432
--- /dev/null
+++ b/en/application-dev/application-test/Readme.md
@@ -0,0 +1,6 @@
+# Application Test
+
+- [arkXtest User Guide](arkxtest-guidelines.md)
+- [SmartPerf User Guide](smartperf-guidelines.md)
+- [wukong User Guide](wukong-guidelines.md)
+
diff --git a/en/application-dev/application-test/arkxtest-guidelines.md b/en/application-dev/application-test/arkxtest-guidelines.md
new file mode 100644
index 0000000000000000000000000000000000000000..ce7a28154635b724d127a50af801c74f84607402
--- /dev/null
+++ b/en/application-dev/application-test/arkxtest-guidelines.md
@@ -0,0 +1,270 @@
+# arkXtest User Guide
+
+
+## Overview
+
+To accelerate test automation of OpenHarmony, arkXtest — an automated test framework that supports both the JavaScript (JS) and TypeScript (TS) programming languages — is provided.
+
+In this document you will learn about the key functions of arkXtest and how to use it to perform unit testing on application or system APIs and to write UI automated test scripts.
+
+
+### Introduction
+
+arkXtest is part of the OpenHarmony toolkit and provides basic capabilities of writing and running OpenHarmony automated test scripts. In terms of test script writing, arkXtest offers a wide range of APIs, including basic process APIs, assertion APIs, and APIs related to UI operations. In terms of test script running, arkXtest offers such features as identifying, scheduling, and executing test scripts, as well as summarizing test script execution results.
+
+
+### Principles
+
+arkXtest is divided into two parts: unit test framework and UI test framework.
+
+- Unit Test Framework
+
+ As the backbone of arkXtest, the unit test framework offers such features as identifying, scheduling, and executing test scripts, as well as summarizing test script execution results. The figure below shows the main functions of the unit test framework.
+
+ 
+
+ The following figure shows the basic unit test process. To start the unit test framework, run the **aa test** command.
+
+ 
+
+- UI Testing Framework
+
+ The UI test framework provides [UiTest APIs](../reference/apis/js-apis-uitest.md) for you to call in different test scenarios. The test scripts are executed on top of the unit test framework mentioned above.
+
+ The figure below shows the main functions of the UI test framework.
+
+ 
+
+
+### Limitations and Constraints
+
+- The features of the UI test framework are available only in OpenHarmony 3.1 and later versions.
+- The feature availability of the unit test framework varies by version. For details about the mappings between the features and versions, see [arkXtest](https://gitee.com/openharmony/testfwk_arkxtest/blob/master/README_en.md).
+
+
+## Environment preparations
+
+### Environment Requirements
+
+Software for writing test scripts: DevEco Studio 3.0 or later
+
+Hardware for running test scripts: PC connected to a OpenHarmony device, such as the RK3568 development board
+
+### Setting Up the Environment
+
+[Download DevEco Studio](https://developer.harmonyos.com/cn/develop/deveco-studio#download) and set it up as instructed on the official website.
+
+
+## Creating a Test Script
+
+1. Open DevEco Studio and create a project, where the **ohos** directory is where the test script is located.
+2. Open the .ets file of the module to be tested in the project directory. Move the cursor to any position in the code, and then right-click and choose **Show Context Actions** > **Create Ohos Test** or press **Alt+Enter** and choose **Create Ohos Test** to create a test class.
+
+## Writing a Unit Test Script
+
+```TS
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'
+import abilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
+
+const delegator = abilityDelegatorRegistry.getAbilityDelegator()
+export default function abilityTest() {
+ describe('ActsAbilityTest', function () {
+ it('testUiExample',0, async function (done) {
+ console.info("uitest: TestUiExample begin");
+ //start tested ability
+ await delegator.executeShellCommand('aa start -b com.ohos.uitest -a MainAbility').then(result =>{
+ console.info('Uitest, start ability finished:' + result)
+ }).catch(err => {
+ console.info('Uitest, start ability failed: ' + err)
+ })
+ await sleep(1000);
+ //check top display ability
+ await delegator.getCurrentTopAbility().then((Ability)=>{
+ console.info("get top ability");
+ expect(Ability.context.abilityInfo.name).assertEqual('MainAbility');
+ })
+ done();
+ })
+
+ function sleep(time) {
+ return new Promise((resolve) => setTimeout(resolve, time));
+ }
+ })
+}
+```
+
+The unit test script must contain the following basic elements:
+
+1. Import of the dependency package so that the dependent test APIs can be used.
+
+2. Test code, mainly about the related logic, such as API invoking.
+
+3. Invoking of the assertion APIs and setting of checkpoints. If there is no checkpoint, the test script is considered as incomplete.
+
+## Writing a UI Test Script
+
+You write a UI test script based on the unit test framework, adding the invoking of APIs provided by the UI test framework to implement the corresponding test logic.
+
+In this example, the UI test script is written based on the preceding unit test script. First, add the dependency package, as shown below:
+
+```js
+import {UiDriver,BY,UiComponent,MatchPattern} from '@ohos.uitest'
+```
+
+Then, write specific test code. Specifically, implement the click action on the started application page and add checkpoint check cases.
+
+```js
+export default function abilityTest() {
+ describe('ActsAbilityTest', function () {
+ it('testUiExample',0, async function (done) {
+ console.info("uitest: TestUiExample begin");
+ //start tested ability
+ await delegator.executeShellCommand('aa start -b com.ohos.uitest -a MainAbility').then(result =>{
+ console.info('Uitest, start ability finished:' + result)
+ }).catch(err => {
+ console.info('Uitest, start ability failed: ' + err)
+ })
+ await sleep(1000);
+ //check top display ability
+ await delegator.getCurrentTopAbility().then((Ability)=>{
+ console.info("get top ability");
+ expect(Ability.context.abilityInfo.name).assertEqual('MainAbility');
+ })
+ //ui test code
+ //init uidriver
+ var driver = await UiDriver.create();
+ await driver.delayMs(1000);
+ //find button by text 'Next'
+ var button = await driver.findComponent(BY.text('Next'));
+ //click button
+ await button.click();
+ await driver.delayMs(1000);
+ //check text
+ await driver.assertComponentExist(BY.text('after click'));
+ await driver.pressBack();
+ done();
+ })
+
+ function sleep(time) {
+ return new Promise((resolve) => setTimeout(resolve, time));
+ }
+ })
+}
+```
+
+## Running the Test Script
+
+You can run a test script in DevEco Studio in any of the following modes:
+
+- Test package level: All test cases in the test package are executed.
+- Test suite level: All test cases defined in the **describe** method are executed.
+- Test method level: The specified **it** method, that is, a single test case, is executed.
+
+
+
+## Viewing the Test Result
+
+After the test is complete, you can view the test result in DevEco Studio, as shown in the following figure.
+
+
+
+## FAQs
+
+### FAQs About Unit Test Cases
+
+#### The logs in the test case are printed after the test case result
+
+**Problem**
+
+The logs added to the test case are displayed after the test case execution, rather than during the test case execution.
+
+**Possible Causes**
+
+More than one asynchronous interface is called in the test case. In principle, logs in the test case are printed before the test case execution is complete.
+
+ **Solution**
+
+If more than one asynchronous interface is called, you are advised to encapsulate the interface invoking into the promise mode
+
+#### Error "fail to start ability" is reported during test case execution
+
+**Problem**
+
+When a test case is executed, the console returns the error message "fail to start ability".
+
+**Possible Causes**
+
+An error occurs during the packaging of the test package, and the test framework dependency file is not included in the test package.
+
+**Solution**
+
+Check whether the test package contains the **OpenHarmonyTestRunner.abc** file. If the file does not exist, rebuild and pack the file and perform the test again.
+
+#### Test case execution timeout
+
+**Problem**
+
+After the test case execution is complete, the console displays the error message "execute time XXms", indicating that the case execution times out.
+
+**Possible Causes**
+
+1. The test case is executed through an asynchronous interface, but the **done** function is not executed during the execution. As a result, the test case execution does not end until it times out.
+2. The time taken for API invocation is longer than the timeout interval set for test case execution.
+
+**Solution**
+
+1. Check the code logic of the test case to ensure that the **done** function is executed even if the assertion fails.
+
+2. Modify the case execution timeout settings under **Run/Debug Configurations** in DevEco Studio.
+
+### FAQs About UI Test Cases
+
+#### The failure log contains "Get windows failed/GetRootByWindow failed"
+
+**Problem**
+
+The UI test case fails to be executed. The HiLog file contains the error message "Get windows failed/GetRootByWindow failed".
+
+**Possible Causes**
+
+The ArkUI feature is disabled. As a result, the control tree information on the test page is not generated.
+
+**Solution**
+
+Run the following command, restart the device, and execute the test case again:
+
+```shell
+hdc shell param set persist.ace.testmode.enabled 1
+```
+
+#### The failure log contains "uitest-api dose not allow calling concurrently"
+
+**Problem**
+
+The UI test case fails to be executed. The HiLog file contains the error message "uitest-api dose not allow calling concurrently".
+
+**Possible Causes**
+
+1. In the test case, the **await** operator is not added to the asynchronous interface provided by the UI test framework.
+
+2. The UI test case is executed in multiple processes. As a result, multiple UI test processes are started. The framework does not support multi-process invoking.
+
+**Solution**
+
+1. Check the case implementation and add the **await** operator to the asynchronous interface invoking.
+
+2. Do not execute UI test cases in multiple processes.
+
+#### The failure log contains "dose not exist on current UI! Check if the UI has changed after you got the widget object"
+
+**Problem**
+
+The UI test case fails to be executed. The HiLog file contains the error message "dose not exist on current UI! Check if the UI has changed after you got the widget object".
+
+**Possible Causes**
+
+After the target component is found in the code of the test case, the device UI changes. As a result, the found component is lost and the emulation operation cannot be performed.
+
+**Solution**
+
+Run the UI test case again.
diff --git a/en/application-dev/application-test/figures/Execute.PNG b/en/application-dev/application-test/figures/Execute.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..90dcb55338ad473d29557e4c761801b16c770d45
Binary files /dev/null and b/en/application-dev/application-test/figures/Execute.PNG differ
diff --git a/en/application-dev/application-test/figures/SmartPerfStru.png b/en/application-dev/application-test/figures/SmartPerfStru.png
new file mode 100644
index 0000000000000000000000000000000000000000..24d203f938891e5a2b73c066776c62b1065fd064
Binary files /dev/null and b/en/application-dev/application-test/figures/SmartPerfStru.png differ
diff --git a/en/application-dev/application-test/figures/TestFlow.PNG b/en/application-dev/application-test/figures/TestFlow.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..0b79c7e8c34e78397f1c442208de5dbff9c2e91e
Binary files /dev/null and b/en/application-dev/application-test/figures/TestFlow.PNG differ
diff --git a/en/application-dev/application-test/figures/TestResult.PNG b/en/application-dev/application-test/figures/TestResult.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..300266842efab6da7a4f7469ab8c9e890f238b89
Binary files /dev/null and b/en/application-dev/application-test/figures/TestResult.PNG differ
diff --git a/en/application-dev/application-test/figures/Uitest.PNG b/en/application-dev/application-test/figures/Uitest.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..a9ff5b9d831b4abe1767219dfa8e2fffc5c2e3f8
Binary files /dev/null and b/en/application-dev/application-test/figures/Uitest.PNG differ
diff --git a/en/application-dev/application-test/figures/UnitTest.PNG b/en/application-dev/application-test/figures/UnitTest.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..d55de62d830df9cfdf345552c54dbf4196564ef6
Binary files /dev/null and b/en/application-dev/application-test/figures/UnitTest.PNG differ
diff --git a/en/application-dev/application-test/figures/wukongRandomTest.png b/en/application-dev/application-test/figures/wukongRandomTest.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8164620f94f8d4ec61e22e53eb655888ce15050
Binary files /dev/null and b/en/application-dev/application-test/figures/wukongRandomTest.png differ
diff --git a/en/application-dev/application-test/figures/wukongRandomTestFlow.png b/en/application-dev/application-test/figures/wukongRandomTestFlow.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2355d66557b2b3ce4066691adbe7cce7eb1a5f2
Binary files /dev/null and b/en/application-dev/application-test/figures/wukongRandomTestFlow.png differ
diff --git a/en/application-dev/application-test/figures/wukongSpecialTest.png b/en/application-dev/application-test/figures/wukongSpecialTest.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f4362da3f8c8cd7b40582acdb443a72434efebf
Binary files /dev/null and b/en/application-dev/application-test/figures/wukongSpecialTest.png differ
diff --git a/en/application-dev/application-test/smartperf-guidelines.md b/en/application-dev/application-test/smartperf-guidelines.md
new file mode 100644
index 0000000000000000000000000000000000000000..91b6cf44ef419487de7b435e42d26199c3b088d0
--- /dev/null
+++ b/en/application-dev/application-test/smartperf-guidelines.md
@@ -0,0 +1,75 @@
+# SmartPerf User Guide
+
+## Overview
+
+Performance testing helps developers detect the performance bottlenecks and deliver quality applications that meet user expectations. For this reason, SmartPerf, a performance testing tool specially designed for OpenHarmony developers, is provided.
+
+## Introduction
+
+SmartPerf is a reliable, easy-to-use performance and power consumption test tool built for the OpenHarmony system. It provides KPIs with test value details that help you measure the performance and power consumption of your application, such as FPS, CPU, GPU, and Ftrace.
+
+You can use SmartPerf in two modes: visualized operation mode (SmartPerf-Device) and command-line shell mode (SmartPerf-Daemon). SmartPerf-Device supports visualized operations and floating window based operations (such as data collection control and real-time data display). SmartPerf-Daemon is applicable to devices without screens and devices with high tolerance regarding performance, for example, Hi3568.
+
+## Principles
+
+SmartPerf come with SmartPerf-Device and SmartPerf-Daemon. SmartPerf-Device sends data requests for KPIs (such as FPS, RAM, and Trace) through messages to SmartPerf-Daemon, which then collects and sends back data as requested, and displays the received data. SmartPerf-Daemon also allows on-demand data collection through hell commands. The figure below demonstrates the main functions of SmartPerf.
+
+
+
+## Constraints
+
+- SmartPerf-Device and SmartPerf-Daemon are pre-installed in version 3.2 and later versions.
+- SmartPerf-Device requires a screen to work correctly.
+
+## Environment Preparations
+
+To run SmartPerf-Daemon, you must connect the PC to an OpenHarmony device, such as the RK3568 development board.
+
+## Performing Performance Testing
+
+**Using SmartPerf-Device**
+
+In the screenshots below, the RK3568 development board is used as an example.
+
+1. Set the application for which you want to collect data.
+
+ Start SmartPerf-Device. On the home screen, select the test application and test indicators, and touch **Start Test**.
+
+2. Control the data collection process from the floating window.
+
+ To start collection, touch **Start** in the floating window. To pause, touch the timer in the floating window to pause data collection. To resume, touch the timer again. To view the collected data in real time, double-touch the timer. To stop, touch and hold the timer. You can drag the floating window to anywhere you like.
+
+
+3. View the report.
+
+ Touch **Report** to view the test report list. Touch **Report List** to view details about test indicators.
+
+**Using SmartPerf-Daemon**
+
+1. Access the shell and run the following command to view the help information:
+```
+:# SP_daemon --help
+```
+2. Run the collection commands.
+```
+:# SP_daemon -N 2 -PKG com.ohos.contacts -c -g -t -p -r
+```
+
+**Collection Commands**
+
+| Command | Function |Mandatory|
+| :-----| :--------------------- |:-----|
+| -N | Set the number of collection times. |Yes|
+| -PKG | Set the package name. | No|
+| -PID | Sets the PID of a process (applicable to RAM).|No|
+| -c | Set whether to collect CPU data. | No|
+| -g | Set whether to collect GPU data. |No|
+| -f | Set whether to collect FPS data. |No|
+| -t | Set whether to collect temperature data. |No|
+| -p | Set whether to collect current data. |No|
+| -r | Set whether to collect memory data. |No|
+
+The default output path of the test result is as follows:
+```
+/data/local/tmp/data.csv
+```
diff --git a/en/application-dev/application-test/wukong-guidelines.md b/en/application-dev/application-test/wukong-guidelines.md
new file mode 100644
index 0000000000000000000000000000000000000000..e10cb9fa1badd83bd244e70a1f4445afd7f085b7
--- /dev/null
+++ b/en/application-dev/application-test/wukong-guidelines.md
@@ -0,0 +1,113 @@
+# wukong User Guide
+
+
+## Overview
+
+Stability testing is important in that it demonstrates how an application performs under stress. For this reason, wukong, a stability testing tool specially designed for OpenHarmony developers, is provided.
+
+In this document you will learn about the key functions of wukong and how to use it to perform stability testing.
+
+## Introduction
+
+wukong is part of the OpenHarmony toolkit and implements basic application stability test capabilities such as random event injection, component injection, exception capture, report generation, and data traversal of abilities.
+
+## Principles
+
+wukong mainly provides two types of tests: random test and special test.
+
+- Random test
+
+ The random test is the staple service of wukong. It provides the basic startup, running, and result summary features, as shown below.
+
+ 
+
+ The following figure shows the basic running process of the random test, which depends on the **hdc** command.
+
+ 
+
+- Special test
+
+ The special test provides a wide range of features: traversing the components of an application in sequence, recording and playback, and sleeping and waking up.
+
+ The following figure shows the main features of the special test.
+
+ 
+
+For details about the test commands, see [wukong](https://gitee.com/openharmony/ostest_wukong/blob/master/README.md).
+
+## Constraints
+
+1. wukong is pre-installed in version 3.2 and later versions.
+
+2. In versions earlier than 3.2, you must build wukong separately and push it to the tested OpenHarmony device. The procedure is as follows:
+ How to build:
+ ```
+ ./build.sh --product-name rk3568 --build-target wukong
+ ```
+ How to push:
+ ```
+ hdc_std shell mount -o rw,remount /
+ hdc_std file send wukong /
+ hdc_std shell chmod a+x /wukong
+ hdc_std shell mv /wukong /bin/
+ ```
+
+## Environment Preparations
+
+To run commands, connect the PC to an OpenHarmony device, such as the RK3568 development board.
+
+## Performing Stability Testing
+
+**Using wukong exec for Random Test**
+
+Access the shell and run the following random test command:
+```
+# wukong exec -s 10 -i 1000 -a 0.28 -t 0.72 -c 100
+```
+Random test commands
+| Command | Value | Description |
+| -------------- | -------------- | ---------------------------------------------- |
+| wukong exec | - | Works as the main command. |
+| -s | 10 | Sets the random seed. The value 10 is the seed value. |
+| -i | 1000 | Sets the application startup interval to 1000 ms.|
+| -a | 0.28 | Sets the proportion of the random application startup test to 28%. |
+| -t | 0.72 | Sets the proportion of the random touch test to 72%. |
+| -c | 100 | Sets the number of execution times to 100. |
+
+**Using wukong special for Special Test**
+
+Access the shell and run the following commands to perform the sequential traversal test:
+```bash
+# wukong special -C [bundlename] -p
+```
+Special test commands
+| Command | Value | Description |
+| -------------- |-------------- | ---------------------------------------------- |
+| wukong special | - | Works as the main command. |
+| -C [bundlename] |[bundlename] | Sets the bundle name of the application for the sequential traversal test. |
+| -p | - | Indicates a screenshot. |
+
+## Viewing the Test Result
+
+After the test commands are executed, the test result is automatically generated.
+
+You can obtain the test result in the following directory:
+```
+Before 2022/9/22: /data/local/wukong/report/xxxxxxxx_xxxxxx/
+Since 2022/9/22: /data/local/tmp/wukong/report/xxxxxxxx_xxxxxx/
+```
+>**NOTE**
+>
+>The folder for test reports is automatically generated.
+
+Content of the folder is described in the table below.
+| Folder/File | Description |
+| ------------------------------------ | ------------------ |
+| exception/ | Stores exception files generated during the test.|
+| screenshot/ | Stores screenshots of the sequential traversal test. |
+| wukong_report.csv | Stores the test report summary. |
+
+You can view the wukong execution log in the path below:
+```
+reports/xxxxxxxx_xxxxxx/wukong.log
+```
diff --git a/en/application-dev/connectivity/Readme-EN.md b/en/application-dev/connectivity/Readme-EN.md
index 16bf40cf8467bc805d3b485ca46d6f0fa295b3bc..578e2a3c56c8a1f6cce377eb39ef9a7756d74491 100755
--- a/en/application-dev/connectivity/Readme-EN.md
+++ b/en/application-dev/connectivity/Readme-EN.md
@@ -1,11 +1,11 @@
# Connectivity
- Network Management
- - [Network Management Overview](net-mgmt-overview.md)
- - [HTTP Data Request](http-request.md)
- - [WebSocket Connection](websocket-connection.md)
- - [Socket Connection](socket-connection.md)
+ - [Network Management Overview](net-mgmt-overview.md)
+ - [HTTP Data Request](http-request.md)
+ - [WebSocket Connection](websocket-connection.md)
+ - [Socket Connection](socket-connection.md)
- IPC & RPC
- - [IPC & RPC Overview](ipc-rpc-overview.md)
- - [IPC & RPC Development](ipc-rpc-development-guideline.md)
- - [Subscribing to State Changes of a Remote Object](subscribe-remote-state.md)
+ - [IPC & RPC Overview](ipc-rpc-overview.md)
+ - [IPC & RPC Development](ipc-rpc-development-guideline.md)
+ - [Subscribing to State Changes of a Remote Object](subscribe-remote-state.md)
diff --git a/en/application-dev/connectivity/http-request.md b/en/application-dev/connectivity/http-request.md
index 6ddf26b87022c8bf098efc72de9ae4b4c0e28779..da1a7e1c517f284037a41a88e2167b6d1d2406aa 100644
--- a/en/application-dev/connectivity/http-request.md
+++ b/en/application-dev/connectivity/http-request.md
@@ -12,7 +12,7 @@ To use related APIs, you must declare the **ohos.permission.INTERNET** permissio
For details about how to apply for permissions, see [Access Control Development](../security/accesstoken-guidelines.md).
-The following table describes the related APIs.
+The following table provides only a simple description of the related APIs. For details, see [API Reference](../reference/apis/js-apis-http.md).
| API | Description |
| ----------------------------------------- | --------------------------------------------------------- |
diff --git a/en/application-dev/connectivity/ipc-rpc-development-guideline.md b/en/application-dev/connectivity/ipc-rpc-development-guideline.md
index 1fddf868604e564e4b6a6701f8d3a8088c4d8326..0eeef8040da8abd9710f3996f0b5f2c65ecf71e2 100644
--- a/en/application-dev/connectivity/ipc-rpc-development-guideline.md
+++ b/en/application-dev/connectivity/ipc-rpc-development-guideline.md
@@ -10,7 +10,7 @@ IPC/RPC enables a proxy and a stub that run on different processes to communicat
| Class/Interface | Function | Description |
| --------------- | -------- | ----------- |
-| IRemoteBroker | sptr AsObject() | Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of **IRemoteBroker**. If you call this method on the stub, the **RemoteObject** is returned; if you call this method on the proxy, the proxy object is returned. |
+| [IRemoteBroker](../reference/apis/js-apis-rpc.md#iremotebroker) | sptr AsObject() | Obtains the holder of a remote proxy object. This method must be implemented by the derived classes of **IRemoteBroker**. If you call this method on the stub, the **RemoteObject** is returned; if you call this method on the proxy, the proxy object is returned. |
| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Called to process a request from the proxy and return the result. Derived classes need to override this method. |
| IRemoteProxy | | Service proxy classes are derived from the **IRemoteProxy** class. |
@@ -25,10 +25,10 @@ IPC/RPC enables a proxy and a stub that run on different processes to communicat
```
class ITestAbility : public IRemoteBroker {
public:
- // DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
- DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility");
- int TRANS_ID_PING_ABILITY = 1; // Define the message code.
- virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
+ // DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string.
+ DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility");
+ int TRANS_ID_PING_ABILITY = 1; // Define the message code.
+ virtual int TestPingAbility(const std::u16string &dummy) = 0; // Define functions.
};
```
diff --git a/en/application-dev/database/database-datashare-guidelines.md b/en/application-dev/database/database-datashare-guidelines.md
index 495f3b538b48b22d2d97f213d0e32189be799560..064c3e393fe27cedceb1f3f7d2d1e03b8ec22db6 100644
--- a/en/application-dev/database/database-datashare-guidelines.md
+++ b/en/application-dev/database/database-datashare-guidelines.md
@@ -52,9 +52,9 @@ Examples are given below.
3. Implement the data provider services. For example, implement data storage of the data provider by using a database, reading and writing files, or accessing the network.
```ts
- let DB_NAME = "DB00.db";
- let TBL_NAME = "TBL00";
- let DDL_TBL_CREATE = "CREATE TABLE IF NOT EXISTS "
+ const DB_NAME = "DB00.db";
+ const TBL_NAME = "TBL00";
+ const DDL_TBL_CREATE = "CREATE TABLE IF NOT EXISTS "
+ TBL_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, isStudent BOOLEAN, Binary BINARY)";
@@ -132,9 +132,9 @@ Examples are given below.
1. Import the dependencies.
```ts
- import Ability from '@ohos.application.Ability'
- import dataShare from '@ohos.data.dataShare'
- import dataSharePredicates from '@ohos.data.dataSharePredicates'
+ import Ability from '@ohos.application.Ability';
+ import dataShare from '@ohos.data.dataShare';
+ import dataSharePredicates from '@ohos.data.dataSharePredicates';
```
2. Define the URI string for communicating with the data provider.
@@ -164,29 +164,25 @@ Examples are given below.
```ts
// Construct a piece of data.
- var valuesBucket = { "name": "ZhangSan", "age": 21, "isStudent": false, "Binary": new Uint8Array([1, 2, 3]) };
- var updateBucket = { "name": "LiSi", "age": 18, "isStudent": true, "Binary": new Uint8Array([1, 2, 3]) };
- let da = new dataSharePredicates.DataSharePredicates();
- var valArray = new Array("*");
- let people = new Array(
- { "name": "LiSi", "age": 41, "Binary": ar },
- { "name": "WangWu", "age": 21, "Binary": arr },
- { "name": "ZhaoLiu", "age": 61, "Binary": arr });
+ let valuesBucket = { "name": "ZhangSan", "age": 21, "isStudent": false, "Binary": new Uint8Array([1, 2, 3]) };
+ let updateBucket = { "name": "LiSi", "age": 18, "isStudent": true, "Binary": new Uint8Array([1, 2, 3]) };
+ let predicates = new dataSharePredicates.DataSharePredicates();
+ let valArray = new Array("*");
// Insert a piece of data.
dsHelper.insert(dseUri, valuesBucket, (err, data) => {
console.log("dsHelper insert result: " + data);
});
- // Delete data.
- dsHelper.delete(dseUri, da, (err, data) => {
- console.log("dsHelper delete result: " + data);
- });
// Update data.
- dsHelper.update(dseUri, da, updateBucket, (err, data) => {
+ dsHelper.update(dseUri, predicates, updateBucket, (err, data) => {
console.log("dsHelper update result: " + data);
});
// Query data.
- dsHelper.query(dseUri, da, valArray, (err, data) => {
+ dsHelper.query(dseUri, predicates, valArray, (err, data) => {
console.log("dsHelper query result: " + data);
});
+ // Delete data.
+ dsHelper.delete(dseUri, predicates, (err, data) => {
+ console.log("dsHelper delete result: " + data);
+ });
```
diff --git a/en/application-dev/database/database-datashare-overview.md b/en/application-dev/database/database-datashare-overview.md
index f603c4dd54840118471cba6c344de58121577d57..019adeb3fa6850ed5407e0107d5996054ef11de7 100644
--- a/en/application-dev/database/database-datashare-overview.md
+++ b/en/application-dev/database/database-datashare-overview.md
@@ -22,7 +22,7 @@ Before you get started, familiarize yourself with the following concepts:
An application that accesses the data or services provided by a data provider. It is also called a client.
-- Value bucket (**ValuesBucket**)
+- **ValuesBucket**
One or more data records stored in the form of key-value (KV) pairs. The keys are of the string type. The values can be of the number, string, Boolean, or Unit8Array type.
diff --git a/en/application-dev/database/database-distributedobject-overview.md b/en/application-dev/database/database-distributedobject-overview.md
index 80985ed39b8c91a5c9635e0be8fd00f4be2da702..9fb93eba7c13f85da0cdccb9036df26e4d8d8ce0 100644
--- a/en/application-dev/database/database-distributedobject-overview.md
+++ b/en/application-dev/database/database-distributedobject-overview.md
@@ -12,7 +12,7 @@ The distributed data object management framework provides object-oriented in-mem
- **Distributed data object**
- A distributed data object is an encapsulation of the JS object type. Each distributed data object instance creates a data table in the in-memory database. The in-memory databases created for different applications are isolated from each other. Reading data from and writing data to a distributed data object are mapped to the **put** and **get** operations in the corresponding database, respectively.
+ A distributed data object is an encapsulation of the JS object type. Each distributed data object instance creates a data table in the in-memory database. The in-memory databases created for different applications are isolated from each other. Reading data from and writing data to a distributed data object are mapped to the **get** and **put** operations in the corresponding database, respectively.
The distributed data object can be in the following states in its lifecycle:
diff --git a/en/application-dev/database/database-mdds-guidelines.md b/en/application-dev/database/database-mdds-guidelines.md
index 2205df9ceffb51c3c6cb7816f6d11784ba532b20..73f785de4ddccaa1e10c6049066a5f3908d85fc6 100644
--- a/en/application-dev/database/database-mdds-guidelines.md
+++ b/en/application-dev/database/database-mdds-guidelines.md
@@ -6,20 +6,20 @@ The Distributed Data Service (DDS) implements synchronization of application dat
## Available APIs
-For details about the APIs, see [Distributed Data Management](../reference/apis/js-apis-distributed-data.md).
+For details about the APIs, see [Distributed KV Store](../reference/apis/js-apis-distributedKVStore.md).
**Table 1** APIs provided by the DDS
-| API | Description |
-| ------------------------------------------------------------ | ----------------------------------------------- |
-| createKVManager(config: KVManagerConfig, callback: AsyncCallback<KVManager>): void createKVManager(config: KVManagerConfig): Promise<KVManager> | Creates a **KVManager** object for database management.|
-| getKVStore<TextendsKVStore>(storeId: string, options: Options, callback: AsyncCallback<T>): void getKVStore<TextendsKVStore>(storeId: string, options: Options): Promise<T> | Obtains a KV store with the specified **Options** and **storeId**.|
-| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback<void>): void put(key: string, value: Uint8Array\|string\|number\|boolean): Promise<void> | Inserts and updates data. |
-| delete(key: string, callback: AsyncCallback<void>): void delete(key: string): Promise<void> | Deletes data. |
-| get(key: string, callback: AsyncCallback<Uint8Array\|string\|boolean\|number>): void get(key: string): Promise<Uint8Array\|string\|boolean\|number> | Queries data. |
-| on(event: 'dataChange', type: SubscribeType, observer: Callback<ChangeNotification>): void on(event: 'syncComplete', syncCallback: Callback<Array<[string,number]>>): void | Subscribes to data changes in the KV store. |
-| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void | Triggers database synchronization in manual mode. |
+| API | Description |
+| ------------------------------------------------------------ | ------------------------------------------------------------ |
+| createKVManager(config: KVManagerConfig, callback: AsyncCallback<KVManager>): void createKVManager(config: KVManagerConfig): Promise<KVManager> | Creates a **KvManager** object for database management. |
+| getKVStore<TextendsKVStore>(storeId: string, options: Options, callback: AsyncCallback<T>): void getKVStore<TextendsKVStore>(storeId: string, options: Options): Promise<T> | Creates and obtains a KV store.|
+| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback<void>): void put(key: string, value: Uint8Array\|string\|number\|boolean): Promise<void> | Inserts and updates data. |
+| delete(key: string, callback: AsyncCallback<void>): void delete(key: string): Promise<void> | Deletes data. |
+| get(key: string, callback: AsyncCallback<Uint8Array\|string\|boolean\|number>): void get(key: string): Promise<Uint8Array\|string\|boolean\|number> | Queries data. |
+| on(event: 'dataChange', type: SubscribeType, observer: Callback<ChangeNotification>): void on(event: 'syncComplete', syncCallback: Callback<Array<[string,number]>>): void | Subscribes to data changes in the KV store. |
+| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: number): void | Triggers database synchronization in manual mode. |
## How to Develop
@@ -28,70 +28,105 @@ The following uses a single KV store as an example to describe the development p
1. Import the distributed data module.
```js
- import distributedData from '@ohos.data.distributedData';
+ import distributedKVStore from '@ohos.data.distributedKVStore';
```
+
2. Apply for the required permission if data synchronization is required.
Add the permission required (FA model) in the **config.json** file. The sample code is as follows:
```json
- {
- "module": {
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC"
- }
- ]
- }
- }
+ {
+ "module": {
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
+ }
+ ]
+ }
+ }
```
+
For the apps based on the stage model, see [Declaring Permissions](../security/accesstoken-guidelines.md#stage-model).
This permission must also be granted by the user when the application is started for the first time. The sample code is as follows:
```js
+ // FA model
import featureAbility from '@ohos.ability.featureAbility';
-
+
function grantPermission() {
- console.info('grantPermission');
- let context = featureAbility.getContext();
- context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
- console.info(`result.requestCode=${result.requestCode}`)
-
- })
- console.info('end grantPermission');
+ console.info('grantPermission');
+ let context = featureAbility.getContext();
+ context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666).then((data) => {
+ console.info('success: ${data}');
+ }).catch((error) => {
+ console.info('failed: ${error}');
+ })
}
-
+
+ grantPermission();
+
+ // Stage model
+ import Ability from '@ohos.application.Ability';
+
+ let context = null;
+
+ function grantPermission() {
+ class MainAbility extends Ability {
+ onWindowStageCreate(windowStage) {
+ let context = this.context;
+ }
+ }
+
+ let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC'];
+ context.requestPermissionsFromUser(permissions).then((data) => {
+ console.log('success: ${data}');
+ }).catch((error) => {
+ console.log('failed: ${error}');
+ });
+ }
+
grantPermission();
```
-3. Create a **kvManager** instance based on the specified **kvManagerConfig** object.
+3. Create a **KvManager** instance based on the specified **KvManagerConfig** object.
1. Create a **kvManagerConfig** object based on the application context.
- 2. Create a **kvManager** instance.
+ 2. Create a **KvManager** instance.
The sample code is as follows:
```js
+ // Obtain the context of the FA model.
+ import featureAbility from '@ohos.ability.featureAbility';
+ let context = featureAbility.getContext();
+
+ // Obtain the context of the stage model.
+ import AbilityStage from '@ohos.application.Ability';
+ let context = null;
+ class MainAbility extends AbilityStage{
+ onWindowStageCreate(windowStage){
+ context = this.context;
+ }
+ }
+
let kvManager;
try {
const kvManagerConfig = {
bundleName: 'com.example.datamanagertest',
- userInfo: {
- userId: '0',
- userType: distributedData.UserType.SAME_USER_ID
- }
+ context:context,
}
- distributedData.createKVManager(kvManagerConfig, function (err, manager) {
+ distributedKVStore.createKVManager(kvManagerConfig, function (err, manager) {
if (err) {
- console.log("createKVManager err: " + JSON.stringify(err));
+ console.error(`Failed to create KVManager.code is ${err.code},message is ${err.message}`);
return;
}
- console.log("createKVManager success");
+ console.log('Created KVManager successfully');
kvManager = manager;
});
} catch (e) {
- console.log("An unexpected error occurred. Error: " + e);
+ console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
}
```
@@ -110,34 +145,38 @@ The following uses a single KV store as an example to describe the development p
encrypt: false,
backup: false,
autoSync: false,
- kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
- securityLevel: distributedData.SecurityLevel.S0
+ kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
+ securityLevel: distributedKVStore.SecurityLevel.S1
};
kvManager.getKVStore('storeId', options, function (err, store) {
if (err) {
- console.log("getKVStore err: " + JSON.stringify(err));
+ console.error(`Failed to get KVStore: code is ${err.code},message is ${err.message}`);
return;
}
- console.log("getKVStore success");
+ console.log('Obtained KVStore successfully');
kvStore = store;
});
} catch (e) {
- console.log("An unexpected error occurred. Error: " + e);
+ console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
}
```
> **NOTE**
>
> For data synchronization between networked devices, you are advised to open the distributed KV store during application startup to obtain the database handle. With this database handle (`kvStore` in this example), you can perform operations, such as inserting data into the KV store, without creating the KV store repeatedly during the lifecycle of the handle.
-
+
5. Subscribe to changes in the distributed data.
The following is the sample code for subscribing to the data changes of a single KV store:
```js
- kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) {
- console.log("dataChange callback call data: " + JSON.stringify(data));
- });
+ try{
+ kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) {
+ console.log(`dataChange callback call data: ${data}`);
+ });
+ }catch(e){
+ console.error(`An unexpected error occured.code is ${e.code},message is ${e.message}`);
+ }
```
6. Write data to the single KV store.
@@ -151,15 +190,15 @@ The following uses a single KV store as an example to describe the development p
const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
try {
- kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) {
+ kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
if (err != undefined) {
- console.log("put err: " + JSON.stringify(err));
+ console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
return;
}
- console.log("put success");
+ console.log('Put data successfully');
});
- } catch (e) {
- console.log("An unexpected error occurred. Error: " + e);
+ }catch (e) {
+ console.error(`An unexpected error occurred.code is ${e.code},message is ${e.message}`);
}
```
@@ -174,18 +213,22 @@ The following uses a single KV store as an example to describe the development p
const KEY_TEST_STRING_ELEMENT = 'key_test_string';
const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
try {
- kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) {
+ kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
+ if (err != undefined) {
+ console.error(`Failed to put.code is ${err.code},message is ${err.message}`);
+ return;
+ }
+ console.log('Put data successfully');
+ kvStore.get(KEY_TEST_STRING_ELEMENT, function (err,data) {
if (err != undefined) {
- console.log("put err: " + JSON.stringify(err));
+ console.error(`Failed to get data.code is ${err.code},message is ${err.message}`);
return;
}
- console.log("put success");
- kvStore.get(KEY_TEST_STRING_ELEMENT, function (err, data) {
- console.log("get success data: " + data);
+ console.log(`Obtained data successfully:${data}`);
});
});
- } catch (e) {
- console.log("An unexpected error occurred. Error: " + e);
+ }catch (e) {
+ console.error(`Failed to get.code is ${e.code},message is ${e.message}`);
}
```
@@ -196,7 +239,7 @@ The following uses a single KV store as an example to describe the development p
> **NOTE**
>
> The APIs of the `deviceManager` module are system interfaces.
-
+
The following is the example code for synchronizing data in a single KV store:
```js
@@ -204,7 +247,7 @@ The following uses a single KV store as an example to describe the development p
let devManager;
// Create deviceManager.
- deviceManager.createDeviceManager("bundleName", (err, value) => {
+ deviceManager.createDeviceManager('bundleName', (err, value) => {
if (!err) {
devManager = value;
// deviceIds is obtained by deviceManager by calling getTrustedDeviceListSync().
@@ -217,9 +260,9 @@ The following uses a single KV store as an example to describe the development p
}
try{
// 1000 indicates that the maximum delay is 1000 ms.
- kvStore.sync(deviceIds, distributedData.SyncMode.PUSH_ONLY, 1000);
+ kvStore.sync(deviceIds, distributedKVStore.SyncMode.PUSH_ONLY, 1000);
} catch (e) {
- console.log("An unexpected error occurred. Error: " + e);
+ console.error(`An unexpected error occurred. code is ${e.code},message is ${e.message}`);
}
}
});
diff --git a/en/application-dev/database/database-mdds-overview.md b/en/application-dev/database/database-mdds-overview.md
index 26efa7491805e871017db3593f5fa50d947717f5..cfe264a4f7eb06cd51cb834bc3e38ee27e649a14 100644
--- a/en/application-dev/database/database-mdds-overview.md
+++ b/en/application-dev/database/database-mdds-overview.md
@@ -1,105 +1,103 @@
# Distributed Data Service Overview
-The distributed data service (DDS) implements distributed database collaboration across devices for applications.
+The distributed data service (DDS) implements distributed database collaboration across devices for applications.
Applications save data to distributed databases by calling the DDS APIs. The DDS isolates data of different applications based on a triplet of account, application, and database to ensure secure data access. The DDS synchronizes application data between trusted devices to provide users with consistent data access experience on different devices.
You do not need to care about the implementation of the database locking mechanism.
+
## Basic Concepts
-- **KV data model**
+### KV Data Model
- The key-value \(KV\) data model allows data to be organized, indexed, and stored in key-value pairs.
+The key-value (KV) data model allows data to be organized, indexed, and stored in KV pairs.
- The KV data model is suitable for storing service data that is not related. It provides better read and write performance than the SQL database. The KV data model is widely used in distributed scenarios because it handles database version compatibility issues and data synchronization conflicts easily. The distributed database is based on the KV data model and provides KV-based access interfaces.
+The KV data model is suitable for storing service data that is not related. It provides better read and write performance than the SQL database. The KV data model is widely used in distributed scenarios because it handles database version compatibility issues and data synchronization conflicts easily. The distributed database is based on the KV data model and provides KV-based access interfaces.
-- **Distributed database transactions**
+### Distributed Database Transaction
- Distributed database transactions include local transactions \(same as the transactions of traditional databases\) and synchronization transactions. Synchronization transactions allow data to be synchronized between devices by local transaction. Synchronization of a local transaction modification either succeeds or fails on all the devices.
+Distributed database transactions include local transactions (same as the transactions of traditional databases) and synchronization transactions. Synchronization transactions allow data to be synchronized between devices by local transaction. Synchronization of a local transaction modification either succeeds or fails on all the devices.
-- **Distributed database consistency**
+### Distributed Database Consistency
- In a distributed scenario, cross-device collaboration demands consistent data between the devices in the same network. The data consistency can be classified into the following types:
+In a distributed scenario, cross-device collaboration demands consistent data between the devices in the same network. The data consistency can be classified into the following types:
- - **Strong consistency**: When data is inserted, deleted, or modified on a device, other devices in the same network will obtain the latest data immediately.
- - **Weak consistency**: When data is added, deleted, or modified on a device, other devices in the same network may or may not obtain the latest data. The data on these devices may be inconsistent after a certain period of time.
- - **Eventual consistency**: When data is added, deleted, or modified on a device, other devices in the same network may not obtain the latest data immediately. However, data on these devices will become consistent after a certain period of time.
+- **Strong consistency**: When data is inserted, deleted, or modified on a device, other devices in the same network will obtain the latest data immediately.
+- **Weak consistency**: When data is added, deleted, or modified on a device, other devices in the same network may or may not obtain the latest data. The data on these devices may be inconsistent after a certain period of time.
+- **Eventual consistency**: When data is added, deleted, or modified on a device, other devices in the same network may not obtain the latest data immediately. However, data on these devices will become consistent after a certain period of time.
- Strong consistency has high requirements on distributed data management and may be used in distributed server deployment. The DDS supports only the eventual consistency because mobile devices are not always online and the network has no center.
+Strong consistency has high requirements on distributed data management and may be used in distributed server deployment. The DDS supports only the eventual consistency because mobile devices are not always online and the network has no center.
-- **Distributed database synchronization**
+### Distributed Database Synchronization
- After discovering and authenticating a device, the underlying communication component notifies the upper-layer application \(including the DDS\) that the device goes online. The DDS then establishes an encrypted transmission channel to synchronize data between the two devices.
+After discovering and authenticating a device, the underlying communication component notifies the upper-layer application (including the DDS) that the device goes online. The DDS then establishes an encrypted transmission channel to synchronize data between the two devices.
- The DDS provides the following synchronization modes:
+The DDS provides the following synchronization modes:
- - **Manual synchronization**: Applications call **sync** to trigger a synchronization. The list of devices to be synchronized and the synchronization mode must be specified. The synchronization mode can be **PULL\_ONLY** \(pulling remote data to the local end\), **PUSH\_ONLY** \(pushing local data to the remote end\), or **PUSH\_PULL** \(pushing local data to the remote end and pulling remote data to the local end\). The internal interface supports condition-based synchronization. The data that meets the conditions can be synchronized to the remote end.
- - **Automatic synchronization**: includes full synchronization and condition-based subscription synchronization. In full synchronization, the distributed database automatically pushes local data to the remote end and pulls remote data to the local end when a device goes online or application data is updated. Applications do not need to call **sync**. The internal interface supports condition-based subscription synchronization. The data that meets the subscription conditions on the remote end is automatically synchronized to the local end.
+- **Manual synchronization**: Applications call **sync()** to trigger a synchronization. The list of devices to be synchronized and the synchronization mode must be specified. The synchronization mode can be **PULL_ONLY** (pulling remote data to the local end), **PUSH_ONLY** (pushing local data to the remote end), or **PUSH_PULL** (pushing local data to the remote end and pulling remote data to the local end). The internal interface supports condition-based synchronization. The data that meets the conditions can be synchronized to the remote end.
+- **Automatic synchronization**: includes full synchronization and condition-based subscription synchronization. In full synchronization, the distributed database automatically pushes local data to the remote end and pulls remote data to the local end when a device goes online or application data is updated. Applications do not need to call **sync()**. The internal interface supports condition-based subscription synchronization. The data that meets the subscription conditions on the remote end is automatically synchronized to the local end.
-- **Single KV store**
+### Single KV Store
- Data is saved locally in the unit of a single KV entry. Only one entry is saved for each key. Data can be modified only locally and synchronized to remote devices in sequence based on the update time.
+Data is saved locally in the unit of a single KV entry. Only one entry is saved for each key. Data can be modified only locally and synchronized to remote devices in sequence based on the update time.
-- **Device KV store**
+### Device KV Store
- The device KV store is based on the single KV store. The local device ID is added to the key when KV data is stored in the device KV store. Data can be isolated, managed, and queried by device. However, the data synchronized from remote devices cannot be modified locally.
+The device KV store is based on the single KV store. The local device ID is added to the key when KV data is stored in the device KV store. Data can be isolated, managed, and queried by device. However, the data synchronized from remote devices cannot be modified locally.
-- **Conflict resolution**
+### Conflict Resolution
- A data conflict occurs when multiple devices modify the same data and commit the modification to the database. The last write wins \(LWW\) is the default conflict resolution policy used for data conflicts. Based on the commit timestamps, the data with a later timestamp is used. Currently, customized conflict resolution policies are not supported.
+A data conflict occurs when multiple devices modify the same data and commit the modification to the database. The last write wins (LWW) is the default conflict resolution policy used for data conflicts. Based on the commit timestamps, the data with a later timestamp is used. Currently, customized conflict resolution policies are not supported.
-- **Schema-based database management and data query based on predicates**
+### Schema-based Database Management and Predicate-based Data Query
- A schema is specified when you create or open a single KV store. Based on the schema, the database detects the value format of key-value pairs and checks the value structure. Based on the fields in the values, the database implements index creation and predicate-based query.
+A schema is specified when you create or open a single KV store. Based on the schema, the database detects the value format of KV pairs and checks the value structure. Based on the fields in the values, the database implements index creation and predicate-based query.
-- **Distributed database backup**
+### Distributed Database Backup
- The DDS provides the database backup capability. You can set **backup** to **true** to enable daily backup. If a distributed database is damaged, the DDS deletes the database and restores the most recent data from the backup database. If no backup database is available, the DDS creates one. The DDS can also back up encrypted databases.
+The DDS provides the database backup capability. You can set **backup** to **true** to enable daily backup. If a distributed database is damaged, the DDS deletes the database and restores the most recent data from the backup database. If no backup database is available, the DDS creates one. The DDS can also back up encrypted databases.
## Working Principles
-The DDS supports distributed management of application database data in the OpenHarmony system. Data can be synchronized between multiple devices with the same account, delivering a consistent user experience across devices. The DDS consists of the following:
+The DDS supports distributed management of application database data in the OpenHarmony system. Data can be synchronized between multiple devices with the same account, delivering a consistent user experience across devices.
-- **APIs**
+The DDS consists of the following:
- The DDS provides APIs to create databases, access data, and subscribe to data. The APIs support the KV data model and common data types. They are highly compatible and easy to use, and can be released.
+- **APIs** The DDS provides APIs to create databases, access data, and subscribe to data. The APIs support the KV data model and common data types. They are highly compatible and easy to use, and can be released.
-- **Service component**
+- **Service component** The service component implements management of metadata, permissions, encryption, backup and restore, and multiple users, and completes initialization of the storage component, synchronization component, and communication adaptation layer of the distributed database.
- The service component implements management of metadata, permissions, encryption, backup and restore, and multiple users, and completes initialization of the storage component, synchronization component, and communication adaptation layer of the distributed database.
+- **Storage component** The storage component implements data access, data reduction, transactions, snapshots, database encryption, data combination, and conflict resolution.
-- **Storage component**
+- **Synchronization component** The synchronization component interacts with the storage component and the communication adaptation layer to maintain data consistency between online devices. It synchronizes data generated on the local device to other devices and merges data from other devices into the local device.
- The storage component implements data access, data reduction, transactions, snapshots, database encryption, data combination, and conflict resolution.
+- **Communication adaptation layer** The communication adaptation layer calls APIs of the underlying public communication layer to create and connect to communication channels, receive device online and offline messages, update metadata of the connected and disconnected devices, send device online and offline messages to the synchronization component. The synchronization component updates the list of connected devices, and calls the APIs of the communication adaption layer to encapsulate data and send the data to the connected devices.
-- **Synchronization component**
+Applications call the DDS APIs to create, access, and subscribe to distributed databases. The APIs store data to the storage component based on the capabilities provided by the service component. The storage component interacts with the synchronization component to synchronize data. The synchronization component uses the communication adaptation layer to synchronize data to remote devices, which update the data in the storage component and provide the data for applications through service APIs.
- The synchronization component interacts with the storage component and the communication adaptation layer to maintain data consistency between online devices. It synchronizes data generated on the local device to other devices and merges data from other devices into the local device.
-- **Communication adaptation layer**
+**Figure 1** How DDS works
- The communication adaptation layer calls APIs of the underlying public communication layer to create and connect to communication channels, receive device online and offline messages, update metadata of the connected and disconnected devices, send device online and offline messages to the synchronization component. The synchronization component updates the list of connected devices, and calls the APIs of the communication adaption layer to encapsulate data and send the data to the connected devices.
+
-Applications call the DDS APIs to create, access, and subscribe to distributed databases. The APIs store data to the storage component based on the capabilities provided by the service component. The storage component interacts with the synchronization component to synchronize data. The synchronization component uses the communication adaptation layer to synchronize data to remote devices, which update the data in the storage component and provide the data for applications through service APIs.
-**Figure 1** How DDS works
+## Constraints
+- The DDS supports the KV data model only. It does not support foreign keys or triggers of the relational database.
-
+- The KV data model specifications supported by the DDS are as follows:
-## Constraints
+ - For each record in a device KV store, the key must be less than or equal to 896 bytes and the value be less than 4 MB.
+ - For each record in a single KV store, the key must be less than or equal to 1 KB and the value be less than 4 MB.
+ - An application can open a maximum of 16 KV stores simultaneously.
+
+- The data that needs to be synchronized between devices should be stored in distributed databases rather than local databases.
-- The DDS supports the KV data model only. It does not support foreign keys or triggers of the relational database.
-- The KV data model specifications supported by the DDS are as follows:
- - For each record in a device KV store, the key must be less than or equal to 896 bytes and the value be less than 4 MB.
- - For each record in a single KV store, the key must be less than or equal to 1 KB and the value be less than 4 MB.
- - An application can open a maximum of 16 KV stores simultaneously.
+- The DDS does not support customized conflict resolution policies.
-- The data that needs to be synchronized between devices should be stored in distributed databases rather than local databases.
-- The DDS does not support customized conflict resolution policies.
-- The maximum number of access requests to the KvStore API is 1000 per second and 10000 per minute. The maximum number of access requests to the KvManager API is 50 per second and 500 per minute.
-- Blocking operations, such as modifying UI components, are not allowed in the distributed database event callback.
+- The maximum number of access requests to the KvStore API is 1000 per second and 10000 per minute. The maximum number of access requests to the KvManager API is 50 per second and 500 per minute.
+- Blocking operations, such as modifying UI components, are not allowed in the distributed database event callback.
diff --git a/en/application-dev/database/database-preference-guidelines.md b/en/application-dev/database/database-preference-guidelines.md
index 61aa2294c3f8ee077241e347e47e7780f50c4359..897be371287a22f8efe7a8571feec93458d1ba5f 100644
--- a/en/application-dev/database/database-preference-guidelines.md
+++ b/en/application-dev/database/database-preference-guidelines.md
@@ -28,26 +28,29 @@ Obtain a **Preferences** instance for data operations. A **Preferences** instanc
| --------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| ohos.data.preferences | getPreferences(context: Context, name: string): Promise\ | Obtains a **Preferences** instance.|
-### Accessing Data
+### Processing Data
-Call the **put()** method to add or modify data in a **Preferences** instance.
+Call **put()** to add or modify data in a **Preferences** instance.
-Call the **get()** method to read data from a **Preferences** instance.
+Call **get()** to read data from a **Preferences** instance.
Call **getAll()** to obtain an **Object** instance that contains all KV pairs in a **Preferences** instance.
-**Table 2** APIs for accessing **Preferences** data
+Call **delete()** to delete the KV pair of the specified key from the **Preferences** instance.
+
+**Table 2** APIs for processing **Preferences** data
| Class | API | Description |
| ----------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
| Preferences | put(key: string, value: ValueType): Promise\ | Writes data to the **Preferences** instance. The value to write can be a number, a string, a Boolean value, or an array of numbers, strings, or Boolean values.|
| Preferences | get(key: string, defValue: ValueType): Promise\ | Obtains data from the **Preferences** instance. The value to read can be a number, a string, a Boolean value, or an array of numbers, strings, or Boolean values.|
-| Preferences | getAll(): Promise