diff --git a/en/application-dev/IDL/idl-guidelines.md b/en/application-dev/IDL/idl-guidelines.md index 102992de24a2879f9b08a5274058c2cdf4c0a280..7753e85d309ebbf350b7825a9ad3f76e3a3fcddf 100644 --- a/en/application-dev/IDL/idl-guidelines.md +++ b/en/application-dev/IDL/idl-guidelines.md @@ -62,7 +62,7 @@ sequenceable a.b..C.D The preceding statement is parsed into the following code in the C++ header file: ```cpp -#include "a/b/d.h" +#include "a/b/d.h" using C::D; ``` @@ -347,11 +347,10 @@ export default { #### Calling Methods from the Client for IPC -When the client calls **connectAbility()** to connect to a Service ability, the **onConnect** callback in **onAbilityConnectDone** of the client receives the **IRemoteObject** instance returned by the **onConnect()** method of the Service ability. The client and Service ability are in different applications. Therefore, the directory of the client application must contain a copy of the .idl file (the SDK automatically generates the proxy class). The **onConnect** callback then uses the **IRemoteObject** instance to create the **testProxy** instance of the **IdlTestServiceProxy** class and calls the related IPC method. The sample code is as follows: +When the client calls **connectServiceExtensionAbility()** to connect to a Service ability, the **onConnect** callback in **onAbilityConnectDone** of the client receives the **IRemoteObject** instance returned by the **onConnect()** method of the Service ability. The client and Service ability are in different applications. Therefore, the directory of the client application must contain a copy of the .idl file (the SDK automatically generates the proxy class). The **onConnect** callback then uses the **IRemoteObject** instance to create the **testProxy** instance of the **IdlTestServiceProxy** class and calls the related IPC method. The sample code is as follows: ```ts import IdlTestServiceProxy from './idl_test_service_proxy' -import featureAbility from '@ohos.ability.featureAbility'; function callbackTestIntTransaction(result: number, ret: number): void { if (result == 0 && ret == 124) { @@ -396,13 +395,13 @@ var onAbilityConnectDone = { } }; -function connectAbility: void { +function connectAbility(): void { let want = { bundleName: 'com.example.myapplicationidl', abilityName: 'com.example.myapplicationidl.ServiceAbility' }; let connectionId = -1; - connectionId = featureAbility.connectAbility(want, onAbilityConnectDone); + connectionId = this.context.connectServiceExtensionAbility(want, onAbilityConnectDone); } diff --git a/en/application-dev/application-models/Readme-EN.md b/en/application-dev/application-models/Readme-EN.md index ab82a4abae17e667670a2587b4016eee669abd26..7c320ef8068cd15bd0694f454c054b425d9841fd 100644 --- a/en/application-dev/application-models/Readme-EN.md +++ b/en/application-dev/application-models/Readme-EN.md @@ -61,7 +61,7 @@ - [Component Startup Rules (Stage Model)](component-startup-rules.md) - Inter-Device Application Component Interaction (Continuation) - [Continuation Overview](inter-device-interaction-hop-overview.md) - - [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md) + - [Cross-Device Migration](hop-cross-device-migration.md) - [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md) - [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md) - Process Model diff --git a/en/application-dev/application-models/accessibilityextensionability.md b/en/application-dev/application-models/accessibilityextensionability.md index a76742c142bfccdd015665478aadbaedf19ff39e..94c4429c5b2a4b49ba4dbae48f813dce16bba68a 100644 --- a/en/application-dev/application-models/accessibilityextensionability.md +++ b/en/application-dev/application-models/accessibilityextensionability.md @@ -118,7 +118,12 @@ After developing the custom logic for an accessibility extension service, you mu ``` ## Enabling or Disabling a Custom Accessibility Extension Service -To enable or disable an accessibility extension service, run the following command: +You can enable or disable a custom accessibility extension service through the command line interface or the device settings. + +**Method 1**: through the command line interface + +Run the **hdc shell** command, then the following system command: + - To enable the service: **accessibility enable -a AccessibilityExtAbility -b com.example.demo -c rg** - To disable the service: **accessibility disable -a AccessibilityExtAbility -b com.example.demo** @@ -126,3 +131,9 @@ In the preceding commands, **AccessibilityExtAbility** indicates the name of the If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed. + + **Method 2**: through the device settings +- From the device settings screen, access the list of installed extended services under accessibility. +If an extended service is not installed, it is grayed out, and "No service" is displayed. +- Select the target extended service, and toggle on or off the switch to enable or disable it. +- If you opt to enable a service, a security reminder is displayed. Wait until the countdown ends and then select the check box indicating that you are aware of and willing to assume the listed risks. diff --git a/en/application-dev/application-models/arkts-ui-widget-configuration.md b/en/application-dev/application-models/arkts-ui-widget-configuration.md index ea9832f92d32dfe0c2a4160f3ac6f8e904d323fa..d86c3b6991460a25c0ea6a177a8aec8c4607364c 100644 --- a/en/application-dev/application-models/arkts-ui-widget-configuration.md +++ b/en/application-dev/application-models/arkts-ui-widget-configuration.md @@ -54,7 +54,7 @@ Widget-related configuration includes **FormExtensionAbility** configuration and | 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)| | dataProxyEnabled | Whether the widget supports the [update-through-proxy](./arkts-ui-widget-update-by-proxy.md) feature.
- **true**: The widget supports the update-through-proxy feature.
- **false**: The widget does not support the update-through-proxy feature.
If this tag is set to **true**, the settings for the scheduled update time will still take effect, but the settings for the update interval and next update time will not.| Boolean| Yes (initial value: **false**)| - | isDynamic | Whether the widget is a dynamic widget. This tag only applies to ArkTS widgets.
- **true**: The widget is a dynamic widget.
- **false**: The widget is a static widget. In this case, the widget is displayed as a static image after being added.| Boolean| Yes (initial value: **true**)| + | isDynamic | Whether the widget is a dynamic widget. This tag applies only to ArkTS widgets.
- **true**: The widget is a dynamic widget.
- **false**: The widget is a static widget. In this case, the widget is displayed as a static image after being added.| Boolean| Yes (initial value: **true**)| **Table 2** Internal structure of the window object diff --git a/en/application-dev/application-models/component-startup-rules.md b/en/application-dev/application-models/component-startup-rules.md index bddf63dbc69ea243733e6f60f67f92a854833bf7..2db47d35f24df7d3eb155bb4ab2540f4a1af7ce0 100644 --- a/en/application-dev/application-models/component-startup-rules.md +++ b/en/application-dev/application-models/component-startup-rules.md @@ -26,7 +26,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol - If the **exported** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission. - For details, see [Component exported Configuration](../quick-start/module-configuration-file.md#abilities). -- **Before starting a component of a background application, verify the BACKGROUND permission.** +- **Before starting a UIAbility component of a background application, verify the BACKGROUND permission.** - An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground. - Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission. @@ -45,7 +45,9 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol The rules for starting components on the same device vary in the following scenarios: -- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components +- Starting the UIAbility component + +- Starting the ServiceExtensionAbility and DataShareExtensionAbility components - Using **startAbilityByCall()** to start the UIAbility component @@ -56,9 +58,10 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol The rules for starting components on a different device vary in the following scenarios: -- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components +- Starting the UIAbility component + +- Starting the ServiceExtensionAbility and DataShareExtensionAbility components - Using **startAbilityByCall()** to start the UIAbility component ![component-startup-rules](figures/component-startup-inter-stage.png) - diff --git a/en/application-dev/application-models/figures/component-startup-inner-stage.png b/en/application-dev/application-models/figures/component-startup-inner-stage.png index 00514276f4ac3eb8ead650e5858cebb0a344d2c6..9761b9879e513f0e1ad942b5fe18997f1331c9e5 100644 Binary files a/en/application-dev/application-models/figures/component-startup-inner-stage.png and b/en/application-dev/application-models/figures/component-startup-inner-stage.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inter-stage.png b/en/application-dev/application-models/figures/component-startup-inter-stage.png index a6f79e6803edc160e5570729456569f46cc80967..517407f6b557648db78a0de89431d8b18f8e2b59 100644 Binary files a/en/application-dev/application-models/figures/component-startup-inter-stage.png and b/en/application-dev/application-models/figures/component-startup-inter-stage.png differ diff --git a/en/application-dev/application-models/start-pageability-from-stage.md b/en/application-dev/application-models/start-pageability-from-stage.md index bd6a11187fdfbc81c63bcc6601f8a8e82b0dbe4c..123e15c45614f83ece1c11db87827535b2ac4937 100644 --- a/en/application-dev/application-models/start-pageability-from-stage.md +++ b/en/application-dev/application-models/start-pageability-from-stage.md @@ -8,6 +8,10 @@ This topic describes how the two application components of the stage model start A UIAbility starts a PageAbility in the same way as it starts another UIAbility. +> **NOTE** +> +> In the FA model, **abilityName** consists of **bundleName** and **AbilityName**. For details, see the code snippet below. + ```ts import UIAbility from '@ohos.app.ability.UIAbility'; @@ -25,7 +29,7 @@ export default class EntryAbility extends UIAbility { }); let want = { bundleName: "com.ohos.fa", - abilityName: "EntryAbility", + abilityName: "com.ohos.fa.EntryAbility", }; this.context.startAbility(want).then(() => { console.info('Start Ability successfully.'); diff --git a/en/application-dev/application-models/start-uiability-from-fa.md b/en/application-dev/application-models/start-uiability-from-fa.md index 42d8e034cd6519643423bb289217d1aa140a18d4..8520cf94be0d0d21999af3175848a37edac85c52 100644 --- a/en/application-dev/application-models/start-uiability-from-fa.md +++ b/en/application-dev/application-models/start-uiability-from-fa.md @@ -14,7 +14,7 @@ import featureAbility from '@ohos.ability.featureAbility'; let parameter = { "want": { bundleName: "com.ohos.stage", - abilityName: "com.ohos.stage.EntryAbility" + abilityName: "EntryAbility" } }; featureAbility.startAbility(parameter).then((code) => { diff --git a/en/application-dev/application-models/want-overview.md b/en/application-dev/application-models/want-overview.md index cf5cac43999a5efbe59659252b6b3db325cacd8a..9260c71666f3c47181756ba205c265391d989b05 100644 --- a/en/application-dev/application-models/want-overview.md +++ b/en/application-dev/application-models/want-overview.md @@ -12,7 +12,7 @@ ## Types of Want -- **Explicit Want**: If **abilityName** and **bundleName** are specified in the **want** parameter when starting an an application component, explicit Want is used. +- **Explicit Want**: If **abilityName** and **bundleName** are specified in the **want** parameter when starting an application component, explicit Want is used. Explicit Want is usually used to start a known target application component in the same application. The target application component is started by specifying **bundleName** of the application where the target application component is located and **abilityName** in the **Want** object. When there is an explicit object to process the request, explicit Want is a simple and effective way to start the target application component. @@ -24,7 +24,7 @@ } ``` -- **Implicit Want**: If **abilityName** is not specified in the **want** parameter when starting the an application component, implicit Want is used. +- **Implicit Want**: If **abilityName** is not specified in the **want** parameter when starting an application component, implicit Want is used. Implicit Want can be used when the object used to process the request is unclear and the current application wants to use a capability (defined by the [skills tag](../quick-start/module-configuration-file.md#skills)) provided by another application. The system matches all applications that declare to support the capability. For example, for a link open request, the system matches all applications that support the request and provides the available ones for users to select. @@ -47,6 +47,7 @@ > - An application component that meets the conditions is matched. That application component is started. > - Multiple application components that meet the conditions are matched. A dialog box is displayed for users to select one of them. > - > - If the **want** parameter passed does not contain **abilityName** or **bundleName**, the ServiceExtensionAbility components of all applications cannot be started through implicit Want. + > - In the scenario for starting the ServiceExtensionAbility component: + > - If the **want** parameter passed in contains **abilityName**, the ServiceExtensionAbility component cannot be started through implicit Want. > - > - If the **want** parameter passed contains **bundleName**, the **startServiceExtensionAbility()** method can be used to implicitly start ServiceExtensionAbility. By default, ServiceExtensionAbility with the highest priority is returned. If all the matching ServiceExtensionAbility components have the same priority, the first ServiceExtensionAbility is returned. + > - If the **want** parameter passed in contains **bundleName**, the **startServiceExtensionAbility()** method can be used to implicitly start the ServiceExtensionAbility component. By default, the ServiceExtensionAbility component with the highest priority is returned. If all the matching ServiceExtensionAbility components have the same priority, the first ServiceExtensionAbility component is returned. diff --git a/en/application-dev/arkts-utils/cpu-intensive-task-development.md b/en/application-dev/arkts-utils/cpu-intensive-task-development.md index 80ecd66bb86f11bb4b0dace92e8e6924bdbd8b4f..da11a1866dbeb1d374972fde6579676387d97ada 100644 --- a/en/application-dev/arkts-utils/cpu-intensive-task-development.md +++ b/en/application-dev/arkts-utils/cpu-intensive-task-development.md @@ -15,6 +15,7 @@ If a task does not need to occupy a background thread for a long time (3 minutes 1. Implement the logic of image processing. 2. Segment the data, and initiate associated task scheduling through task groups. + Create a [task group](../reference/apis/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis/js-apis-taskpool.md#addtask10) to add tasks, call [execute()](../reference/apis/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group, and set [a high priority](../reference/apis/js-apis-taskpool.md#priority) for the task group. After all the tasks in the task group are complete, the histogram processing result is returned simultaneously. 3. Summarize and process the result arrays. @@ -78,7 +79,7 @@ The following uses the training of a region-specific house price prediction mode ![newWorker](figures/newWorker.png) -2. In the main thread, call [ThreadWorker()](../reference/apis/js-apis-worker.md#threadworker9) to create a **Worker** object. The calling thread is the host thread. +2. In the main thread, call [constructor()](../reference/apis/js-apis-worker.md#constructor9) of **ThreadWorker** to create a **Worker** object. The calling thread is the host thread. ```js import worker from '@ohos.worker'; @@ -167,24 +168,22 @@ The following uses the training of a region-specific house price prediction mode 6. After the task is completed in the worker thread, destroy the worker thread. The worker thread can be destroyed by itself or the host thread. Then, call [onexit()](../reference/apis/js-apis-worker.md#onexit9) in the host thread to define the processing logic after the worker thread is destroyed. - ```js // After the worker thread is destroyed, execute the onexit() callback. workerInstance.onexit = function() { console.info("main thread terminate"); } ``` - - In the host thread, call [terminate()](../reference/apis/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages. - + Method 1: In the host thread, call [terminate()](../reference/apis/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages. + ```js - // Destroy the worker thread. +// Destroy the worker thread. workerInstance.terminate(); ``` - - In the worker thread, call [close()](../reference/apis/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages. + Method 2: In the worker thread, call [close()](../reference/apis/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages. + ```js // Destroy the worker thread. workerPort.close(); diff --git a/en/application-dev/arkts-utils/linear-container.md b/en/application-dev/arkts-utils/linear-container.md index 2a160f113f68e3257278e5a18168bb811a8efe30..84ed8ab890864a7d525aa24c096431b12d3d18e5 100644 --- a/en/application-dev/arkts-utils/linear-container.md +++ b/en/application-dev/arkts-utils/linear-container.md @@ -44,14 +44,14 @@ The APIs provided by **Vector** are deprecated since API version 9. You are advi | Accessing elements| Use **vec\[index]** to obtain the value at a given position (specified by **index**).| | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **getLastElement()** to obtain the last element in this container.| -| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| -| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| +| Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| +| Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, Vector?: Vector<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| | Modifying elements| Use **vec\[index]=xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| | Modifying elements| Use **setLength(newSize: number)** to set the size of this container.| -| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| +| Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| | Deleting elements| Use **removeByRange(fromIndex: number, toIndex: number)** to remove all of the elements within a range.| @@ -74,14 +74,14 @@ You are advised to use **List** for frequent insertion and removal operations. | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **getFirst()** to obtain the first element in this container.| | Accessing elements| Use **getLast()** to obtain the last element in this container.| -| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| -| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| +| Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| +| Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **forEach(callbackfn: (value: T, index?: number, list?: List<T>)=> void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| | Modifying elements| Use **list\[index] = xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| | Modifying elements| Use **replaceAllElements(callbackFn:(value: T,index?: number,list?: List<T>)=>T,thisArg?: Object)** to replace all elements in this container with new elements.| -| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| +| Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| @@ -105,13 +105,13 @@ You are advised to use **LinkedList** for frequent insertion and removal operati | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **getFirst()** to obtain the first element in this container.| | Accessing elements| Use **getLast()** to obtain the last element in this container.| -| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| -| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| +| Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| +| Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, list?: LinkedList<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| | Modifying elements| Use **list\[index]=xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| -| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| +| Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| diff --git a/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md b/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md index 2d42ea1a56cd56eb06cd1e8394735e17fed70a2b..08451191025d01ecfcd3b70f8fb8170826c35dc4 100644 --- a/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md +++ b/en/application-dev/arkts-utils/multi-thread-concurrency-overview.md @@ -12,7 +12,7 @@ Due to the memory isolation feature of the actor model, cross-thread serializati ## Data Transfer Objects -Data objects that can be transferred are classified into three types: [common objects](#common-objects), [transferable objects](#transferable-objects), and [shared objects](#shared-objects). +Data objects that can be transferred are classified into the following types: [common objects](#common-objects), [transferable objects](#transferable-objects), [shared objects](#shared-objects), and [native binding objects](#native-binding-objects). ### Common Objects @@ -24,7 +24,7 @@ The following object types are supported: basic types except Symbol, Date, Strin ### Transferable Objects -Transferable objects are serialized through address transfer. It transfers the ownership of an object of the ArrayBuffer type object, rather than the content in it. After the ownership is transferred, the object becomes unavailable in the sender and can be used only in the receiver. +Transferable objects are serialized through address transfer. It transfers the ownership of an object of the ArrayBuffer type, rather than the content in it. After the ownership is transferred, the object becomes unavailable in the sender and can be used only in the receiver. ```js @@ -47,6 +47,15 @@ If multiple operations are simultaneously performed to modify data stored in an let sharedBuffer = new SharedArrayBuffer(1024); ``` +### Native Binding Objects + +Native binding objects are provided by the system. They are bound to underlying system services and enables direct access to these services. + +Currently, native bound objects that support serialization include [Context](../application-models/application-context-stage.md) and [RemoteObject](../reference/apis/js-apis-rpc.md#remoteobject). + +The **Context** object provides the context information about an application component. It provides a way to access system services and resources so that the application component can interact with the system. For details about how to obtain context information, see [Context (Stage Model)](../application-models/application-context-stage.md). + +The **RemoteObject** object implements remote communication. It transfers the reference of an object between processes so that these processes can share the status and methods of the object. The service provider must inherit this class. For details about how to create a **RemoteObject** object, see [RemoteObject](../reference/apis/js-apis-rpc.md#remoteobject). ## TaskPool and Worker diff --git a/en/application-dev/arkts-utils/nonlinear-container.md b/en/application-dev/arkts-utils/nonlinear-container.md index 3287d2675528cd73c0e43c562263b5af07bfaf46..b5c6380ae873b9dc47b69a6754b357f7dac8c1c8 100644 --- a/en/application-dev/arkts-utils/nonlinear-container.md +++ b/en/application-dev/arkts-utils/nonlinear-container.md @@ -52,9 +52,9 @@ You are advised to use **HashSet** when you need a set that has only unique elem | Adding elements| Use **add(value: T)** to add a value to this container.| | Accessing elements| Use **values()** to return an iterator that contains all the values in this container.| | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| -| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet) => void, thisArg?: Object)** to traverse the elements in this container.| +| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| -| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet) => void, thisArg?: Object)** to change a value in this container.| +| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet\) => void, thisArg?: Object)** to change a value in this container.| | Deleting elements| Use **remove(value: T)** to remove a value.| | Deleting elements| Use **clear()** to clear this container.| @@ -109,9 +109,9 @@ You are advised to use **TreeSet** when you need to store data in sorted order. | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| | Accessing elements| Use **getFirstValue()** to obtain the first value in this container.| | Accessing elements| Use **getLastValue()** to obtain the last value in this container.| -| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet) => void, thisArg?: Object)** to traverse the elements in this container.| +| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| -| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet) => void, thisArg?: Object)** to change a value in this container.| +| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\) => void, thisArg?: Object)** to change a value in this container.| | Deleting elements| Use **remove(value: T)** to remove a value.| | Deleting elements| Use **clear()** to clear this container.| @@ -169,9 +169,9 @@ You are advised to use **LightWeightSet** when you need a set that has only uniq | Accessing elements| Use **values()** to return an iterator that contains all the values in this container.| | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| | Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).| -| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet) => void, thisArg?: Object)** to traverse the elements in this container.| +| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<T>** for data access.| -| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet) => void, thisArg?: Object)** to change a value in this container.| +| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\) => void, thisArg?: Object)** to change a value in this container.| | Deleting elements| Use **remove(key: K)** to remove an element with the specified key.| | Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).| | Deleting elements| Use **clear()** to clear this container.| @@ -197,10 +197,10 @@ You are advised to use PlainArray when you need to store KV pairs whose keys are | Accessing elements| Use **getIndexOfValue(value: T)** to obtain the index of the specified value.| | Accessing elements| Use **getKeyAt(index: number)** to obtain the key of an element at a given position (specified by **index**).| | Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).| -| Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray) => void, thisArg?: Object)** to traverse the elements in this container.| +| Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator<[number, T]>** for data access.| | Modifying elements| Use **setValueAt(index:number, value: T)** to change the value of an element at a given position (specified by **index**).| -| Modifying elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray) => void, thisArg?: Object)** to modify an element in this container.| +| Modifying elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\) => void, thisArg?: Object)** to modify an element in this container.| | Deleting elements| Use **remove(key: number)** to remove an element with the specified key.| | Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).| | Deleting elements| Use **removeRangeFrom(index: number, size: number)** to remove elements in a specified range.| diff --git a/en/application-dev/arkts-utils/xml-parsing.md b/en/application-dev/arkts-utils/xml-parsing.md index dd3e46517b3eec6aafce6d6566a2da982bbd8d6c..89ed22585be75803b281517d390f400ceeda9d4d 100644 --- a/en/application-dev/arkts-utils/xml-parsing.md +++ b/en/application-dev/arkts-utils/xml-parsing.md @@ -4,7 +4,7 @@ Data transferred in XML format must be parsed in actual use. Generally, three types of elements need to be parsed, as described in [Parsing XML Tags and Tag Values](#parsing-xml-tags-and-tag-values), [Parsing XML Attributes and Attribute Values](#parsing-xml-attributes-and-attribute-values), and [Parsing XML Event Types and Element Depths](#parsing-xml-event-types-and-element-depths). -The **xml** module provides the **XmlPullParser** class to parse XML files. The input is an object of the ArrayBufffer or DataView type containing XML text, and the output is the parsed information. +The **xml** module provides the **XmlPullParser** class to parse XML files. The input is an object of the ArrayBuffer or DataView type containing XML text, and the output is the parsed information. **Table 1** XML parsing options diff --git a/en/application-dev/connectivity/Readme-EN.md b/en/application-dev/connectivity/Readme-EN.md index c09ca21b6d0814bd1cd2cecb95b0d2896fada8c4..1a391bd7af03ae3c5d01eb01e14b66efd1f0c565 100755 --- a/en/application-dev/connectivity/Readme-EN.md +++ b/en/application-dev/connectivity/Readme-EN.md @@ -9,6 +9,8 @@ - [Ethernet Connection](net-ethernet.md) - [Network Connection Management](net-connection-manager.md) - [mDNS Management](net-mdns.md) + - [Traffic Management](net-statistics.md) + - [VPN Management](net-vpn.md) - IPC & RPC - [IPC & RPC Overview](ipc-rpc-overview.md) - [IPC & RPC Development](ipc-rpc-development-guideline.md) diff --git a/en/application-dev/connectivity/http-request.md b/en/application-dev/connectivity/http-request.md index 1bb784cf96fb1d74dcbafed54498435f505814b6..a0fa4102864ba2403e7a6826f3ca3b872b5a80dd 100644 --- a/en/application-dev/connectivity/http-request.md +++ b/en/application-dev/connectivity/http-request.md @@ -1,6 +1,6 @@ # HTTP Data Request -## When to Use +## Overview An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**. @@ -18,7 +18,7 @@ The following table provides only a simple description of the related APIs. For | ----------------------------------------- | ----------------------------------- | | createHttp() | Creates an HTTP request. | | request() | Initiates an HTTP request to a given URL. | -| request2()10+ | Initiates an HTTP network request based on the URL and returns a streaming response.| +| requestInStream()10+ | Initiates an HTTP network request to a given URL and returns a streaming response.| | destroy() | Destroys an HTTP request. | | on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. | | off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events.| @@ -27,8 +27,8 @@ The following table provides only a simple description of the related APIs. For | off\('dataReceive'\)10+ | Unregisters the observer for events indicating receiving of HTTP streaming responses. | | on\('dataEnd'\)10+ | Registers an observer for events indicating completion of receiving HTTP streaming responses. | | off\('dataEnd'\)10+ | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.| -| on\('dataProgress'\)10+ | Registers an observer for events indicating progress of receiving HTTP streaming responses. | -| off\('dataProgress'\)10+ | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.| +| on\('dataReceiveProgress'\)10+ | Registers an observer for events indicating progress of receiving HTTP streaming responses. | +| off\('dataReceiveProgress'\)10+ | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.| ## How to Develop request APIs @@ -53,6 +53,7 @@ httpRequest.on('headersReceive', (header) => { }); httpRequest.request( // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. + "EXAMPLE_URL", { method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET. // You can add header fields based on service requirements. @@ -81,7 +82,7 @@ httpRequest.request( // Call the destroy() method to release resources after HttpRequest is complete. httpRequest.destroy(); } else { - console.info('error:' + JSON.stringify(err)); + console.error('error:' + JSON.stringify(err)); // Unsubscribe from HTTP Response Header events. httpRequest.off('headersReceive'); // Call the destroy() method to release resources after HttpRequest is complete. @@ -91,12 +92,12 @@ httpRequest.request( ); ``` -## How to Develop request2 APIs +## How to Develop requestInStream APIs 1. Import the **http** namespace from **@ohos.net.http.d.ts**. 2. Call **createHttp()** to create an **HttpRequest** object. 3. Depending on your need, call **on()** of the **HttpRequest** object to subscribe to HTTP response header events as well as events indicating receiving of HTTP streaming responses, progress of receiving HTTP streaming responses, and completion of receiving HTTP streaming responses. -4. Call **request2()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request. +4. Call **requestInStream()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request. 5. Parse the returned response code as needed. 6. Call **off()** of the **HttpRequest** object to unsubscribe from the related events. 7. Call **httpRequest.destroy()** to release resources after the request is processed. @@ -122,11 +123,11 @@ httpRequest.on('dataEnd', () => { console.info('No more data in response, data receive end'); }); // Subscribe to events indicating progress of receiving HTTP streaming responses. -httpRequest.on('dataProgress', (data) => { - console.log("dataProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize); +httpRequest.on('dataReceiveProgress', (data) => { + console.log("dataReceiveProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize); }); -httpRequest.request2( +httpRequest.requestInStream( // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. "EXAMPLE_URL", { @@ -146,14 +147,14 @@ httpRequest.request2( readTimeout: 60000, // Optional. The default value is 60000, in ms. If a large amount of data needs to be transmitted, you are advised to set this parameter to a larger value to ensure normal data transmission. usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system. }, (err, data) => { - console.info('error:' + JSON.stringify(err)); + console.error('error:' + JSON.stringify(err)); console.info('ResponseCode :' + JSON.stringify(data)); // Unsubscribe from HTTP Response Header events. httpRequest.off('headersReceive'); // Unregister the observer for events indicating receiving of HTTP streaming responses. httpRequest.off('dataReceive'); // Unregister the observer for events indicating progress of receiving HTTP streaming responses. - httpRequest.off('dataProgress'); + httpRequest.off('dataReceiveProgress'); // Unregister the observer for events indicating completion of receiving HTTP streaming responses. httpRequest.off('dataEnd'); // Call the destroy() method to release resources after HttpRequest is complete. @@ -161,10 +162,3 @@ httpRequest.request2( } ); ``` - -## Samples - -The following sample is provided to help you better understand how to develop the HTTP data request feature: - -- [`Http`: Data Request (ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http) -- [HTTP Communication (ArkTS) (API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/SmartChatEtsOH) diff --git a/en/application-dev/connectivity/ipc-rpc-development-guideline.md b/en/application-dev/connectivity/ipc-rpc-development-guideline.md index b9bbb0608dfb83ba6d2198b063e68c4b324bbd88..14016ef5da297361bd4a17a3d278357060590784 100644 --- a/en/application-dev/connectivity/ipc-rpc-development-guideline.md +++ b/en/application-dev/connectivity/ipc-rpc-development-guideline.md @@ -1,6 +1,6 @@ # IPC & RPC Development Guidelines -## When to Use +## Overview IPC/RPC enables a proxy and a stub that run on different processes to communicate with each other, regardless of whether they run on the same or different devices. diff --git a/en/application-dev/connectivity/net-connection-manager.md b/en/application-dev/connectivity/net-connection-manager.md index c443c93759caddbc5203b65022426882c0bb960b..f3b945ab0970786000ab8b04adfe90592a11e0d1 100644 --- a/en/application-dev/connectivity/net-connection-manager.md +++ b/en/application-dev/connectivity/net-connection-manager.md @@ -1,10 +1,11 @@ # Network Connection Management -## Introduction +## Overview The Network Connection Management module provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution. > **NOTE** +> > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-connection.md). ## Basic Concepts @@ -107,7 +108,7 @@ conn.on('netAvailable', (data => { // Listen to network status change events. If the network is unavailable, an on_netUnavailable event is returned. conn.on('netUnavailable', (data => { - console.log("net is unavailable, netId is " + data.netId); + console.log("net is unavailable, data is " + JSON.stringify(data)); })); // Register an observer for network status changes. diff --git a/en/application-dev/connectivity/net-ethernet.md b/en/application-dev/connectivity/net-ethernet.md index 18f20a7fd7e1a4c9516386c543c9521522df5f66..76ae1ee28078520b9d70796f71fd2b9236f47959 100644 --- a/en/application-dev/connectivity/net-ethernet.md +++ b/en/application-dev/connectivity/net-ethernet.md @@ -1,10 +1,11 @@ # Ethernet Connection -## Introduction +## Overview The Ethernet Connection module allows a device to access the Internet through a network cable. After a device is connected to the Ethernet through a network cable, the device can obtain a series of network attributes, such as the dynamically allocated IP address, subnet mask, gateway, and DNS. You can manually configure and obtain the network attributes of the device in static mode. > **NOTE** +> > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-ethernet.md). ## **Constraints** diff --git a/en/application-dev/connectivity/net-mdns.md b/en/application-dev/connectivity/net-mdns.md index de7982a5c03908a70e4005bdc5fbea3584c435f5..75da959da8c4b1fc55aa0afca1cf0dcd945b86bb 100644 --- a/en/application-dev/connectivity/net-mdns.md +++ b/en/application-dev/connectivity/net-mdns.md @@ -1,6 +1,6 @@ # MDNS Management -## Introduction +## Overview Multicast DNS (mDNS) provides functions such as adding, removing, discovering, and resolving local services on a LAN. - Local service: a service provider on a LAN, for example, a printer or scanner. diff --git a/en/application-dev/connectivity/net-sharing.md b/en/application-dev/connectivity/net-sharing.md index 4072217d9ced5d99b2052b5db8ccb8333fcb7023..f2b2e6ac21362691ede111db8b16316fa9fd32cb 100644 --- a/en/application-dev/connectivity/net-sharing.md +++ b/en/application-dev/connectivity/net-sharing.md @@ -1,10 +1,11 @@ # Network Sharing -## Introduction +## Overview The Network Sharing module allows you to share your device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing. It also allows you to query the network sharing state and shared mobile data volume. > **NOTE** +> > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-sharing.md). ## Basic Concepts diff --git a/en/application-dev/connectivity/net-statistics.md b/en/application-dev/connectivity/net-statistics.md index 47ec62ff156448b3214885176c30b2f76d77b76c..6df8800dd479b48c32619514b8e6b90d5c776330 100644 --- a/en/application-dev/connectivity/net-statistics.md +++ b/en/application-dev/connectivity/net-statistics.md @@ -1,6 +1,6 @@ # Traffic Management -## Introduction +## Overview The traffic management module allows you to query real-time or historical data traffic by the specified network interface card (NIC) or user ID (UID). @@ -11,6 +11,7 @@ Its functions include: - Subscribing to traffic change events by NIC or UID > **NOTE** +> > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [Traffic Management](../reference/apis/js-apis-net-statistics.md). The following describes the development procedure specific to each application scenario. diff --git a/en/application-dev/connectivity/net-vpn.md b/en/application-dev/connectivity/net-vpn.md new file mode 100644 index 0000000000000000000000000000000000000000..a93b00b932bdec33de7cb45764474c163ed456ce --- /dev/null +++ b/en/application-dev/connectivity/net-vpn.md @@ -0,0 +1,363 @@ +# VPN Management + +## Overview + +A virtual private network (VPN) is a dedicated network established on a public network. On a VPN, the connection between any two nodes does not have an end-to-end physical link required by the traditional private network. Instead, user data is transmitted over a logical link because a VPN is a logical network deployed over the network platform (such as the Internet) provided by the public network service provider. + +> **NOTE** +> +> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [Traffic Management](../reference/apis/js-apis-net-vpn.md). + +The following describes the development procedure specific to each application scenario. + +## Available APIs + +For the complete list of APIs and example code, see [VPN Management](../reference/apis/js-apis-net-vpn.md). + +| Type| API| Description| +| ---- | ---- | ---- | +| ohos.net.vpn | setUp(config: VpnConfig, callback: AsyncCallback\): void | Establishes a VPN. This API uses an asynchronous callback to return the result.| +| ohos.net.vpn | protect(socketFd: number, callback: AsyncCallback\): void | Enables VPN tunnel protection. This API uses an asynchronous callback to return the result.| +| ohos.net.vpn | destroy(callback: AsyncCallback\): void | Destroys a VPN. This API uses an asynchronous callback to return the result.| + +## Starting a VPN + +1. Establish a VPN tunnel. The following uses the UDP tunnel as an example. +2. Enable protection for the UDP tunnel. +3. Establish a VPN. +4. Process data of the virtual network interface card (vNIC), such as reading or writing data. +5. Destroy the VPN. + +This example shows how to develop an application using native C++ code. For details, see [Simple Native C++ Example (ArkTS) (API9)] (https://gitee.com/openharmony/codelabs/tree/master/NativeAPI/NativeTemplateDemo). + +The sample application consists of two parts: JS code and C++ code. + +## JS Code +The JS code is used to implement the service logic, such as creating a tunnel, establishing a VPN, enabling VPN protection, and destroying a VPN. + +```js +import hilog from '@ohos.hilog'; +import vpn from '@ohos.net.vpn'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import vpn_client from "libvpn_client.so" + +class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage) { + globalThis.context = this.context; + } +} + +let TunnelFd = -1 +let VpnConnection = vpn.createVpnConnection(globalThis.context) + +@Entry +@Component +struct Index { + @State message: string = 'Test VPN' + + //1. Establish a VPN tunnel. The following uses the UDP tunnel as an example. + CreateTunnel() { + TunnelFd = vpn_client.udpConnect("192.168.43.208", 8888) + } + + // 2. Enable protection for the UDP tunnel. + Protect() { + VpnConnection.protect(TunnelFd).then(function () { + console.info("vpn Protect Success.") + }).catch(function (err) { + console.info("vpn Protect Failed " + JSON.stringify(err)) + }) + } + + SetupVpn() { + let config = { + addresses: [{ + address: { + address: "10.0.0.5", + family: 1 + }, + prefixLength: 24, + }], + routes: [], + mtu: 1400, + dnsAddresses: [ + "114.114.114.114" + ], + acceptedApplications: [], + refusedApplications: [] + } + + try { + // 3. Create a VPN. + VpnConnection.setUp(config, (error, data) => { + console.info("tunfd: " + JSON.stringify(data)); + // 4. Process data of the virtual vNIC, such as reading or writing data. + vpn_client.startVpn(data, TunnelFd) + }) + } catch (error) { + console.info("vpn setUp fail " + JSON.stringify(error)); + } + } + + // 5. Destroy the VPN. + Destroy() { + vpn_client.stopVpn(TunnelFd) + VpnConnection.destroy().then(function () { + console.info("vpn Destroy Success.") + }).catch(function (err) { + console.info("vpn Destroy Failed " + JSON.stringify(err)) + }) + } + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + console.info("vpn Client") + }) + Button('CreateTunnel').onClick(() => { + this.CreateTunnel() + }).fontSize(50) + Button('Protect').onClick(() => { + this.Protect() + }).fontSize(50) + Button('SetupVpn').onClick(() => { + this.SetupVpn() + }).fontSize(50) + Button('Destroy').onClick(() => { + this.Destroy() + }).fontSize(50) + } + .width('100%') + } + .height('100%') + } +} +``` + +## C++ Code +The C++ code is used for underlying service implementation, such as UDP tunnel client implementation and vNIC data read and write. + +```c++ +#include "napi/native_api.h" +#include "hilog/log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BUFFER_SIZE 2048 + +#define VPN_LOG_TAG "NetMgrVpn" +#define VPN_LOG_DOMAIN 0x15b0 +#define MAKE_FILE_NAME (strrchr(__FILE__, '/') + 1) + +#define NETMANAGER_VPN_LOGE(fmt, ...) \ + OH_LOG_Print(LOG_APP, LOG_ERROR, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \ + __LINE__, ##__VA_ARGS__) + +#define NETMANAGER_VPN_LOGI(fmt, ...) \ + OH_LOG_Print(LOG_APP, LOG_INFO, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \ + __LINE__, ##__VA_ARGS__) + +#define NETMANAGER_VPN_LOGD(fmt, ...) \ + OH_LOG_Print(LOG_APP, LOG_DEBUG, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \ + __LINE__, ##__VA_ARGS__) + +struct FdInfo { + int32_t tunFd = 0; + int32_t tunnelFd = 0; + struct sockaddr_in serverAddr; +}; + +static FdInfo fdInfo; +static bool threadRunF = false; +static std::thread threadt1; +static std::thread threadt2; + +// Obtain the IP address of the UDP server. +static constexpr const int MAX_STRING_LENGTH = 1024; +std::string GetStringFromValueUtf8(napi_env env, napi_value value) { + std::string result; + char str[MAX_STRING_LENGTH] = {0}; + size_t length = 0; + napi_get_value_string_utf8(env, value, str, MAX_STRING_LENGTH, &length); + if (length > 0) { + return result.append(str, length); + } + return result; +} + +void HandleReadTunfd(FdInfo fdInfo) { + uint8_t buffer[BUFFER_SIZE] = {0}; + while (threadRunF) { + int ret = read(fdInfo.tunFd, buffer, sizeof(buffer)); + if (ret <= 0) { + if (errno != 11) { + NETMANAGER_VPN_LOGE("read tun device error: %{public}d, tunfd: %{public}d", errno, fdInfo.tunFd); + } + continue; + } + + // Read data from the vNIC and send the data to the UDP server through the UDP tunnel. + NETMANAGER_VPN_LOGD("buffer: %{public}s, len: %{public}d", buffer, ret); + ret = sendto(fdInfo.tunnelFd, buffer, ret, 0, (struct sockaddr *)&fdInfo.serverAddr, sizeof(fdInfo.serverAddr)); + if (ret <= 0) { + NETMANAGER_VPN_LOGE("send to server[%{public}s:%{public}d] failed, ret: %{public}d, error: %{public}s", + inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), ret, + strerror(errno)); + continue; + } + } +} + +void HandleTcpReceived(FdInfo fdInfo) { + int addrlen = sizeof(struct sockaddr_in); + uint8_t buffer[BUFFER_SIZE] = {0}; + while (threadRunF) { + int length = recvfrom(fdInfo.tunnelFd, buffer, sizeof(buffer), 0, (struct sockaddr *)&fdInfo.serverAddr, + (socklen_t *)&addrlen); + if (length < 0) { + if (errno != 11) { + NETMANAGER_VPN_LOGE("read tun device error: %{public}d, tunnelfd: %{public}d", errno, fdInfo.tunnelFd); + } + continue; + } + + // Receive data from the UDP server and write the data to the vNIC. + NETMANAGER_VPN_LOGD("from [%{public}s:%{public}d] data: %{public}s, len: %{public}d", + inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), buffer, length); + int ret = write(fdInfo.tunFd, buffer, length); + if (ret <= 0) { + NETMANAGER_VPN_LOGE("error Write To Tunfd, errno: %{public}d", errno); + } + } +} + +static napi_value UdpConnect(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + int32_t port = 0; + napi_get_value_int32(env, args[1], &port); + std::string ipAddr = GetStringFromValueUtf8(env, args[0]); + + NETMANAGER_VPN_LOGI("ip: %{public}s port: %{public}d", ipAddr.c_str(), port); + + // Establish a UDP tunnel. + int32_t sockFd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockFd == -1) { + NETMANAGER_VPN_LOGE("socket() error"); + return 0; + } + + struct timeval timeout = {1, 0}; + setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); + + memset(&fdInfo.serverAddr, 0, sizeof(fdInfo.serverAddr)); + fdInfo.serverAddr.sin_family = AF_INET; + fdInfo.serverAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str()); // server's IP addr + fdInfo.serverAddr.sin_port = htons(port); // port + + NETMANAGER_VPN_LOGI("Connection successful"); + + napi_value tunnelFd; + napi_create_int32(env, sockFd, &tunnelFd); + return tunnelFd; +} + +static napi_value StartVpn(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + napi_get_value_int32(env, args[0], &fdInfo.tunFd); + napi_get_value_int32(env, args[1], &fdInfo.tunnelFd); + + if (threadRunF) { + threadRunF = false; + threadt1.join(); + threadt2.join(); + } + + // Start two threads. One is used to read data from the vNIC, and the other is used to receive data from the server. + threadRunF = true; + std::thread tt1(HandleReadTunfd, fdInfo); + std::thread tt2(HandleTcpReceived, fdInfo); + + threadt1 = std::move(tt1); + threadt2 = std::move(tt2); + + NETMANAGER_VPN_LOGI("StartVpn successful"); + + napi_value retValue; + napi_create_int32(env, 0, &retValue); + return retValue; +} + +static napi_value StopVpn(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + int32_t tunnelFd; + napi_get_value_int32(env, args[0], &tunnelFd); + if (tunnelFd) { + close(tunnelFd); + tunnelFd = 0; + } + + // Stop the two threads. + if (threadRunF) { + threadRunF = false; + threadt1.join(); + threadt2.join(); + } + + NETMANAGER_VPN_LOGI("StopVpn successful"); + + napi_value retValue; + napi_create_int32(env, 0, &retValue); + return retValue; +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor desc[] = { + {"udpConnect", nullptr, UdpConnect, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"startVpn", nullptr, StartVpn, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"stopVpn", nullptr, StopVpn, nullptr, nullptr, nullptr, napi_default, nullptr}, + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void *)0), + .reserved = {0}, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { + napi_module_register(&demoModule); +} +``` diff --git a/en/application-dev/connectivity/socket-connection.md b/en/application-dev/connectivity/socket-connection.md index 9dda8b4e4c0ac6931ea75ad706fef76c9fb3c0a3..fe8ab1f141e3525de46985ba113eee364adac723 100644 --- a/en/application-dev/connectivity/socket-connection.md +++ b/en/application-dev/connectivity/socket-connection.md @@ -1,6 +1,6 @@ # Socket Connection -## Introduction +## Overview The Socket Connection module allows an application to transmit data over a socket connection through the TCP, UDP, or TLS protocol. diff --git a/en/application-dev/connectivity/subscribe-remote-state.md b/en/application-dev/connectivity/subscribe-remote-state.md index 5b21750ba8b56fefcb10a5fff653d7512765c279..d23385e44752cb0945217eddc74117202ca38c5f 100755 --- a/en/application-dev/connectivity/subscribe-remote-state.md +++ b/en/application-dev/connectivity/subscribe-remote-state.md @@ -1,5 +1,7 @@ # Subscribing to State Changes of a Remote Object +## Overview + IPC/RPC allows you to subscribe to the state changes of a remote stub object. When the remote stub object dies, a death notification will be sent to your local proxy object. Such subscription and unsubscription are controlled by APIs. To be specific, you need to implement the **DeathRecipient** interface and the **onRemoteDied** API to clear resources. This callback is invoked when the process accommodating the remote stub object dies, or the device accommodating the remote stub object leaves the network. It is worth noting that these APIs should be called in the following order: The proxy object must first subscribe to death notifications of the stub object. If the stub object is in the normal state, the proxy object can cancel the subscription as required. If the process of the stub object exits or the device hosting the stub object goes offline, subsequent operations customized by the proxy object will be automatically triggered. ## When to Use diff --git a/en/application-dev/connectivity/websocket-connection.md b/en/application-dev/connectivity/websocket-connection.md index 4c373011c45be18183e4c622c3e7e35b97198a24..1b162256db5cad28aa50ca6989625f9191fb2257 100644 --- a/en/application-dev/connectivity/websocket-connection.md +++ b/en/application-dev/connectivity/websocket-connection.md @@ -1,6 +1,6 @@ # WebSocket Connection -## When to Use +## Overview You can use WebSocket to establish a bidirectional connection between a server and a client. Before doing this, you need to use the **createWebSocket()** API to create a **WebSocket** object and then use the **connect()** API to connect to the server. If the connection is successful, the client will receive a callback of the **open** event. Then, the client can communicate with the server using the **send()** API. When the server sends a message to the client, the client will receive a callback of the **message** event. If the client no longer needs this connection, it can call the **close()** API to disconnect from the server. Then, the client will receive a callback of the **close** event. diff --git a/en/application-dev/database/data-persistence-by-preferences.md b/en/application-dev/database/data-persistence-by-preferences.md index e37c12369d59d2165220c8d8f5bbaa85029c37df..553050a55a585dc34e620623eb187a0365b8488e 100644 --- a/en/application-dev/database/data-persistence-by-preferences.md +++ b/en/application-dev/database/data-persistence-by-preferences.md @@ -68,7 +68,7 @@ The following table lists the APIs used for persisting user preference data. For return; } console.info('Succeeded in getting preferences.'); - // Perform related data operations. + // Before performing related data operations, obtain a Preferences instance. }) } catch (err) { console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`); @@ -93,7 +93,7 @@ The following table lists the APIs used for persisting user preference data. For return; } console.info('Succeeded in getting preferences.'); - // Perform related data operations. + // Before performing related data operations, obtain a Preferences instance. }) } catch (err) { console.error(`Failed to get preferences. Code is ${err.code},message:${err.message}`); @@ -220,4 +220,4 @@ The following table lists the APIs used for persisting user preference data. For } catch (err) { console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`); } - ``` + ``` \ No newline at end of file diff --git a/en/application-dev/database/data-sync-of-kv-store.md b/en/application-dev/database/data-sync-of-kv-store.md index eb8994570f04b0d6690c2b91b1b1745602e980fb..b23dd91ed1a7b4ea0cd13f6d9b49de82e1821190 100644 --- a/en/application-dev/database/data-sync-of-kv-store.md +++ b/en/application-dev/database/data-sync-of-kv-store.md @@ -171,7 +171,7 @@ The following uses a single KV store as an example to describe how to implement return; } console.info('Succeeded in getting KVStore.'); - // Perform related data operations. + // Before performing related data operations, obtain a KV store instance. }); } catch (e) { console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`); @@ -275,4 +275,4 @@ The following uses a single KV store as an example to describe how to implement } } }); - ``` + ``` \ No newline at end of file diff --git a/en/application-dev/dfx/Readme-EN.md b/en/application-dev/dfx/Readme-EN.md index 5a1b6326bae1ecb94ef7fe8d9e4cfe2cdf2c6c56..c40f752d8f85e8894eb725965f50a7614dddef36 100644 --- a/en/application-dev/dfx/Readme-EN.md +++ b/en/application-dev/dfx/Readme-EN.md @@ -1,7 +1,6 @@ # DFX - [Development of Application Event Logging](hiappevent-guidelines.md) -- [Development of Performance Tracing](hitracemeter-guidelines.md) - [Development of Distributed Call Chain Tracing](hitracechain-guidelines.md) - [HiLog Development (Native)](hilog-guidelines.md) - Performance Tracing diff --git a/en/application-dev/dfx/appfreeze-guidelines.md b/en/application-dev/dfx/appfreeze-guidelines.md index 05b52c4d8070386ec350701cefb2c6b63ef67d55..4984c95e215fe832f59abc3306bf777c6c313818 100644 --- a/en/application-dev/dfx/appfreeze-guidelines.md +++ b/en/application-dev/dfx/appfreeze-guidelines.md @@ -1,6 +1,6 @@ # Application Freeze (appfreeze) Log Analysis -## Introduction +## Overview Application freeze (appfreeze) means that an application does not respond to user operations (for example, clicking) within a given period of time. OpenHarmony provides a mechanism for detecting appfreeze faults and generates appfreeze logs for fault analysis. diff --git a/en/application-dev/dfx/apprecovery-guidelines.md b/en/application-dev/dfx/apprecovery-guidelines.md index 284de5ca6d5f6027f2cce975a29b3259b2778021..9548404b3b359ad3f6fbe6778e0ddaeb374cc2ec 100644 --- a/en/application-dev/dfx/apprecovery-guidelines.md +++ b/en/application-dev/dfx/apprecovery-guidelines.md @@ -1,6 +1,6 @@ # Application Recovery Development -## When to Use +## Overview During application running, some unexpected behaviors are inevitable. For example, unprocessed exceptions and errors are thrown, and the call or running constraints of the recovery framework are violated. @@ -99,9 +99,12 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant' - Define and register the [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) callback. For details about its usage, see [errorManager](../reference/apis/js-apis-app-ability-errorManager.md). ```ts - var registerId = -1; - var callback = { - onUnhandledException(errMsg) { + export let abilityWant : Want // file1 + + import * as G form "../file1" + let registerId = -1; + let callback: Callback = { + onUnhandledException(errMsg: string): void { console.log(errMsg); appRecovery.saveAppState(); appRecovery.restartApp(); @@ -112,7 +115,7 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant' // Main window is created, set main page for this ability console.log("[Demo] MainAbility onWindowStageCreate") - globalThis.registerObserver = (() => { + G.registerObserver = (() => { registerId = errorManager.on('error', callback); }) @@ -138,13 +141,16 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state, After the callback triggers **appRecovery.restartApp()**, the application is restarted. After the restart, **onCreate(want, launchParam)** of **MainAbility** is called, and the saved data is in **parameters** of **want**. ```ts +export let abilityWant : Want // file1 + +import * as GlobalWant form "../file1" storage: LocalStorage onCreate(want, launchParam) { console.log("[Demo] MainAbility onCreate") - globalThis.abilityWant = want; + GlobalWant.abilityWant = want; if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { this.storage = new LocalStorage(); - let recoveryData = want.parameters["myData"]; + let recoveryData: string = want.parameters["myData"]; this.storage.setOrCreate("myData", recoveryData); this.context.restoreWindowStage(this.storage); } @@ -154,12 +160,15 @@ onCreate(want, launchParam) { - Unregister the **ErrorObserver** callback. ```ts +export let abilityWant : Want // file1 + +import * as G form "../file1" onWindowStageDestroy() { // Main window is destroyed, release UI related resources console.log("[Demo] MainAbility onWindowStageDestroy") - globalThis.unRegisterObserver = (() => { - errorManager.off('error', registerId, (err) => { + G.unRegisterObserver = (() => { + errorManager.off(type: 'error', registerId: number, (err:Error) => { console.error("[Demo] err:", err); }); }) @@ -171,20 +180,22 @@ onWindowStageDestroy() { This is triggered by the recovery framework. You do not need to register an **ErrorObserver** callback. You only need to implement **onSaveState** for application state saving and **onCreate** for data restore. ```ts +export let abilityWant : Want // file1 + +import * as GlobalWant form "../file1" export default class MainAbility extends Ability { - storage: LocalStorage - onCreate(want, launchParam) { + onCreate(want: Want, launchParam:AbilityConstant.LaunchParam):void { console.log("[Demo] MainAbility onCreate") - globalThis.abilityWant = want; + GlobalWant.abilityWant = want; if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { this.storage = new LocalStorage(); - let recoveryData = want.parameters["myData"]; - this.storage.setOrCreate("myData", recoveryData); + let recoveryData: string = want.parameters["myData"]; + this.storage.setOrCreate("myData", recoveryData); this.context.restoreWindowStage(this.storage); } } - onSaveState(state, wantParams) { + onSaveState(state: AbilityConstant.StateType, wantParams: { [key: string]: Object }) : AbilityConstant.OnSaveResult{ // Ability has called to save app data console.log("[Demo] MainAbility onSaveState") wantParams["myData"] = "my1234567"; diff --git a/en/application-dev/dfx/cppcrash-guidelines.md b/en/application-dev/dfx/cppcrash-guidelines.md index 4454422fe4f3aec6c781090a2e833ee103488dab..15136518788324e23ac46c8c8b5bba327c03ea7a 100644 --- a/en/application-dev/dfx/cppcrash-guidelines.md +++ b/en/application-dev/dfx/cppcrash-guidelines.md @@ -1,6 +1,6 @@ -# cppcrash Log Analysis +# Process Crash (cppcrash) Log Analysis -## Introduction +## Overview A process crash refers to a C/C++ runtime crash. The FaultLogger module of OpenHarmony provides capabilities such as process crash detection, log collection, log storage, and log reporting, helping you to locate faults more effectively. @@ -23,7 +23,7 @@ Process crash detection is implemented based on the Linux signal mechanism. Curr ## Crash Log Collection -Process crash log is the fault log managed together with the app freeze and JS application crash logs by the FaultLogger module. You can collect process crash logs in any of the following ways: +Process crash log is a type of fault logs managed together with the app freeze and JS application crash logs by the FaultLogger module. You can collect process crash logs in any of the following ways: ### Collecting Logs by Using Shell @@ -72,17 +72,14 @@ Thread name:crasher <- Abnormal thread ### Locating Faults Through Logs -1. Determine the faulty module and fault type based on fault logs. - - Generally, you can identify the faulty module based on the crash process name and identify the crash cause based on the signal. Besides, you can restore the function call chain of the crash stack based on the method name in the stack. - - In the example, **SIGSEGV** is thrown by the Linux kernel because of access to an invalid memory address. The problem occurs in the **TriggerSegmentFaultException** function. - - In most scenarios, a crash is caused by the top layer of the crash stack, such as null pointer access and proactive program abort. +- Determine the faulty module and fault type based on fault logs. + Generally, you can identify the faulty module based on the crash process name and identify the crash cause based on the signal. Besides, you can restore the function call chain of the crash stack based on the method name in the stack.\ + In the example, **SIGSEGV** is thrown by the Linux kernel because of access to an invalid memory address. The problem occurs in the **TriggerSegmentFaultException** function.\ + In most scenarios, a crash is caused by the top layer of the crash stack, such as null pointer access and proactive program abort.\ If the cause cannot be located through the call stack, you need to check for other faults, for example, memory corruption or stack overflow. -2. Use the addr2line tool of Linux to parse the code line number to restore the call stack at the time of process crash. +- Use the addr2line tool of Linux to parse the code line number to restore the call stack at the time of process crash. When using the addr2line tool to parse the code line number of the crash stack, make sure that binary files with debugging information is used. Generally, such files are generated during version build or application build. @@ -94,17 +91,17 @@ Thread name:crasher <- Abnormal thread \code root directory\out\product\exe.unstripped ``` - You can run `apt-get install addr2line` to install the addr2line tool on Linux. - + You can run `apt-get install addr2line` to install the addr2line tool on Linux.\ On On DevEco Studio, you can also use the llvm-addr2line tool archived in the SDK to parse code line numbers. The usage method is the same. - The following example shows how to use the addr2line tool to parse the code line number based on the offset address: + The following example shows how to use the addr2line tool to parse the code line number based on the offset address. + + **[product name]** indicates the device name. ``` - root:~/OpenHarmony/out/rk3568/exe.unstripped/hiviewdfx/faultloggerd$ addr2line -e crasher 0000332c + root:~/OpenHarmony/out/[product name]/exe.unstripped/hiviewdfx/faultloggerd$ addr2line -e crasher 0000332c base/hiviewdfx/faultloggerd/tools/crasher/dfx_crasher.c:57 ``` - In this example, the crash is caused by assignment of a value to an unwritable area. It is in code line 57 in the **dfx_crasher.c** file. You can modify it to avoid the crash. - + In this example, the crash is caused by assignment of a value to an unwritable area. It is in code line 57 in the **dfx_crasher.c** file. You can modify it to avoid the crash.\ If the obtained code line number is seemingly incorrect, you can fine-tune the address (for example, subtract the address by 1) or disable some compilation optimization items. It is known that the obtained code line number may be incorrect when Link Time Optimization (LTO) is enabled. diff --git a/en/application-dev/dfx/errormanager-guidelines.md b/en/application-dev/dfx/errormanager-guidelines.md index 4679cfcfc78893590fe73eab770e49fc68a1a828..14d7735d731d0fb2eb3fc41f61de58f5de7f4e02 100644 --- a/en/application-dev/dfx/errormanager-guidelines.md +++ b/en/application-dev/dfx/errormanager-guidelines.md @@ -1,6 +1,6 @@ # Development of Error Manager -## When to Use +## Overview If coding specification issues or errors exist in the code of an application, the application may encounter unexpected errors, for example, uncaught exceptions or application lifecycle timeouts, while it is running. In such a case, the application may exit unexpectedly. Error logs, however, are usually stored on users' local storage, making it inconvenient to locate faults. With the APIs provided by the **errorManager** module, your application will be able to report related errors and logs to your service platform for fault locating before it exits. diff --git a/en/application-dev/dfx/hiappevent-guidelines.md b/en/application-dev/dfx/hiappevent-guidelines.md index d21d4e3fa9e0fa0b795c82e7157cd6215eab5e0c..6b0f4dd1cb8ec36288514e3f8767770f4e30105b 100644 --- a/en/application-dev/dfx/hiappevent-guidelines.md +++ b/en/application-dev/dfx/hiappevent-guidelines.md @@ -1,6 +1,6 @@ # Development of Application Event Logging -## Introduction +## Overview A traditional log system aggregates log information generated by all applications running on the entire device, making it difficult to identify key information in the log. Therefore, an effective logging mechanism is needed to evaluate mission-critical information, for example, number of visits, number of daily active users, user operation habits, and key factors that affect application usage. diff --git a/en/application-dev/dfx/hilog-guidelines.md b/en/application-dev/dfx/hilog-guidelines.md index 25b4a7f9cc5c92d9f20ed6582299d5dd65b937d0..45d46c01fb4c601241120ce9cf5d249bd0bc893f 100644 --- a/en/application-dev/dfx/hilog-guidelines.md +++ b/en/application-dev/dfx/hilog-guidelines.md @@ -1,6 +1,6 @@ # HiLog Development (Native) -## Introduction +## Overview HiLog is the log system of OpenHarmony that provides logging for the system framework, services, and applications to record information on user operations and system running status. diff --git a/en/application-dev/dfx/hitracechain-guidelines.md b/en/application-dev/dfx/hitracechain-guidelines.md index affd260b0503f3c4f4c4b748d5911d94f7fef9e3..44e2da92dfbf985f27a275ac6e02e61a934d199e 100644 --- a/en/application-dev/dfx/hitracechain-guidelines.md +++ b/en/application-dev/dfx/hitracechain-guidelines.md @@ -1,6 +1,6 @@ # Development of Distributed Call Chain Tracing -## Introduction +## Overview The hiTraceChain module provides APIs to implement call chain tracing throughout a service process. This can help you quickly obtain the run log for the call chain of a specified service process and locate faults in inter-device, inter-process, or inter-thread communications. diff --git a/en/application-dev/dfx/hitracemeter-guidelines.md b/en/application-dev/dfx/hitracemeter-guidelines.md index ed99e4e89d5b6fce3d5bd50ef8dedcfc32b04fb1..195aae4b2d98dd1ab950613c6c97ed07cfcfe98e 100644 --- a/en/application-dev/dfx/hitracemeter-guidelines.md +++ b/en/application-dev/dfx/hitracemeter-guidelines.md @@ -1,6 +1,6 @@ # Development of Performance Tracing (ArkTS) -## Introduction +## Overview hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance. @@ -21,7 +21,7 @@ hiTraceMeter provides APIs for system performance tracing. You can call the APIs ## Available APIs -The performance tracing APIs are provided by the **hiTraceMeter** module. For details, see [API Reference](../reference/apis/js-apis-hitracemeter.md). +The performance tracing APIs are provided by the **hiTraceMeter** module. For details, see [API Reference]( ../reference/apis/js-apis-hitracemeter.md). **APIs for performance tracing** @@ -35,60 +35,16 @@ The performance tracing APIs are provided by the **hiTraceMeter** module. For de In this example, distributed call chain tracing begins when the application startup execution page is loaded and stops when the service usage is completed. -1. Create a JS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **js** > **default** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. The sample code is as follows: - - ```js - import hiTraceMeter from '@ohos.hiTraceMeter' - - export default { - data: { - title: "" - }, - onInit() { - this.title = this.$t('strings.world'); - - // Start trace tasks with the same name concurrently. - hiTraceMeter.startTrace("business", 1); - // Keep the service process running. - console.log(`business running`); - hiTraceMeter.startTrace("business", 2); // Start the second trace task with the same name while the first task is still running. The tasks are running concurrently and therefore their taskId must be different. - // Keep the service process running. - console.log(`business running`); - hiTraceMeter.finishTrace("business", 1); - // Keep the service process running. - console.log(`business running`); - hiTraceMeter.finishTrace("business", 2); - - // Start trace tasks with the same name in serial mode. - hiTraceMeter.startTrace("business", 1); - // Keep the service process running. - console.log(`business running`); - hiTraceMeter.finishTrace("business", 1); // End the first trace task. - // Keep the service process running. - console.log(`business running`); - hiTraceMeter.startTrace("business", 1); // Start the second trace task with the same name in serial mode. - // Keep the service process running. - console.log(`business running`); - - let traceCount = 3; - hiTraceMeter.traceByValue("myTestCount", traceCount); - traceCount = 4; - hiTraceMeter.traceByValue("myTestCount", traceCount); - hiTraceMeter.finishTrace("business", 1); - } - } - ``` - -2. Create an ArkTs application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. For example, if the name of the trace task is **HITRACE\_TAG\_APP**, the sample code is as follows: - +1. Create an ArkTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. For example, if the name of the trace task is **HITRACE\_TAG\_APP**, the sample code is as follows: + ```ts import hitrace from '@ohos.hiTraceMeter'; - + @Entry @Component struct Index { @State message: string = 'Hello World'; - + build() { Row() { Column() { @@ -97,7 +53,7 @@ In this example, distributed call chain tracing begins when the application star .fontWeight(FontWeight.Bold) .onClick(() => { this.message = 'Hello ArkUI'; - + // Start trace tasks with the same name concurrently. hitrace.startTrace("HITRACE_TAG_APP", 1001); // Keep the service process running. @@ -107,7 +63,7 @@ In this example, distributed call chain tracing begins when the application star hitrace.startTrace("HITRACE_TAG_APP", 1002); // Keep the service process running. console.log(`HITRACE_TAG_APP running`); - + hitrace.finishTrace("HITRACE_TAG_APP", 1001); hitrace.finishTrace("HITRACE_TAG_APP", 1002); @@ -143,7 +99,7 @@ In this example, distributed call chain tracing begins when the application star ``` 3. Click the run button on the application page. Then, run the following commands in sequence in shell: - + ```shell hdc shell hitrace --trace_begin app diff --git a/en/application-dev/dfx/hitracemeter-native-guidelines.md b/en/application-dev/dfx/hitracemeter-native-guidelines.md index bb0274f7c4077b016061430250e7a949cf826864..912ec1c5f87b6ebfdd6f14cb4da568e251501af2 100644 --- a/en/application-dev/dfx/hitracemeter-native-guidelines.md +++ b/en/application-dev/dfx/hitracemeter-native-guidelines.md @@ -1,6 +1,6 @@ # Development of Performance Tracing (Native) -## Introduction +## Overview hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance. > **NOTE** diff --git a/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md b/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md index 56c1f44dfd74cec442e94b6116a0bab8965cbc66..cc07a581e4fb9a271b566928e8a5c991185c42c8 100644 --- a/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md +++ b/en/application-dev/faqs/faqs-arkui-animation-interactive-event.md @@ -36,10 +36,11 @@ You can use [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) -**Solution** +**Solution** -- Add **focusable\(true\)** to the list item to enable it to obtain focus. + Use either of the following: +- Add **focusable\(true\)** to the list item to enable it to obtain focus. - Nest a focusable component, for example, **\