diff --git a/README_zh.md b/README_zh.md index ebf1bc8d7557d35f99eaacf8fd1427972d61d3b0..386fa1d7449553f92f399839d947a0dacd4e18b8 100644 --- a/README_zh.md +++ b/README_zh.md @@ -18,15 +18,15 @@ - master:最新开发版本。 - - OpenHarmony 3.2 Beta2版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-beta2.md)了解版本详情。 + - OpenHarmony 3.2 Beta3版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-beta3.md)了解版本详情。 - OpenHarmony 3.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.1-release.md)了解版本详情。 - 该已更新至OpenHarmony 3.1.1 Release,点击[此处](zh-cn/release-notes/OpenHarmony-v3.1.1-release.md)了解版本详情。 + 该版本已更新至OpenHarmony 3.1.3 Release,点击[此处](zh-cn/release-notes/OpenHarmony-v3.1.3-release.md)了解版本详情。 - OpenHarmony 3.0 LTS版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.0-LTS.md)了解版本详情。 - 该版本已更新至OpenHarmony 3.0.5 LTS,点击[此处](zh-cn/release-notes/OpenHarmony-v3.0.5-LTS.md)了解版本详情。 + 该版本已更新至OpenHarmony 3.0.6 LTS,点击[此处](zh-cn/release-notes/OpenHarmony-v3.0.6-LTS.md)了解版本详情。 - OpenHarmony 2.2 Beta2版本:点击[此处](zh-cn/release-notes/OpenHarmony-v2.2-beta2.md)了解版本详情。 @@ -34,7 +34,7 @@ ### 历史稳定版本 -OpenHarmony_v1.x_release:OpenHarmony 1.1.4 LTS稳定版本,点击[此处](zh-cn/release-notes/OpenHarmony-v1-1-4-LTS.md)了解版本详情。 +OpenHarmony_v1.x_release:OpenHarmony 1.1.5 LTS稳定版本,点击[此处](zh-cn/release-notes/OpenHarmony-v1.1.5-LTS.md)了解版本详情。 如需了解更多版本详情,点击[此处](zh-cn/release-notes/)。 diff --git a/en/application-dev/reference/arkui-ts/ts-appendix-enums.md b/en/application-dev/reference/arkui-ts/ts-appendix-enums.md index f1bce5a8cc619c0e72e1bff539b311d355c23755..d7b27a661400b2557de5cf6c710f26b0d00e05a5 100644 --- a/en/application-dev/reference/arkui-ts/ts-appendix-enums.md +++ b/en/application-dev/reference/arkui-ts/ts-appendix-enums.md @@ -137,9 +137,9 @@ | Name | Description | | -------- | ---------------------- | | Top | Top edge in the vertical direction. | -| Center(deprecated) | Center position in the vertical direction.
This API is deprecated since API version 9. | +| Center(deprecated) | Center position in the vertical direction.
This API is deprecated since API version 9. | | Bottom | Bottom edge in the vertical direction. | -| Baseline(deprecated) | Text baseline position in the cross axis direction.
This API is deprecated since API version 9.| +| Baseline(deprecated) | Text baseline position in the cross axis direction.
This API is deprecated since API version 9. | | Start | Start position in the horizontal direction. | | Middle(deprecated) | Center position in the horizontal direction.
This API is deprecated since API version 9. | | End | End position in the horizontal direction. | @@ -249,7 +249,7 @@ | End | The child components are aligned with the end edge of the main axis. The last component is aligned with the main-end, and other components are aligned with the next one.| | SpaceBetween | The child components are evenly distributed along the main axis. The space between any two adjacent components is the same. The first component is aligned with the main-start, the last component is aligned with the main-end, and the remaining components are distributed so that the space between any two adjacent components is the same.| | SpaceAround | The child components are evenly distributed along the main axis. The space between any two adjacent components is the same. The space between the first component and main-start, and that between the last component and cross-main are both half the size of the space between two adjacent components.| -| SpaceEvenly | The child components are equally distributed along the main axis. The space between the first component and main-start, the space between the last component and main-end, and the space between two adjacent components are the same.| +| SpaceEvenly | The child components are evenly distributed along the main axis. The space between the first component and main-start, the space between the last component and main-end, and the space between any two adjacent components are the same. | ## ItemAlign @@ -355,9 +355,9 @@ | Name | Description | | -------- | -------------------------------------- | -| Clip | Extra-long text is truncated. | +| Clip | Extra-long text is clipped. | | Ellipsis | An ellipsis (...) is used to represent clipped text.| -| None | No truncation or ellipsis is used for extra-long text. | +| None | No clipping or ellipsis is used for extra-long text. | ## TextDecorationType @@ -413,9 +413,9 @@ | Name | Description | | ----------- | -------------------- | -| None | Copy and paste is not allowed. | -| InApp | Intra-application copy and paste is allowed.| -| LocalDevice | Intra-device copy and paste is allowed.| +| None | Copy is not allowed. | +| InApp | Intra-application copy is allowed.| +| LocalDevice | Intra-device copy is allowed.| ## HitTestMode9+ diff --git a/en/contribute/introducing-third-party-open-source-software.md b/en/contribute/introducing-third-party-open-source-software.md index a0b35543246aff22d2d6ad693f1553add5932457..9d035a952d283b41604c492639eb2f0f52c37a88 100644 --- a/en/contribute/introducing-third-party-open-source-software.md +++ b/en/contribute/introducing-third-party-open-source-software.md @@ -12,7 +12,7 @@ This guide applies to all third-party open-source software to be introduced to t ## Improvements and Revisions 1. This document is drafted and maintained by the OpenHarmony SIG QA. What you are reading now is the latest version of this document. - + 2. Any addition, modification, or deletion of the principles mentioned in this document can be traced in the tracing system. 3. The PMC reviews and finalizes the principles after thorough discussion in the community. @@ -40,6 +40,22 @@ For easier maintenance and evolution, comply with the following principles when 12. When software introduction depends on other dependency software, it is not allowed to nest the dependency software in the subdirectory of the software introduction, and all dependency softwares must be placed in separate repository, and name it in the format of **third_party_*****softwareName***, because nested placement of dependency software may lead to multiple versions of the same software, old versions of security vulnerabilities cannot be fixed in a timely, and will risk the opensource compliance issues. - Dependency software are named in the compiled BUILD.gn with part name by prefixing the newly software introduction name, e.g. part_name = "software_introduction_name_dependency software_name". - The inter-component dependencies between software introduction and dependency software are resolved via external_deps. +13. OpenHarmony's archiving directory requirements for third-party software introduction. + - If you don't have a really good reason to store it elsewhere and under one of the permitted licenses belongs in third_party. + - For the dedicated third-party software introduction which belongs to the specail devboard, and is is not suitable introduced into the OpenHarmony platform, you could apply to store it in the following locations, Naming it in the format of **softwareName**, where **softwareName** must be an official name, and create README.OpenSource description file in the corresponding directory; Creating BUILD.gn to build it independently to support the automatic collection of open source obligation declaration. + + ``` + device/soc/$(SOC_COMPANY)/third_party + device/board/$(BOARD_COMPANY)/third_party + vendor/$(PRODUCT_COMPANY)/third_party + ``` + +14. Precompiled binary or toolchain used in the OpenHarmony, the following information needs to be provided. + - The source code corresponding to the pre-compiled binary or toolchain, which needs to store the corresponding source code in the OpenHarmony community, and provide the corresponding build guide, and provide open source obligation statement guide; + - Third-party software introduction for precompiled binary or toolchain, need to meet the principles 1 ~ 13; + - The [prebuilt toolchain's description documentation](./prebuilts-readme-template.md): including source code acquisition address, build instructions, update methods, archived in the toolchain root directory with the toolchain build; + - The root directory corresponding to the pre-compiled binary or toolchain needs to provide notice file of the full open source obligation statement; + - If the precompiled binary files come from upstream service platform (e.g. npm packages, etc.). We need to provide the following information in the place where the binary is archived, first we need to provide a general description with the name **README**, include the following information: background description of the introduction and official website; next we need to provide a opensource obligation statement file with the name **NOTICE**, include the following information: software name, version, copyrights, and license information of every third-party open-source software. ### Software Introduction Process @@ -64,10 +80,10 @@ Follow the process described in the [SIG Management Regulations](https://gitee.c | Check Item| Description| Self-Check Result Example| | :----- | :----- | :----- | | Software name| Provide the official name of the software and the repository name to which the software is introduced. The repository name is in the format of **third_party**_**softwareName**.| third_party_**softwareName**| -| Official website| Provide the official website link of the software.| https://softwaresite | +| Official website| Provide the official website link of the software.| | | Software version| Provide the version number of the software to be introduced. The version number must be an official version number released by the community. Do not modify the version number or introduce a version that is not officially released.| 1.0.0 | | Software version release date| Provide the official release date of the software version.| 2021.01.01 | -| Software version address| Provide the official download URL of the version. Note that the URL must be able to locate the release package of the specific version.| https://gitee.com/softwarecodesite/v1.0.0.zip | +| Software version address| Provide the official download URL of the version. Note that the URL must be able to locate the release package of the specific version.| | | Software license| Provide the official license name of the version and the relative path of the license file. If there are multiple licenses, list them all and describe their relationship, for example, And, Or, or different licenses for different directories.| Apache-2.0 | | Software lifecycle| Describe whether the software has an LTS version, how frequent a version is released, code submitted to the community in the last year, issue resolution status, and whether end of maintenance or evolution is notified.| No LTS version; one version released every six months; 10 code submissions in the last six months| | Security vulnerabilities| List disclosed security vulnerabilities in the software, including the vulnerability number, severity, link, and whether patches or solutions are available.| No disclosed vulnerabilities.| @@ -121,9 +137,9 @@ Confirm the issues found by the OAT tool and configure the **OAT.xml** file. For ] ``` -#### PMC Review +#### Open source software introduction Review -Refer to the [SIG Management Regulations](https://gitee.com/openharmony/community/tree/master/sig). The PMC will arrange the SIG request review and repository construction based on the received PR. +Refer to the [SIG-Architecture](https://gitee.com/openharmony/community/blob/master/sig/sig-architecture/sig-architecture_cn.md). The SIG-Architecture will arrange the review of the applying of creating new repository. ### License Requirements for Third-Party Open-Source Software @@ -131,66 +147,66 @@ Refer to the [SIG Management Regulations](https://gitee.com/openharmony/communit 2. The software license must be compatible with the license for the code repository. 3. The following licenses for third-party open-source software are recommended in the OpenHarmony project: -* Apache License 2.0 -* Mulan Permissive Software License, Version 2 -* BSD 2-clause -* BSD 3-clause -* DOM4J License -* PostgreSQL License -* Eclipse Distribution License 1.0 -* MIT -* ISC -* ICU -* University of Illinois/NCSA -* W3C Software License -* zlib/libpng -* Academic Free License 3.0 -* Python Software Foundation License -* Python Imaging Library Software License -* Boost Software License Version 1.0 -* WTF Public License -* UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE -* Zope Public License 2.0 +- Apache License 2.0 +- Mulan Permissive Software License, Version 2 +- BSD 2-clause +- BSD 3-clause +- DOM4J License +- PostgreSQL License +- Eclipse Distribution License 1.0 +- MIT +- ISC +- ICU +- University of Illinois/NCSA +- W3C Software License +- zlib/libpng +- Academic Free License 3.0 +- Python Software Foundation License +- Python Imaging Library Software License +- Boost Software License Version 1.0 +- WTF Public License +- UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +- Zope Public License 2.0 4. The following licenses for third-party open-source software are not recommended in the OpenHarmony project: -* GNU GPL 1, 2, 3 -* GNU Affero GPL 3 -* GNU LGPL 2, 2.1, 3 -* QPL -* Sleepycat License -* Server Side Public License (SSPL) version 1 -* Code Project Open License (CPOL) -* BSD-4-Clause/BSD-4-Clause (University of California-Specific) -* Facebook BSD+Patents license -* NPL 1.0/NPL 1.1 -* The Solipsistic Eclipse Public License -* The "Don't Be A Dick" Public License -* JSON License -* Binary Code License (BCL) -* Intel Simplified Software License -* JSR-275 License -* Microsoft Limited Public License -* Amazon Software License (ASL) -* Java SDK for Satori RTM license -* Redis Source Available License (RSAL) -* Booz Allen Public License -* Creative Commons Non-Commercial -* Sun Community Source License 3.0 -* Common Development and Distribution Licenses: CDDL 1.0 and CDDL 1.1 -* Common Public License: CPL 1.0 -* Eclipse Public License: EPL 1.0 -* IBM Public License: IPL 1.0 -* Mozilla Public Licenses: MPL 1.0, MPL 1.1, and MPL 2.0 -* Sun Public License: SPL 1.0 -* Open Software License 3.0 -* Erlang Public License -* UnRAR License -* SIL Open Font License -* Ubuntu Font License Version 1.0 -* IPA Font License Agreement v1.0 -* Ruby License -* Eclipse Public License 2.0: EPL 2.0 +- GNU GPL 1, 2, 3 +- GNU Affero GPL 3 +- GNU LGPL 2, 2.1, 3 +- QPL +- Sleepycat License +- Server Side Public License (SSPL) version 1 +- Code Project Open License (CPOL) +- BSD-4-Clause/BSD-4-Clause (University of California-Specific) +- Facebook BSD+Patents license +- NPL 1.0/NPL 1.1 +- The Solipsistic Eclipse Public License +- The "Don't Be A Dick" Public License +- JSON License +- Binary Code License (BCL) +- Intel Simplified Software License +- JSR-275 License +- Microsoft Limited Public License +- Amazon Software License (ASL) +- Java SDK for Satori RTM license +- Redis Source Available License (RSAL) +- Booz Allen Public License +- Creative Commons Non-Commercial +- Sun Community Source License 3.0 +- Common Development and Distribution Licenses: CDDL 1.0 and CDDL 1.1 +- Common Public License: CPL 1.0 +- Eclipse Public License: EPL 1.0 +- IBM Public License: IPL 1.0 +- Mozilla Public Licenses: MPL 1.0, MPL 1.1, and MPL 2.0 +- Sun Public License: SPL 1.0 +- Open Software License 3.0 +- Erlang Public License +- UnRAR License +- SIL Open Font License +- Ubuntu Font License Version 1.0 +- IPA Font License Agreement v1.0 +- Ruby License +- Eclipse Public License 2.0: EPL 2.0 If you want to introduce the software that complies with the unrecommended licenses listed in **4** or other licenses that are not mentioned, send an email to oh-legal@openatom.io. diff --git a/en/contribute/prebuilts-readme-template.md b/en/contribute/prebuilts-readme-template.md new file mode 100644 index 0000000000000000000000000000000000000000..d106f08a850bc065e5be5d2c597058d82996fc22 --- /dev/null +++ b/en/contribute/prebuilts-readme-template.md @@ -0,0 +1,28 @@ +Prebuilts for Clang/LLVM-based tools used in OpenHarmony +==================================================== + +1. For the latest version of this doc, please make sure to visit: +[OpenHarmony Clang/LLVM-based Tools Readme Doc](https://gitee.com/openharmony/third_party_llvm-project/blob/master/llvm-build/README.md) + +2. Build Instructions +------------------ + +``` +# Get source code +repo init -u https://gitee.com/openharmony/manifest.git -b llvm_toolchain-dev +repo sync -c +repo forall -c 'git lfs pull' +cp -r toolchain/llvm-project/llvm-build toolchain + +# Build Clang/LLVM-based prebuilts tool +./toolchain/llvm-project/llvm-build/env_prepare.sh +python3 ./toolchain/llvm-build/build.py +``` + +3. Update Prebuilts +---------------- +From an OpenHarmony project run: + +``` +$ ./build/prebuilts_download.sh +``` diff --git a/zh-cn/application-dev/media/camera.md b/zh-cn/application-dev/media/camera.md index 60f0348ee1442aba10a477226a3effd969151c98..617c4107faa983dc2231c80578405be95cf93e1c 100644 --- a/zh-cn/application-dev/media/camera.md +++ b/zh-cn/application-dev/media/camera.md @@ -59,7 +59,8 @@ import image from '@ohos.multimedia.image' import media from '@ohos.multimedia.media' // 创建CameraManager对象 -let cameraManager = await camera.getCameraManager(null) +context: any = getContext(this) +let cameraManager = await camera.getCameraManager(this.context) if (!cameraManager) { console.error('Failed to get the CameraManager instance'); } @@ -78,14 +79,10 @@ for (let index = 0; index < cameraArray.length; index++) { } // 创建相机输入流 -let cameraInput -await cameraManager.createCameraInput(cameraArray[0].cameraId).then((input) => { - console.log('Promise returned with the CameraInput instance'); - cameraInput = input -}) +let cameraInput = await cameraManager.createCameraInput(cameraArray[0]) // 获取相机设备支持的输出流能力 -let cameraOutputCap = await camera.getSupportedOutputCapability(cameraInput); +let cameraOutputCap = await cameraManager.getSupportedOutputCapability(cameraArray[0]); if (!cameraOutputCap) { console.error("outputCapability outputCapability == null || undefined") } else { @@ -112,8 +109,8 @@ if (!metadataObjectTypesArray) { console.error("createOutput metadataObjectTypesArray == null || undefined") } -// 创建预览输出流 -let previewOutput = await camera.createPreviewOutput(previewProfilesArray[0], surfaceId) +// 创建预览输出流,其中参数 surfaceId 参考下面 XComponent 组件,预览流为XComponent组件提供的surface +let previewOutput = await cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId) if (!previewOutput) { console.error("Failed to create the PreviewOutput instance.") } @@ -123,7 +120,7 @@ let imageReceiver = await image.createImageReceiver(1920, 1080, 4, 8) // 获取照片显示SurfaceId let photoSurfaceId = await imageReceiver.getReceivingSurfaceId() // 创建拍照输出流 -let photoOutput = await this.camera.createPhotoOutput(photoProfilesArray[0], photoSurfaceId) +let photoOutput = await cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId) if (!photoOutput) { console.error('Failed to create the PhotoOutput instance.'); return; @@ -155,20 +152,21 @@ let videoConfig = { // 创建录像输出流 let videoRecorder -await media.createVideoRecorder().then((recorder) => { +media.createVideoRecorder().then((recorder) => { console.log('createVideoRecorder called') videoRecorder = recorder }) // 设置视频录制的参数 -await videoRecorder.prepare(videoConfig) +videoRecorder.prepare(videoConfig) //获取录像SurfaceId -await videoRecorder.getInputSurface().then((id) => { +let videoSurfaceId +videoRecorder.getInputSurface().then((id) => { console.log('getInputSurface called') videoSurfaceId = id }) // 创建VideoOutput对象 -let videoOutput = camera.createVideoOutput(videoProfilesArray[0], videoSurfaceId) +let videoOutput = await cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId) if (!videoOutput) { console.error('Failed to create the videoOutput instance.'); return; @@ -205,11 +203,11 @@ build() { ```typescript function getImageReceiverSurfaceId() { - var receiver = image.createImageReceiver(640, 480, 4, 8) + let receiver = image.createImageReceiver(640, 480, 4, 8) console.log(TAG + 'before ImageReceiver check') if (receiver !== undefined) { console.log('ImageReceiver is ok') - surfaceId1 = await receiver.getReceivingSurfaceId() + surfaceId1 = receiver.getReceivingSurfaceId() console.log('ImageReceived id: ' + JSON.stringify(surfaceId1)) } else { console.log('ImageReceiver is not ok') @@ -399,17 +397,17 @@ videoOutput.start(async (err) => { }); // 开始录像 -await videoRecorder.start().then(() => { +videoRecorder.start().then(() => { console.info('videoRecorder start success'); } // 停止录像 -await videoRecorder.stop().then(() => { +videoRecorder.stop().then(() => { console.info('stop success'); } // 停止录像输出流 -await videoOutput.stop((err) => { +videoOutput.stop((err) => { if (err) { console.error('Failed to stop the video output ${err.message}'); return; @@ -424,22 +422,22 @@ await videoOutput.stop((err) => { ```typescript // 停止当前会话 -await captureSession.stop() +captureSession.stop() // 释放相机输入流 -await cameraInput.release() +cameraInput.release() // 释放预览输出流 -await previewOutput.release() +previewOutput.release() // 释放拍照输出流 -await photoOutput.release() +photoOutput.release() // 释放录像输出流 -await videoOutput.release() +videoOutput.release() // 释放会话 -await captureSession.release() +captureSession.release() // 会话置空 captureSession = null diff --git a/zh-cn/application-dev/quick-start/arkts-state-mgmt-page-level.md b/zh-cn/application-dev/quick-start/arkts-state-mgmt-page-level.md index 959f924a34bbe7fd48ded0a20c3b38178b323035..a140452948660edabecc87e7b98706b91c51a268 100644 --- a/zh-cn/application-dev/quick-start/arkts-state-mgmt-page-level.md +++ b/zh-cn/application-dev/quick-start/arkts-state-mgmt-page-level.md @@ -1,6 +1,6 @@ # 页面级变量的状态管理 -@State、@Prop、@Link、@Provide、Consume、@ObjectLink、@Observed和@Watch用于管理页面级变量的状态。 +@State、@Prop、@Link、@Provide、@Consume、@ObjectLink、@Observed和@Watch用于管理页面级变量的状态。 请参考[状态变量多种数据类型声明的使用限制](./arkts-restrictions-and-extensions.md)了解@State、@Provide、 @Link和@Consume四种状态变量的约束条件。 diff --git a/zh-cn/application-dev/quick-start/package-structure.md b/zh-cn/application-dev/quick-start/package-structure.md index 462dc9120fb3f296677c5cac7d2390078f41fe67..c51e7a2855d52515c947406c6c1cbe0d178f938b 100755 --- a/zh-cn/application-dev/quick-start/package-structure.md +++ b/zh-cn/application-dev/quick-start/package-structure.md @@ -92,9 +92,6 @@ app对象包含应用全局配置信息,内部结构说明参见表2。 | vendor | 标识对应用开发厂商的描述。字符串长度不超过255字节。 | 字符串 | 可缺省,缺省值为空 | | version | 标识应用的版本信息。参考表3。 | 对象 | 否 | | apiVersion | 标识应用程序所依赖的OpenHarmony API版本。参考表4。 | 对象 | 可缺省,缺省值为空 | -| singleton | 标识应用是否开启单例模式,仅支持系统应用,三方应用配置不生效。如果配置为true,在多用户场景下,该应用仍然单实例运行,不会随用户切换而变动,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为false | -| removable | 标识应用是否可卸载,仅支持系统应用,三方应用配置不生效,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为true | -| userDataClearable | 标识是否允许应用清除用户数据,仅支持系统应用,三方应用配置不生效,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为true | 表3 version内部结构说明 diff --git a/zh-cn/application-dev/quick-start/stage-structure.md b/zh-cn/application-dev/quick-start/stage-structure.md index dbdb68f9ae500bd586ec8fc85f20159cf1bcf8b6..fe72991043a1e313e677f968c8240d6b96bec2fa 100755 --- a/zh-cn/application-dev/quick-start/stage-structure.md +++ b/zh-cn/application-dev/quick-start/stage-structure.md @@ -2,7 +2,7 @@ # 应用包结构配置文件的说明 -在开发FA模型下的应用程序时,需要在config.json文件中对应用的包结构进行申明;同样的,在开发stage模型下的应用程序时,需要在module.json5和app.json配置文件中对应用的包结构进行声明。 +在开发stage模型的应用程序时,需要在app.json5和module.json5配置文件中对应用的包结构进行声明。 ## 配置文件内部结构 @@ -12,18 +12,41 @@ | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | ---------- | -| app | 标识应用的全局配置信息。参考[app对象内部结构](#app对象内部结构)。 | 对象 | 否 | -| module | 标识HAP包的配置信息。该标签下的配置只对当前HAP包生效。参考[module对象内部结构](#module对象内部结构)。 | 对象 | 否 | +| app | 标识应用的全局配置信息。参考[app对象内部结构](#app对象内部结构)。 | 对象 | 不可缺省。 | +| module | 标识HAP包的配置信息。该标签下的配置只对当前HAP包生效。参考[module对象内部结构](#module对象内部结构)。 | 对象 | 不可缺省。 | ### app对象内部结构 -app.json示例: +该标签为整个应用的属性,影响应用中所有HAP及组件。该标签的内部结构参见表2。 + +表2 app对象的内部结构说明 + +| 属性名称 | 含义 | 数据类型 | 是否可缺省 | +| ------------------------------ | ------------------------------------------------------------ | -------- | ------------------------------------------- | +| bundleName | 该标签标识应用的包名,用于标识应用的唯一性。标签的值命名规则 :
1)字符串以字母、数字、下划线和符号”.”组成;
2)以字母开头;
3)最小长度7字节,最大长度127个字节。
推荐采用反域名形式命名(如 :com.example.xxx,建议第一级为域名后缀com,第二级为厂商/个人名,第三级为应用名,也可以多级)。 | 字符串 | 不可缺省。 | +| debug | 该标签标识应用是否可调试。该标签由IDE编译构建时产生。 | 布尔值 | 可缺省,缺省值为false。 | +| icon | 该标签标识应用的图标,标签值为图标资源文件的索引。 | 字符串 | 不可缺省。 | +| label | 该标签标识应用的名称,标签值为字符串资源的索引。 | 字符串 | 不可缺省。 | +| description | 该标签标识App的描述信息,标签值是是字符串类型或对描述内容的字符串资源索引。 | 字符串 | 可缺省,缺省值为空。 | +| vendor | 该标签是对应用开发厂商的描述。最大长度255字节。 | 字符串 | 可缺省,缺省值为空。 | +| versionCode | 该标签标识应用的版本号,该标签值为32位非负整数。此数字仅用于确定某个版本是否比另一个版本更新,数值越大表示版本越高。开发者可以将该值设置为任何正整数,但是必须确保应用的新版本都使用比旧版本更大的值。versionCode 值应小于2的31次方。 | 数值 | 不可缺省。 | +| versionName | 该标签标识版本号的文字描述,用于向用户展示。
该标签仅由数字和点构成,推荐采用“A.B.C.D”四段式的形式。四段式推荐的含义如下所示。
第一段 :主版本号/Major,范围0-99,重大修改的版本,如实现新的大功能或重大变化。
第二段 :次版本号/Minor,范围0-99,表示实现较突出的特点,如新功能添加和大问题修复。
第三段 :特性版本号/Feature,范围0-99,标识规划的新版本特性。
第四段 :修订版本号/Patch,范围0-999,表示维护版本,修复bug。 | 字符串 | 不可缺省。 | +| minCompatibleVersionCode | 该标签标识该app能够兼容的最低历史版本号,用于跨设备兼容性判断。 | 数值 | 可缺省。缺省值等于versionCode标签值。| +| minAPIVersion | 该标签标识应用运行需要的SDK的API最小版本。 | 数值 | 可缺省,缺省值为bundle-profile.json5中的compatibleSdkVersion。| +| targetAPIVersion | 该标签标识应用运行需要的API目标版本。 | 数值 | 可缺省,缺省值为bundle-profile.json5中的compileSdkVersion。| +| apiReleaseType | 该标签标识应用运行需要的API目标版本的类型,采用字符串类型表示。取值为“CanaryN”、“BetaN”或者“Release”,其中,N代表大于零的整数。
Canary :受限发布的版本。
Beta :公开发布的Beta版本。
Release :公开发布的正式版本。
该字段由IDE读取当前使用的SDK的stage来生成。 | 字符串 | 可缺省,由IDE生成并覆盖。 | +| distributedNotificationEnabled | 该标签标记该应用是否开启分布式通知。 | 布尔值 | 可缺省,缺省值为true。 | +| entityType | 该标签标记该应用的类别,具体有 :游戏类(game),影音类(media)、社交通信类(communication)、新闻类(news)、出行类(travel)、工具类(utility)、购物类(shopping)、教育类(education)、少儿类(kids)、商务类(business)、拍摄类(photography)。 | 字符串 | 可缺省,缺省值为"unspecified"。 | +| multiProjects | 标识当前工程是否支持多工程。 | 布尔值 | 可缺省,缺省值为false。 | +| 设备类型 | 该标签可以配置多个,表示具体设备上的特殊配置信息,具体的设备类型有:"tablet"、"tv"、"wearable"、"car"、"default",可包含的字段有:minAPIVersion、distributedNotificationEnabled。 | 对象 | 可缺省,缺省值使用app下面相关的字段。 | + +app.json示例 : ```json { "app": { - "bundleName": "com.application.music", - "vendor": "application", + "bundleName": "bundleName", + "vendor": "vendorName", "versionCode": 1, "versionName": "1.0", "minCompatibleVersionCode": 1, @@ -32,76 +55,73 @@ app.json示例: "apiReleaseType": "Release", "debug": false, "icon": "$media:app_icon", - "label": "$string:app_name", - "description": "$string:description_application", + "label": "$string:app_label", + "description": "$string:app_description", "distributedNotificationEnabled": true, "entityType": "game", "car": { - "apiCompatibleVersion": 8 + "minAPIVersion": 8 } } } ``` -该标签为整个应用的属性,影响应用中所有hap及组件。该标签的内部结构参见表2。 +### module对象内部结构 -表2 app对象的内部结构说明 +HAP包的配置信息,该标签下的配置只对当前HAP包生效。 -| 属性名称 | 含义 | 数据类型 | 是否可缺省 | -| ------------------------------ | ------------------------------------------------------------ | -------- | ------------------------------------------- | -| bundleName | 该标签标识应用的包名,用于标识应用的唯一性。该标签不可缺省。标签的值命名规则 :
1)字符串以字母、数字、下划线和符号”.”组成;
2)以字母开头;
3)最小长度7个字节,最大长度127个字节。
推荐采用反域名形式命名(如 :com.example.xxx,建议第一级为域名后缀com,第二级为厂商/个人名,第三级为应用名,也可以多级)。
其中,随系统源码编译的应用需命名为”com.ohos.xxx”形式, ohos标识OpenHarmony系统应用。 | 字符串 | 否 | -| debug | 该标签标识应用是否可调试。 | 布尔值 | 该标签可以缺省,缺省为false。 | -| icon | 该标签标识应用的图标,标签值为资源文件的索引。 | 字符串 | 该标签不可缺省。 | -| label | 该标签标识应用的的名称,标签值为资源文件的索引,以支持多语言。 | 字符串 | 该标签不可缺省。 | -| description | 该标签标识App的描述信息,标签值是是字符串类型或对描述内容的资源索引,以支持多语言。 | 字符串 | 该标签可缺省,缺省值为空。 | -| vendor | 该标签是对应用开发厂商的描述。该标签的值是字符串类型(最大255个字节)。 | 字符串 | 该标签可以缺省,缺省为空。 | -| versionCode | 该标签标识应用的版本号,该标签值为32位非负整数。此数字仅用于确定某个版本是否比另一个版本更新,数值越大表示版本越高。开发者可以将该值设置为任何正整数,但是必须确保应用的新版本都使用比旧版本更大的值。该标签不可缺省,versionCode 值应小于2的31方。 | 数值 | 该标签不可缺省 | -| versionName | 该标签标识版本号的文字描述,用于向用户展示。
该标签仅由数字和点构成,推荐采用“A.B.C.D”四段式的形式。四段式推荐的含义如下所示。
第一段 :主版本号/Major,范围0-99,重大修改的版本,如实现新的大功能或重大变化。
第二段 :次版本号/Minor,范围0-99,表示实现较突出的特点,如新功能添加和大问题修复。
第三段 :特性版本号/Feature,范围0-99,标识规划的新版本特性。
第四段 :修订版本号/Patch,范围0-999,表示维护版本,修复bug。 | 字符串 | 该标签不可缺省 | -| minCompatibleVersionCode | 该标签标识该app能够兼容的最低历史版本号,用于跨设备兼容性判断。 | 数值 | 该标签可缺省。缺省值等于versionCode标签值。| -| minAPIVersion | 该标签标识应用运行需要的API最小版本。 | 整形 | 该标签可缺省,缺省值为bundle-profile.json5中的compatibleSdkVersion。| -| targetAPIVersion | 该标签标识应用运行需要的API目标版本。 | 整形 | 该标签可缺省,缺省值为bundle-profile.json5中的compileSdkVersion。| -| apiReleaseType | 该标签标识应用运行需要的API目标版本的类型,采用字符串类型表示。取值为“CanaryN”、“BetaN”或者“Release”,其中,N代表大于零的整数。
Canary :受限发布的版本。
Beta :公开发布的Beta版本。
Release :公开发布的正式版本。 | 字符串 | 该标签可缺省,缺省为“Release”。 | -| distributedNotificationEnabled | 该标签标记该应用是否开启分布式通知。 | 布尔值 | 该标签可缺省,缺省值为true。 | -| entityType | 该标签标记该应用的类别,具体有 :游戏类(game),影音类(media)、社交通信类(communication)、新闻类(news)、出行类(travel)、工具类(utility)、购物类(shopping)、教育类(education)、少儿类(kids)、商务类(business)、拍摄类(photography)。 | 字符串 | 该标签可以缺省,缺省为unspecified。 | -| singleton | 标识该应用开启单例模式,仅支持系统应用配置,三方应用配置不生效。配置为true时,在多用户场景下,该应用仍然单实例运行,不会随用户切换而变动。采用布尔类型,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为false。 | -| removable | 标识应用是否可卸载,仅支持系统应用配置,三方应用配置不生效,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为true。 | -| keepAlive | 标识应用是否始终保持运行状态,仅支持系统应用配置,三方应用配置不生效。标签值为布尔类型,如果为true,应用将始终保持为运行状态,并且在系统启动的时候会被系统启动起来,应用进程退出后,系统也会重新启动该应用进程。 | 布尔值 | 可缺省,缺省值为false。 | -| userDataClearable | 标识是否允许应用清除用户数据,仅支持系统应用配置,三方应用配置不生效,该字段从API8开始支持。 | 布尔值 | 可缺省,缺省值为true。 | -| accessible | 标识应用的安装目录是否是可访问的,仅支持系统应用配置,三方应用配置不生效。配置为true表示安装目录可以被三方应用访问,false表示不能被三方应用访问。 | 布尔值 | 可缺省,缺省值为false。 | -| multiProjects | 标识当前工程是否支持多工程。 | 布尔值 | 可缺省,缺省值为false。 | -| 设备类型 | 该标签可以配置多个,表示具体设备上的特殊配置信息,具体的设备类型有:"tablet"、"tv"、"wearable"、"car",可能包含的字段有:minAPIVersion、distributedNotificationEnabled、keepAlive、removable。 | 对象 | 该标签可缺省,缺省值使用app下面相关的字段。 | +表3 module对象内部结构说明 + +| 属性名称 | 含义 | 数据类型 | 是否可缺省 | +| -------------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------------ | +| name | 该标签标识当前module的名字。module打包成HAP后,表示HAP的名称,标签值采用字符串表示(最大长度31字节),该名称在整个应用要唯一。 | 字符串 | 不可缺省。 | +| type | 该标签标识当前module的类型。类型有两种,分别是entry、feature。 | 字符串 | 不可缺省。 | +| srcEntrance | 该标签标识HAP所对应的入口js代码路径,标签值为字符串(最大长度127字节)。 | 字符串 | 可缺省,缺省值为空。 | +| description | 该标签标识HAP包的描述信息,标签值是是字符串类型或对描述内容的字符串资源索引。 | 字符串 | 可缺省,缺省值为空。 | +| process | 该标签标识HAP的进程名,标签值为字符串类型(最大长度31字节)。如果在HAP标签下配置了process,该应用的所有ability都运行在该进程中。该标签只支持系统应用配置。 | 字符串 | 可缺省,缺省值为app标签下的bundleName。 | +| mainElement | 该标签标识HAP的入口Ability名称或者Extension名称。只有配置为mainElement的Ability或者Extension才允许在服务中心露出。 | 字符串 | 创建OpenHarmony原子化服务时,不可缺省。OpenHarmony应用下,可缺省,缺省值为空。 | +| deviceTypes | 该标签标识HAP可以运行在哪类设备上,标签值采用字符串数组的表示,系统预定义的设备类型见表4。 | 字符串数组 | 不可缺省。 | +| deliveryWithInstall | 该标签标识当前HAP是否在用户主动安装的时候安装,true表示主动安装时安装,false表示主动安装时不安装。 | 布尔值 | 不可缺省。 | +| installationFree | 标识当前HAP是否支持免安装特性。所有Hap包都需要配置不可缺省。
true :表示支持免安装特性,且符合免安装约束。
false :表示不支持免安装特性。

当entry.hap该字段配置为true时,与该entry.hap相关的所有feature.hap该字段也需要配置为true。
当entry.hap该字段配置为false时,与该entry.hap相关的各feature.hap该字段可按业务需求配置true或false。 | 布尔值 | 不可缺省。 | +| virtualMachine | 该标签用于标识当前HAP运行的目标虚拟机类型,供云端分发使用,如应用市场和分发中心。
该标签值为字符串。如果目标虚拟机类型为方舟虚拟机,则其值为"ark + 版本号"。 该标签由IDE构建HAP的时候自动插入。 | 字符串 | 该标签由IDE构建HAP的时候自动插入。 | +| uiSyntax(deprecated) | syntax定义该JS Component的语法类型。
hml标识该JS Component使用hml/css/js进行开发;
ets标识该JS Component使用ets声明式语法进行开发。 | 字符串 | 可缺省,缺省值为hml,该字段从API9开始废弃。 | +| pages | 该标签是一个profile资源,用于列举JS Component中每个页面信息。可以配置window标签定义与显示窗口相关的配置。window参考[window对象内部结构](#window对象内部结构)。 | 字符串 | 在有ability的场景下,不可缺省。 | +| metadata | 该标签标识Hap的自定义元信息。参考[metadata对象内部结构](#metadata对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| abilities | 描述元能力的配置信息,该标签下的配置只对当前ability生效。参考[abilities对象内部结构](#abilities对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| extensionAbilities | 描述extensionAbilities的配置信息,该标签下的配置只对当前extensionAbility生效。参考[extensionAbilities对象内部结构](#extensionabilities对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| definePermissions | 标识HAP定义的权限,仅支持系统应用配置,三方应用配置不生效。参考[definePermissions对象内部结构](#definepermissions对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| requestPermissions | 该标签标识应用运行时需向系统申请的权限集合。参考[requestPermissions对象内部结构](#requestpermissions对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| testRunner | 该标签用于支持对测试框架的配置,参考[testRunner对象内部结构说明](#testrunner对象内部结构)。 | 对象 | 可缺省,缺省值为空。 | -### module对象内部结构 module.json5示例: ```json { "module": { - "name": "myHapName", - "type": "entry|feature|har", - "srcEntrance" : "./MyAbilityStage.js", + "name": "moduleName", + "type": "entry", + "srcEntrance" : "./abilityStage.js", "description" : "$string:description_application", "mainElement": "MainAbility", + "pages": "$profile:pages_config", "deviceTypes": [ "tablet", "tv", "wearable", - "car", - "router" + "car" ], "deliveryWithInstall": true, "installationFree": false, - "virtualMachine": "ark | default", "metadata": [ { - "name": "string", - "value": "string", + "name": "name1", + "value": "value1", "resource": "$profile:config_file1" }, { - "name": "string", - "value": "string", + "name": "name2", + "value": "value2", "resource": "$profile:config_file2" } ], @@ -111,7 +131,7 @@ module.json5示例: "srcEntrance" : "./login/MyMainAbility.ts", "description": "$string:description_main_ability", "icon": "$media:icon", - "label": "HiMusic", + "label": "$string:label", "visible": true, "skills": [ { @@ -121,7 +141,7 @@ module.json5示例: "entities": [ "entity.system.home" ], - "uris": [ ] + "uris": [] } ], "backgroundModes": [ @@ -143,7 +163,7 @@ module.json5示例: "srcEntrance" : "./login/sampleAbility.ts", "description": "$string:description_sample_ability", "icon": "$media:icon", - "label": "HiMusic", + "label": "$string:label", "visible": true, "startWindowIcon": "$media:icon", "startWindowBackground": "$color:red" @@ -151,7 +171,7 @@ module.json5示例: ], "requestPermissions": [ { - "name": "ohos.abilitydemo.permission.PROVIDER", + "name": "permissionName", "reason": "$string:reason", "usedScene": { "abilities": [ @@ -165,80 +185,76 @@ module.json5示例: } ``` -hap包的配置信息,该标签下的配置只对当前hap包生效。 +pages示例 : -表3 module对象内部结构 +1.在开发视图的resources/base/profile下面定义配置文件pages_config.json(文件名称可由开发者定义): -| 属性名称 | 含义 | 数据类型 | 是否可缺省 | -| -------------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------------ | -| name | 该标签标识当前module的名字,module打包成hap后,表示hap的名称,标签值采用字符串表示(最大长度31个字节),该名称在整个应用要唯一。 | 字符串 | 该标签不可缺省。 | -| type | 该标签标识当前hap的类型。类型有三种,分别是entry、feature和har。 | 字符串 | 该标签不可缺省。 | -| srcEntrance | 该标签标识hap所对应的入口js代码路径,标签值为字符串(最长为127字节)。 | 字符串 | 该标签可缺省。 | -| description | 该标签标识hap包的描述信息,标签值是是字符串类型或对描述内容的资源索引,以支持多语言。 | 字符串 | 该标签可缺省,缺省值为空。 | -| process | 该标签标识hap的进程名,标签值为字符串类型(最长为31个字节)。如果在hap标签下配置了process,该应用的所有ability都运行在该进程中。该标签只支持系统应用配置。 | 字符串 | 可缺省,缺省为app标签下的bundleName。 | -| mainElement | 该标签标识hap的入口ability名称或者extension名称。只有配置为mainElement的ability或者extension才允许在服务中心露出。创建OpenHarmony原子化服务时,该标签不可缺省。 | 字符串 | OpenHarmony应用下,该标签可缺省。 | -| deviceTypes | 该标签标识hap可以运行在哪类设备上,标签值采用字符串数组的表示,系统预定义的设备类型见表4。
与syscap不同的是,deviceTypes是以设备类型为粒度,而syscap是以设备能力(例如蓝牙、wifi)为粒度。 | 字符串数组 | 该标签不可缺省,可以为空值。 | -| deliveryWithInstall | 该标签标识当前hap是否在用户主动安装的时候安装,true表示主动安装时安装,false表示主动安装时不安装。 | 布尔值 | 该标签不可缺省。 | -| installationFree | 标识当前HAP是否支持免安装特性。所有Hap包都需要配置不可缺省。
true :表示支持免安装特性,且符合免安装约束。
false :表示不支持免安装特性。

当entry.hap该字段配置为true时,与该entry.hap相关的所有feature.hap该字段也需要配置为true。
当entry.hap该字段配置为false时,与该entry.hap相关的各feature.hap该字段可按业务需求配置true或false。 | 布尔值 | 该标签不可缺省。 | -| virtualMachine | 该标签用于标识当前hap运行的目标虚拟机类型,供云端分发使用,如应用市场和分发中心。
该标签值为字符串。如果目标虚拟机类型为方舟虚拟机,则其值为”ark”; 如果目标虚拟机类型不是方舟虚拟机,则其值为”default”。该标签由IDE构建hap的时候自动插入。解包工具解析时,如果hap包没有该标签,设置该标签值为”default”。 | 字符串 | 该标签可缺省,缺省值为“default”。 | -| uiSyntax(deprecated) | syntax定义该JS Component的语法类型。
hml标识该JS Component使用hml/css/js进行开发;
ets标识该JS Component使用ets声明式语法进行开发。 | 字符串 | 该标签可缺省,默认值为hml,该字段从API9开始废弃。 | -| pages | 该标签是一个profile资源,用于列举JS Component中每个页面信息。pages使用参考pages示例。 | 对象 | 在有ability的场景下,该标签不可缺省。 | -| metadata | 该标签标识Hap的自定义元信息,标签值为数组类型,该标签下的配置只对当前module、或者ability、或者extensionAbility生效。metadata参考[metadata对象内部结构](#metadata对象内部结构)。 | 数组 | 该标签可缺省,缺省值为空。 | -| abilities | 描述元能力的配置信息,标签值为数组类型,该标签下的配置只对当前ability生效。abilities参考[abilities对象内部结构](#abilities对象内部结构)。 | 对象 | 该标签可缺省,缺省值为空。 | -| extensionAbilities | 描述extensionAbilities的配置信息,标签值为数组类型,该标签下的配置只对当前extensionAbility生效。extensionAbilities参考[extensionAbility对象的内部结构说明](#extensionability对象的内部结构说明)。 | 对象 | 该标签可缺省,缺省值为空。 | -| definePermissions | 标识hap定义的权限,仅支持系统应用配置,三方应用配置不生效。该应用的调用者必须申请这些权限才能正常调用该应用。definePermissions参考[definePermissions对象内部结构](#definepermissions对象内部结构) | 对象 | 该标签可缺省,缺省值为空,表示调用者无需任何权限即可调用该应用。 | -| requestPermissions | 该标签标识应用运行时需向系统申请的权限集合,标签值为数组类型。requestPermissions参考[requestPermissions对象内部结构](#requestpermissions对象内部结构)。 | 对象 | 该标签可缺省,缺省值为空。 | -| testRunner | 此标签用于支持对测试框架的配置,参考[testRunner对象内部结构说明](#testrunner对象内部结构)说明。 | 对象 | 可缺省,缺省值为空 | - -表4 deviceTypes对象的系统预定义设备 - -| 中文 | 英文 | 枚举值 | 设备类型 | -| -------- | ----------- | -------- | -------------------------------------------------------- | -| 平板 | tablet | tablet | 平板,带屏音箱 | -| 智慧屏 | smart TV | tv | 智慧屏 | -| 智能手表 | smart watch | wearable | 智能手表,儿童手表,特指资源较丰富的的手表,具备电话功能 | -| 车机 | head unit | car | 车机 | -| 路由器 | router | router | 路由器 | +```json +{ + "src": [ + "pages/index/index", + "pages/second/second", + "pages/third/third", + "pages/four/four" + ], + "window": { + "designWidth": 720, + "autoDesignWidth": false + } +} +``` -deviceTypes示例 : +2.在module.json5的module标签下定义pages信息 : ```json { "module": { - "name": "myHapName", - "type": "har", - "deviceTypes" : [ - "wearable" - ] + "pages": "$profile:pages_config" } } ``` -pages示例 : +表4 deviceTypes对象的系统预定义设备 + +| 设备类型 | 枚举值 | 说明 | +| -------- | ----------- | -------- | +| 平板 | tablet | - | +| 智慧屏 | tv | - | +| 智能手表 | wearable | 系统能力较丰富的手表,具备电话功能。 | +| 车机 | car | - | +| 默认设备 | default | 能够使用全部系统能力的OpenHarmony设备。 | + +deviceTypes示例 : ```json { "module": { - "name": "myHapName", - "type": "har", "deviceTypes" : [ "wearable" - ], - "pages": "$profile:pages_config" + ] } } ``` -pages_config配置文件 +#### window对象内部结构 + +定义与显示窗口相关的配置。 + +表5 window对象内部结构说明 + +| 属性名称 | 含义 | 数据类型 | 是否可缺省 | +| -------- | ------------------------------------------------------------ | -------- | -------------------------- | +| designWidth | 定义页面设计基准宽度,根据实际设备宽度来缩放元素大小。 | 数值 | 可缺省,缺省值为750。 | +| autoDesignWidth | 定义页面设计基准宽度是否自动计算,当设置为true时,designWidth将被忽略,设计基准宽度由设备宽度与屏幕密度计算得出。 | 布尔值 | 可缺省,缺省值为false。 | + +window示例 : ```json { - "src": [ - "pages/index/index", - "pages/second/second", - "pages/third/third", - "pages/four/four" - ] + "window": { + "designWidth": 720, + "autoDesignWidth": false + } } ``` @@ -248,112 +264,32 @@ pages_config配置文件 描述的module、ability、extensionAbility配置信息,标签值为数组类型,该标签下的配置只对当前module、或者ability、或者extensionAbility生效。 -表5 metadata对象内部结构说明 +表6 metadata对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------------- | -| name | 该标签标识数据项的键名称,字符串类型(最大长度255字节)。 | 字符串 | 该标签可缺省,缺省值为空。 | -| value | 该标签标识数据项的值,标签值为字符串(最大长度255字节)。 | 字符串 | 可缺省,缺省为空。 | -| resource | 该标签标识定义用户自定义数据格式,标签值为标识该数据的资源的索引值。 | 字符串 | 可缺省,缺省为空。 | +| name | 该标签标识数据项的键名称,最大长度255字节。 | 字符串 | 可缺省,缺省值为空。 | +| value | 该标签标识数据项的值,最大长度255字节。 | 字符串 | 可缺省,缺省值为空。 | +| resource | 该标签标识定义用户自定义数据格式,标签值为标识该数据的资源的索引值。 | 字符串 | 可缺省,缺省值为空。 | -metadata示例 : +metadata示例 : ```json -{ +{ "module": { "metadata": [ { - "name": "string", - "value": "string", - "resource": "$profile:config_file" + "name": "name1", + "value": "value1", + "resource": "$profile:config_file1" }, { - "name": "string", - "value": "string", - "resource": "$profile:config_file" + "name": "name2", + "value": "value2", + "resource": "$profile:config_file2" } - ] - } -} -``` - -#### abilities对象内部结构 - -abilities描述ability的配置信息,标签值为数组类型。 - -表6 abilities对象内部结构说明 - -| 属性 | 含义 | 数据类型 | 是否可缺省 | -| --------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------------ | -| name | 该标签标识当前ability的逻辑名,该名称在整个应用要唯一,标签值采用字符串表示(最大长度127个字节)。 | 字符串 | 该标签不可缺省。 | -| srcEntrance | 该标签标识ability所对应的js代码路径,标签值为字符串(最长为127字节)。。 | 字符串 | 该标签不可缺省。 | -| launchType | 该标签标示ability的启动模式,标签值可选“standard”、“singleton”、“specified”。该标签缺省为"singleton"。standard表示普通多实例,specified表示指定实例,运行时由ability内部业务决定是否创建多实例,singleton表示单实例。 | 字符串 | 可缺省,该标签缺省为"singleton" | -| description | 该标签标识ability的描述,标签值是是字符串类型或对描述内容的资源索引,要求采用用资源索引方式,以支持多语言。 | 字符串 | 该标签可缺省,缺省值为空。 | -| icon | 该标签标识ability图标,标签值为资源文件的索引。该标签可缺省,缺省值为空。
如果ability被配置为MainElement,该标签必须配置。 | 字符串 | 该标签可缺省,缺省值为空。
如果ability被配置为MainElement,该标签必须配置。 | -| permissions | 该标签标识被其它应用的ability调用时需要申请的权限的集合,一个数组元素为一个权限名称。通常采用反向域名格式(最大255字节),取值为系统预定义的权限。 | 字符串数组 | 该标签可缺省,缺省值为空。 | -| metadata | 该标签标识ability的元信息。metadata参考[metadata对象内部结构](#metadata对象内部结构)。 | 数组 | 该标签可缺省,缺省值为空。 | -| visible | 该标签标识ability是否可以被其它应用调用,为布尔类型,true表示可以被其它应用调用, false表示不可以被其它应用调用。 | 布尔值 | 该标签可缺省,缺省值为false。 | -| continuable | 该标签标识ability是否可以迁移,为布尔类型,true表示可以被迁移, false表示不可以被迁移。 | 布尔值 | 该标签可缺省,缺省值为false。 | -| skills | 该标签标识ability能够接收的意图的特征集,为数组格式。
配置规则 : entry包可以配置多个具有入口能力的skills标签(配置了action.system.home和entity.system.home)的ability,其中第一个配置了skills标签的ability中的label和icon作为OpenHarmony服务或应用的label和icon。
OpenHarmony服务的Feature包不能配置具有入口能力的skills标签。
OpenHarmony应用的Feature包可以配置具有入口能力的skills标签。
skills内部结构参考[skills对象内部结构](#skills对象内部结构)。 | 数组 | 该标签可缺省,缺省值为空。 | -| backgroundModes | 该标签标识ability长时任务集合。指定用于满足特定类型的长时任务。
长时任务类型有如下 :
dataTransfer :通过网络/对端设备进行数据下载、备份、分享、传输等业务。
audioPlayback :音频输出业务。
audioRecording :音频输入业务。
location :定位、导航业务。
bluetoothInteraction :蓝牙扫描、连接、传输业务(穿戴)。
multiDeviceConnection :多设备互联业务。
wifiInteraction :Wifi扫描、连接、传输业务(克隆 多屏)。
voip :音视频电话,VOIP业务。
taskKeeping :计算业务。
| 字符串 | 可缺省,缺省为空。 | -| startWindowIcon | 标识该Ability启动页面图标资源文件的索引。取值示例:$media:icon。 | 字符串 | 不可缺省。| -| startWindowBackground | 标识该Ability启动页面背景颜色资源文件的索引。取值示例:$color:red。 | 字符串 | 不可缺省。| -| removeMissionAfterTerminate | 该标签标识ability销毁后是否从任务列表中移除任务。为布尔类型,true表示销毁后移除任务, false表示销毁后不移除任务。 | 布尔值 | 该标签可缺省,缺省值为false。| -| orientation | 标识该ability启动时的方向。该方向的取值范围包括:
unspecified: 未指定方向,由系统自动判断显示方向,
landscape:横屏,
portrait:竖屏,
landscape_inverted: 反向横屏,
portrait_inverted: 反向竖屏,
auto_rotation: 随传感器旋转,
auto_rotation_landscape: 传感器横屏旋转,包括了横屏和反向横屏,
auto_rotation_portrait: 传感器竖屏旋转,包括了竖屏和反向竖屏,
auto_rotation_restricted: 传感器开关打开,方向可随传感器旋转,
auto_rotation_landscape_restricted: 传感器开关打开,方向可随传感器旋转为横屏, 包括了横屏和反向横屏,
auto_rotation_portrait_restricted: 传感器开关打开,方向随可传感器旋转为竖屏, 包括了横屏和反向横屏,
locked: 传感器开关关闭,方向锁定。 | 字符串 | 该标签可缺省,缺省值为unspecified。| -|supportWindowMode|标识该ability所支持的窗口模式,包含:
fullscreen: 全屏模式,
split: 分屏模式,
floating: 悬浮窗模式。 |数组 | 该标签可缺省,缺省值为
["fullscreen", "split", "floating"]。| -|priority|标识ability的优先级,仅支持系统应用配置,三方应用配置不生效。隐式查询时,优先级越高,ability在返回列表越靠前。该标签取值为integer类型,取值范围0-10。数值越大,优先级越高。 |数值 | 该标签可缺省,缺省值为0。 | -|maxWindowRatio|标识该ability支持的最大的宽高比。| 数值 |该标签可缺省,缺省值为平台支持的最大的宽高比。| -|minWindowRatio|标识该ability支持的最小的宽高比。| 数值 |该标签可缺省,缺省值为平台支持的最小的宽高比。| -|maxWindowWidth|标识该ability支持的最大的窗口宽度,宽度单位为vp。| 数值 |该标签可缺省,缺省值为平台支持的最大的窗口宽度。| -|minWindowWidth|标识该ability支持的最小的窗口宽度, 宽度单位为vp。| 数值 |该标签可缺省,缺省值为平台支持的最小的窗口宽度。| -|maxWindowHeight|标识该ability支持的最大的窗口高度, 高度单位为vp。| 数值 |该标签可缺省,缺省值为平台支持的最大的窗口高度。| -|minWindowHeight|标识该ability支持的最小的窗口高度, 高度单位为vp。| 数值 |该标签可缺省,缺省值为平台支持的最小的窗口高度。| -| excludeFromMissions | 该标签标识ability是否在最近任务列表中显示,仅支持系统应用配置,三方应用配置不生效。为布尔类型,true表示不在任务列表中显示,false表示在任务列表中显示。 | 布尔值 | 该标签可缺省,缺省值为false。| - -abilities示例 - -```json -{ - "abilities": [{ - "name": "MainAbility", - "srcEntrance": "./ets/login/MyLoginAbility.ts", - "launchType":"standard", - "description": "$string:description_main_ability", - "icon": "$media:icon", - "label": "Login", - "permissions": [], - "metadata": [], - "visible": true, - "continuable": true, - "skills": [{ - "actions": ["action.system.home"], - "entities": ["entity.system.home"], - "uris": [] - }], - "backgroundModes": [ - "dataTransfer", - "audioPlayback", - "audioRecording", - "location", - "bluetoothInteraction", - "multiDeviceConnection", - "wifiInteraction", - "voip", - "taskKeeping" ], - "startWindowIcon": "$media:icon", - "startWindowBackground": "$color:red", - "removeMissionAfterTerminate": true, - "orientation": " ", - "supportWindowMode": ["fullscreen", "split", "floating"], - "maxWindowRatio": 3.5, - "minWindowRatio": 0.5, - "maxWindowWidth": 2560, - "minWindowWidth": 1400, - "maxWindowHeight": 300, - "minWindowHeight": 200, - "excludeFromMissions": false - }] + } } ``` @@ -361,231 +297,374 @@ abilities示例 该标签标识ability或者extension能够接收的意图的特征。 -表7 skills内部结构示例 +表7 skill对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | ---------- | -------------------- | | actions | 该标签标识能够接收的意图的action值的集合,取值通常为系统预定义的action值,也允许自定义。 | 字符串数组 | 可缺省,缺省值为空。 | | entities | 该标签标识能够接收Want的元能力的类别集合,取值通常为系统预定义的类别,也允许自定义。 | 字符串数组 | 可缺省,缺省值为空。 | -| uris | 该标签标识向 want过滤器添加数据规范集合。该规范可以是只有数据类型(mimeType 属性),可以是只有 URI,也可以是既有数据类型又有 URI。uris内部结构参考表8。 | 对象数组 | 可缺省,缺省值为空。 | +| uris | 该标签标识与意图中URI(Uniform Resource Identifier)相匹配的集合。uris内部结构参考表8。 | 对象数组 | 可缺省,缺省值为空。 | -表8 uris对象的内部结构说明 +表8 uris对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------- | -------- | -------------------- | -| scheme | 标识uri的scheme值。 | 字符串 | 不可缺省。 | -| host | 标识uri的host值。 | 字符串 | 可缺省,缺省值为空。 | -| port | 标识uri的port值。 | 字符串 | 可缺省,缺省值为空。 | -| path | 标识uri的path值。 | 字符串 | 可缺省,缺省值为空。 | -| type | 标识uri的type值。 | 字符串 | 可缺省,缺省值为空。 | +| scheme | 标识URI的协议名部分,常见的有http、https、file、ftp等。 | 字符串 | 当配置type时可缺省,缺省值为空。没有配置type时不可缺省。 | +| host | 标识URI的主机地址部分,常见的有域名的方式,如example.com,ip地址的方式,如192.0.0.1。该字段要在scheme存在时才有意义。 | 字符串 | 可缺省,缺省值为空。 | +| port | 标识URI的端口部分。如http默认端口为80,https默认端口是443,ftp默认端口是21。该字段要在scheme和host都存在时才有意义。| 字符串 | 可缺省,缺省值为空。 | +| path \| pathStartWith \| pathRegex | 标识URI的路径部分,path、pathStartWith和pathRegex配置时三选一。path标识URI与want中的路径部分全匹配,pathStartWith标识URI与want中的路径部分允许前缀匹配,pathRegex标识URI与want中的路径部分允许正则匹配。该字段要在scheme和host都存在时才有意义。| 字符串 | 可缺省,缺省值为空。 | +| type | 标识数据类型,使用MIME(Multipurpose Internet Mail Extensions)类型规范。可与scheme同时配置,也可以单独配置。| 字符串 | 可缺省,缺省值为空。 | -skills示例 +skills示例 : ```json { - "abilities": [ - { - "skills": [ - { - "actions": [ - "action.system.home" - ], - "entities": [ - "entity.system.home" - ], - "uris": [ - { - "scheme":"uri2", - "host":"host2", - "port":"port2", - "pathStartWith":"path2", - "pathRegex":"/query/.*", - "path":"path", - "type": "text/*" - } - ] - } - ] - } - ], - "extensionAbilities": [ - { - "skills": [ - { - "actions": [ - ], - "entities": [ - ], - "uris": [ - { - "scheme":"uri2", - "host":"host2", - "port":"port2", - "pathStartWith":"path2", - "pathRegex":"/query/.*", - "path":"path", - "type": "text/*" - } - ] - } - ] - } - ] + "module": { + "abilities": [ + { + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ], + "uris": [ + { + "scheme":"https", + "host":"www.example.com", + "port":"8080", + "path":"query/student/name", + "pathStartWith":"query/student", + "pathRegex":"query/.*/name", + "type": "text/*" + } + ] + } + ] + } + ], + "extensionAbilities": [ + { + "skills": [ + { + "actions": [ + "actionName" + ], + "entities": [ + "entityName" + ], + "uris": [ + { + "scheme":"https", + "host":"www.example.com", + "port":"8080", + "path":"query/student/name", + "pathStartWith":"query/student", + "pathRegex":"query/.*/name", + "type": "text/*" + } + ] + } + ] + } + ] + } +} +``` + +#### abilities对象内部结构 + +abilities描述Ability组件的配置信息,标签值为数组类型。 + +表9 ability对象内部结构说明 + +| 属性 | 含义 | 数据类型 | 是否可缺省 | +| --------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------------ | +| name | 该标签标识当前Ability组件的逻辑名,该名称在整个应用要唯一,标签值采用字符串表示(最大长度127字节)。 | 字符串 | 不可缺省。 | +| srcEntrance | 该标签标识Ability组件所对应的js代码路径,标签值为字符串(最大长度127字节)。 | 字符串 | 不可缺省。 | +| launchType | 该标签标识Ability组件的启动模式,可选标签值:
"standard":多实例,每次启动创建一个新的实例。
"singleton":单实例,仅第一次启动创建新实例。
"specified":运行时由开发者决定是否创建新实例。 | 字符串 | 可缺省,缺省值为"singleton" | +| description | 该标签标识Ability组件的描述信息,标签值是是字符串类型或对描述内容的资源索引,要求采用资源索引方式,以支持多语言。 | 字符串 | 可缺省,缺省值为空。 | +| icon | 该标签标识Ability组件的图标,标签值为图标资源文件的索引。 | 字符串 | 可缺省,缺省值为空。
如果Ability组件被配置为MainElement,该标签必须配置。 | +| permissions | 该标签标识被其它应用的Ability组件调用时需要申请的权限的集合,一个数组元素为一个权限名称。通常采用反向域名格式(最大长度255字节),取值为系统预定义的权限。 | 字符串数组 | 可缺省,缺省值为空。 | +| metadata | 该标签标识Ability组件的元信息。参考[metadata对象内部结构](#metadata对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| visible | 该标签标识Ability组件是否可以被其它应用调用,true表示可以被其它应用调用, false表示不可以被其它应用调用。 | 布尔值 | 可缺省,缺省值为false。 | +| continuable | 该标签标识Ability组件是否可以迁移,true表示可以被迁移, false表示不可以被迁移。 | 布尔值 | 可缺省,缺省值为false。 | +| skills | 该标签标识Ability组件能够接收的意图的特征集。
配置规则 : entry包可以配置多个具有入口能力的skills标签(配置了action.system.home和entity.system.home)的Ability组件,其中第一个配置了skills标签的Ability组件中的label和icon作为OpenHarmony服务或应用的label和icon。
OpenHarmony服务的Feature包不能配置具有入口能力的skills标签。
OpenHarmony应用的Feature包可以配置具有入口能力的skills标签。
参考[skills对象内部结构](#skills对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| backgroundModes | 该标签标识Ability组件的长时任务集合。指定用于满足特定类型的长时任务。
长时任务类型有如下 :
dataTransfer :通过网络/对端设备进行数据下载、备份、分享、传输等业务。
audioPlayback :音频输出业务。
audioRecording :音频输入业务。
location :定位、导航业务。
bluetoothInteraction :蓝牙扫描、连接、传输业务(穿戴)。
multiDeviceConnection :多设备互联业务。
wifiInteraction :Wifi扫描、连接、传输业务(克隆 多屏)。
voip :音视频电话,VOIP业务。
taskKeeping :计算业务。
| 字符串 | 可缺省,缺省值为空。 | +| startWindowIcon | 标识该Ability组件启动页面图标资源文件的索引。取值示例:$media:icon。 | 字符串 | 不可缺省。| +| startWindowBackground | 标识该Ability组件启动页面背景颜色资源文件的索引。取值示例:$color:red。 | 字符串 | 不可缺省。| +| removeMissionAfterTerminate | 该标签标识Ability组件销毁后是否从任务列表中移除任务。true表示销毁后移除任务, false表示销毁后不移除任务。 | 布尔值 | 可缺省,缺省值为false。| +| orientation | 标识该Ability组件启动时的方向。取值范围包括:
unspecified: 未指定方向,由系统自动判断显示方向,
landscape:横屏,
portrait:竖屏,
landscape_inverted: 反向横屏,
portrait_inverted: 反向竖屏,
auto_rotation: 随传感器旋转,
auto_rotation_landscape: 传感器横屏旋转,包括了横屏和反向横屏,
auto_rotation_portrait: 传感器竖屏旋转,包括了竖屏和反向竖屏,
auto_rotation_restricted: 传感器开关打开,方向可随传感器旋转,
auto_rotation_landscape_restricted: 传感器开关打开,方向可随传感器旋转为横屏, 包括了横屏和反向横屏,
auto_rotation_portrait_restricted: 传感器开关打开,方向随可传感器旋转为竖屏, 包括了横屏和反向横屏,
locked: 传感器开关关闭,方向锁定。 | 字符串 | 可缺省,缺省值为"unspecified"。| +|supportWindowMode|标识该Ability组件所支持的窗口模式,取值范围包括:
fullscreen: 全屏模式,
split: 分屏模式,
floating: 悬浮窗模式。 |字符串数组 | 可缺省,缺省值为
["fullscreen", "split", "floating"]。| +|maxWindowRatio|标识该Ability组件支持的最大的宽高比。| 数值 |可缺省,缺省值为平台支持的最大的宽高比。| +|minWindowRatio|标识该Ability组件支持的最小的宽高比。| 数值 |可缺省,缺省值为平台支持的最小的宽高比。| +|maxWindowWidth|标识该Ability组件支持的最大的窗口宽度,宽度单位为vp。| 数值 |可缺省,缺省值为平台支持的最大的窗口宽度。| +|minWindowWidth|标识该Ability组件支持的最小的窗口宽度, 宽度单位为vp。| 数值 |可缺省,缺省值为平台支持的最小的窗口宽度。| +|maxWindowHeight|标识该Ability组件支持的最大的窗口高度, 高度单位为vp。| 数值 |可缺省,缺省值为平台支持的最大的窗口高度。| +|minWindowHeight|标识该Ability组件支持的最小的窗口高度, 高度单位为vp。| 数值 |可缺省,缺省值为平台支持的最小的窗口高度。| + +abilities示例 : + +```json +{ + "module": { + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/login/LoginAbility.ts", + "launchType":"standard", + "description": "$string:description", + "icon": "$media:icon", + "label": "$string:label", + "permissions": [], + "metadata": [], + "visible": true, + "continuable": true, + "skills": [ + { + "actions": ["action.system.home"], + "entities": ["entity.system.home"], + "uris": [] + } + ], + "backgroundModes": [ + "dataTransfer", + "audioPlayback", + "audioRecording", + "location", + "bluetoothInteraction", + "multiDeviceConnection", + "wifiInteraction", + "voip", + "taskKeeping" + ], + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:red", + "removeMissionAfterTerminate": true, + "orientation": "landscape", + "supportWindowMode": ["fullscreen", "split", "floating"], + "maxWindowRatio": 3.5, + "minWindowRatio": 0.5, + "maxWindowWidth": 2560, + "minWindowWidth": 1400, + "maxWindowHeight": 300, + "minWindowHeight": 200 + } + ] + } } ``` -#### extensionAbility对象的内部结构说明 -描述extensionAbility的配置信息,标签值为数组类型,该标签下的配置只对当前extensionAbility生效。 +#### extensionAbilities对象内部结构 + +extensionAbilities描述extensionAbility的配置信息,标签值为数组类型。 -表9 extensionAbility对象内部结构说明 +表10 extensionAbility对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ----------- | ------------------------------------------------------------ | ---------- | ----------------------------- | -| name | 该标签标识当前extensionAbility的逻辑名,标签值采用字符串表示(最大长度127个字节),该名称在整个应用要唯一。 | 字符串 | 该标签不可缺省。 | -| srcEntrance | 该标签标识extensionAbility所对应的js代码路径,标签值为字符串(最长为127字节)。 | 字符串 | 该标签不可缺省。 | -| description | 该标签标识extensionAbility的描述,标签值是是字符串类型或对描述内容的资源索引,以支持多语言。 | 字符串 | 该标签可缺省,缺省值为空。 | -| icon | 该标签标识extensionAbility图标,标签值为资源文件的索引。如果extensionAbility被配置为MainElement,该标签必须配置。 | 字符串 | 该标签可缺省,缺省值为空。 | -| label | 该标签标识extensionAbility对用户显示的名称,标签值配置为该名称的资源索引以支持多语言。
如果extensionAbility被配置为MainElement,该标签必须配置,且应用内唯一。 | 字符串 | 该标签不可缺省。 | -| type | 该标签标识extensionAbility的类型,取值为form、workScheduler、inputMethod、service、accessibility、dataShare、fileShare、staticSubscriber、wallpaper、backup、window、enterpriseAdmin、thumbnail、preview其中之一。 | 字符串 | 该标签不可缺省。 | -| permissions | 该标签标识被其它应用的ability调用时需要申请的权限的集合,字符串数组类型,每个数组元素为一个权限名称,通常采用反向域名方式表示(最大255字节),可以是系统预定义的权限,也可以是该应用自定义的权限。如果是后者,需与defPermissions标签中定义的某个权限的name标签值一致。 | 字符串数组 | 该标签可缺省,缺省值为空。 | -| uri | 该标签标识ability提供的数据uri,为字符数组类型(最大长度255),用反向域名的格式表示。该标签在type为dataShare类型的extensionAbility时,不可缺省。 | 字符串 | 该标签可缺省,缺省值为空。 | -| skills | 该标签标识ability能够接收的意图的特征集,为数组格式。
配置规则 : entry包可以配置多个具有入口能力的skills标签(配置了action.system.home和entity.system.home)的ability,其中第一个配置了skills标签的ability中的label和icon作为OpenHarmony服务或应用的label和icon。
OpenHarmony服务的Feature包不能配置具有入口能力的skills标签。
OpenHarmony应用的Feature包可以配置具有入口能力的skills标签。
skills内部结构参考[skills对象内部结构](#skills对象内部结构)。 | 数组 | 该标签可缺省,缺省值为空。 | -| metadata | 该标签标识extensionAbility的元信息。metadata内部结构参考[metadata对象内部结构](#metadata对象内部结构)。 | 对象 | 该标签可缺省,缺省值为空。 | -| visible | 该标签标识extensionAbility是否可以被其它应用调用,为布尔类型。true表示可以被其它应用调用, false表示不可以被其它应用调用。 | 布尔值 | 该标签可缺省,缺省值为false。 | - -extensionAbility示例 : +| name | 该标签标识当前ExtensionAbility组件的逻辑名,标签值采用字符串表示(最大长度127字节),该名称在整个应用要唯一。 | 字符串 | 不可缺省。 | +| srcEntrance | 该标签标识ExtensionAbility组件所对应的js代码路径,标签值为字符串(最大长度127字节)。 | 字符串 | 不可缺省。 | +| description | 该标签标识ExtensionAbility组件的描述,标签值是是字符串类型或对描述内容的资源索引,以支持多语言。 | 字符串 | 可缺省,缺省值为空。 | +| icon | 该标签标识ExtensionAbility组件图标,标签值为资源文件的索引。 | 字符串 | 可缺省,缺省值为空。如果ExtensionAbility组件被配置为MainElement,不可缺省。 | +| label | 该标签标识ExtensionAbility组件对用户显示的名称,标签值配置为该名称的资源索引以支持多语言。 | 字符串 | 可缺省,缺省值为空。如果ExtensionAbility组件被配置为MainElement,该标签必须配置,且应用内唯一。 | +| type | 该标签标识ExtensionAbility组件的类型,取值为form、workScheduler、inputMethod、service、accessibility、dataShare、fileShare、staticSubscriber、wallpaper、backup、window、enterpriseAdmin、thumbnail、preview其中之一。 | 字符串 | 不可缺省。 | +| permissions | 该标签标识被其它应用的ability调用时需要申请的权限的集合,字符串数组类型,每个数组元素为一个权限名称,通常采用反向域名方式表示(最大长度255字节),取值为系统预定义权限或者应用自定义权限,如果是后者,需与defPermissions标签中定义的某个权限的name标签值一致。 | 字符串数组 | 可缺省,缺省值为空。 | +| uri | 该标签标识ability提供的数据URI,为字符数组类型(最大长度255字节),用反向域名的格式表示。 | 字符串 | 可缺省,缺省值为空。该标签在type为dataShare类型的ExtensionAbility组件时,不可缺省。 | +| skills | 该标签标识ability能够接收的意图的特征集,为数组格式。
配置规则 : entry包可以配置多个具有入口能力的skills标签(配置了action.system.home和entity.system.home)的ability,其中第一个配置了skills标签的ability中的label和icon作为OpenHarmony服务或应用的label和icon。
OpenHarmony服务的Feature包不能配置具有入口能力的skills标签。
OpenHarmony应用的Feature包可以配置具有入口能力的skills标签。
参考[skills对象内部结构](#skills对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| metadata | 该标签标识ExtensionAbility组件的元信息。参考[metadata对象内部结构](#metadata对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| visible | 该标签标识ExtensionAbility组件是否可以被其它应用调用。true表示可以被其它应用调用, false表示不可以被其它应用调用。 | 布尔值 | 可缺省,缺省值为false。 | +| readPermission | 该标签标识读取ExtensionAbility组件的数据所需的权限。最大长度255字节。type为dataShare类型的ExtensionAbility组件支持该配置。该标签只对系统应用生效。 | 字符串 | 可缺省,缺省值为空。 | +| writePermission | 该标签标识向ExtensionAbility组件写数据所需的权限。最大长度255字节。type为dataShare类型的ExtensionAbility组件支持该配置。该标签只对系统应用生效。 | 字符串 | 可缺省,缺省值为空。 | + +extensionAbilities示例 : ```json { - "extensionAbilities": [ - { - "name": "FormName", - "srcEntrance": "./form/MyForm.ts", - "icon": "$media:icon", - "label" : "$string:extension_name", - "description": "$string:form_description", - "type": "form", - "permissions": ["ohos.abilitydemo.permission.PROVIDER"], - "readPermission": "", - "writePermission": "", - "visible": true, - "uri":"scheme://authority/path/query" - "skills": [{ - "actions": [], - "entities": [], - "uris": [] - }], - "metadata": [ - { - "name": "ohos.extability.form", - "resource": "$profile:form_config", - } - ] - } - ] + "module": { + "extensionAbilities": [ + { + "name": "extensionName", + "srcEntrance": "./extension/FormExtension.ts", + "icon": "$media:icon", + "label" : "$string:label", + "description": "$string:description", + "type": "form", + "permissions": ["permissionName"], + "readPermission": "", + "writePermission": "", + "visible": true, + "uri":"scheme://authority/path/query" + "skills": [ + { + "actions": [], + "entities": [], + "uris": [] + } + ], + "metadata": [ + { + "name": "ohos.extability.form", + "resource": "$profile:form_config", + } + ] + } + ] + } } ``` #### definePermissions对象内部结构 -该标签标识hap定义的权限。 +该标签标识HAP定义的权限。该标签只支持系统应用配置。 -表10 definePermissions定义权限字段说明 +表11 definePermission对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ---------------------- | ------------------------------------------------------------ | -------- | ------------------------------ | -| name | 标识权限的名称。 | 字符串 | 不可缺省 | -| grantMode | 标识权限的授予方式,授予模式如下:
system_grant:安装后系统自动授予该权限。
user_grant:使用动态申请,用户授权后才可使用 | 字符串 | 可缺省,缺省值为system_grant。 | -| availableLevel | 标识权限限制门限,可选值为"system_core"、"system_basic"、"normal"。该标签有缺省值,缺省值为normal。权限范围如下:
system_core:系统核心权限。
system_basic:系统基础权限。
normal:普通权限。所有应用允许申请的权限。 | 字符串 | 可缺省,缺省值为"normal" | -| provisionEnable | 标识权限是否支持证书方式申请权限,包括高级别的权限,true标识需要开发者可以通过provision证书acls方式申请权限。 | 布尔值 | 可缺省,缺省值为true | -| distributedSceneEnable | 标识权限是否支持分布式场景下使用该权限。 | 布尔值 | 可缺省,缺省值为false | -| label | 标识权限的简短描述,配置为对描述内容的资源索引。 | 字符串 | 可缺省,缺省值为空 | -| description | 标识权限的详细描述,可以是表示描述内容的字符串,也可以是对描述内容的资源索引。 | 字符串 | 可缺省,缺省值为空 | +| name | 标识权限的名称。 | 字符串 | 不可缺省。 | +| grantMode | 标识权限的授予方式,授予模式如下:
system_grant:安装后系统自动授予该权限。
user_grant:应用动态申请,用户授权后才可使用 | 字符串 | 可缺省,缺省值为"system_grant"。 | +| availableLevel | 标识权限限制门限,可选值为system_core、system_basic、normal。
system_core:系统核心权限。
system_basic:系统基础权限。
normal:普通权限。所有应用允许申请的权限。 | 字符串 | 可缺省,缺省值为"normal"。 | +| provisionEnable | 标识权限是否支持证书方式申请权限,包括高级别的权限,true标识需要开发者可以通过provision证书acls方式申请权限。 | 布尔值 | 可缺省,缺省值为true。 | +| distributedSceneEnable | 标识权限是否支持分布式场景下使用该权限。 | 布尔值 | 可缺省,缺省值为false。 | +| label | 标识权限的简短描述,配置为对描述内容的资源索引。 | 字符串 | 可缺省,缺省值为空。 | +| description | 标识权限的详细描述,可以是表示描述内容的字符串,也可以是对描述内容的资源索引。 | 字符串 | 可缺省,缺省值为空。 | + +definePermissions示例 : + +```json +{ + "module": { + "definePermissions": [ + { + "name": "permissionName", + "grantMode": "user_grant", + "availableLevel": "system_basic", + "provisionEnable": false, + "distributedSceneEnable": true, + "label" : "$string:label", + "description": "$string:description" + } + ] + } +} + +``` #### requestPermissions对象内部结构 该标签标识应用运行时需向系统申请的权限集合。 -表11 requestPermissions权限申请字段说明 +表12 requestPermission对象内部结构说明 -| 属性名称 | 含义 | **类型** | **取值范围** | **默认值** | **规则约束** | -| --------- | ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------------------------------ | -------------------- | ------------------------------------------------------------ | -| name | 必须,填写需要使用的权限名称。 | 字符串 | 自定义 | 无 | 未填写时,解析失败。 | -| reason | 可选,当申请的权限为user_grant权限时此字段必填。描述申请权限的原因。 | 字符串 | 使用string类资源引用。格式为`$string: ***`。 | 空 | user_grant权限必填,否则不允许在应用市场上架。需做多语种适配。 | -| usedScene | 可选,当申请的权限为user_grant权限时此字段必填。描述权限使用的场景和时机。场景类型有 :ability、when(调用时机)。可配置多个ability。 | abilities:ability字符串数组,when:字符串 | abilities:ability的名称,when:inuse(使用时)、always(始终) | abilities:空 when:空 | user_grant权限必填abilities,可选填when。 | +| 属性名称 | 含义 | 数据类型 | 是否可缺省 | +| ------| ------| -------- | ------------------------------ | +| name | 需要申请的权限名称。| 字符串 | 不可缺省。 | +| reason | 申请权限的原因。配置为描述内容的资源索引,以支持多语言。 | 字符串 | 可缺省,缺省值为空。当申请权限的grantMode为user_grant时不可缺省。 | +| usedScene | 权限使用的场景和时机。参考[usedScene对象内部结构](#usedscene对象内部结构)。| 对象 | 可缺省,缺省值为空。当申请权限的grantMode为user_grant时不可缺省。 | -requestPermissions示例 : +requestPermissions示例 : ```json { - "name": "ohos.abilitydemo.permission.PROVIDER", - "reason": "$string:reason", - "usedScene": { - "abilities": [ - "AudioAbility", - "VideoAbility", - ], - "when": "inuse" - } + "module": { + "requestPermissions": [ + { + "name": "permissionName", + "reason": "$string:reason", + "usedScene": { + "abilities": [ + "AudioAbility", + "VideoAbility" + ], + "when": "inuse" + } + } + ] + } } ``` + 权限访问的更多说明,可参考[访问控制开发指导](../security/accesstoken-guidelines.md) -#### form对象内部结构 +#### usedScene对象内部结构 + +该标签标识权限使用的场景和时机。 + +表13 usedScene对象内部结构说明 + +| 属性名称 | 含义 | 数据类型 | 是否可缺省 | +| ------- | --------------------| -------- | ------ | +| abilities | 标识需要使用到该权限的ability。| 字符串数组 | 不可缺省。 | +| when | 标识使用该权限的时机,可选值为inuse和always。inuse表示仅前台使用,always表示前后台都可使用 | 字符串 | 可缺省,缺省值为空。 | -forms标签标识卡片的配置,form卡片是可以嵌入桌面上并接收定期更新的应用简要视图。在以下场景中可以包含form标签。 -1. extensions中指定type为form。 +usedScene示例 : + +```json +{ + "module": { + "requestPermissions": [ + { + "usedScene": { + "abilities": [ + "AudioAbility", + "VideoAbility" + ], + "when": "inuse" + } + } + ] + } +} +``` + +#### forms对象内部结构 -2. metadata中指定form信息,其中 : - name :指定form的名称。使用ohos.extability.form作为form信息的标识。 - resource :指定form信息的资源位置。 +forms标签标识卡片的配置,form卡片是可以嵌入桌面上并接收定期更新的应用简要视图。
+配置方式如下:
+extensionAbility标签配置type为form,并配置metadata信息:name :"ohos.extability.form"。resource :指定form信息的资源位置。 -表12 forms对象的内部结构说明 +表14 form对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ------------------- | ------------------------------------------------------------ | ---------- | ----------------------------- | -| name | 标识卡片的类名。字符串最大长度为127字节。 | 字符串 | 否 | -| description | 标识卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。 | 字符串 | 可缺省,缺省为空。 | -| src | 该标签标识JS卡片对应的UI代码。建议开发者通过自适应布局显示不同规格卡片,如果不同规格卡片布局相差较大,建议通过不同卡片来区分。 | 字符串 | 可缺省,缺省为空。 | -| window | 该标签标识JS卡片的自适应能力。window结构参考表12。 | 对象 | 可缺省,缺省为空。 | -| isDefault | 标识该卡片是否为默认卡片,每个Ability有且只有一个默认卡片。 true :默认卡片。 false :非默认卡片。 | 布尔值 | 否 | -| colorMode | 标识卡片的主题样式,取值范围如下 : auto :自适应。 dark :深色主题。 light :浅色主题。 | 字符串 | 可缺省,缺省值为“auto”。 | -| supportDimensions | 标识卡片支持的外观规格,取值范围 : 1 * 2 :表示1行2列的二宫格。 2 * 1 :表示2行1列的二宫格。 2 * 2 :表示2行2列的四宫格。 2 * 4 :表示2行4列的八宫格。 4 * 4 :表示4行4列的十六宫格。 | 字符串数组 | 否 | -| defaultDimension | 标识卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。 | 字符串 | 否 | -| updateEnabled | 该标签标识该卡片是否支持实时刷新,true标识卡片支持实时刷新,false标识不支持。 | 布尔值 | 否 | -| scheduledUpdateTime | 该标签标识卡片定点刷新的时间,采用24小时计数,精确到分钟。 | 字符串 | 是 | -| updateDuration | 该标签标识卡片定时刷新的更新频率,单位为30分钟,取值为30的倍数值。卡片的最高频率为每30分钟刷新一次,和定点刷新二选一,二者都配置的情况下,定时优先。 | 数值 | 可缺省,缺省为空。 | -| metadata | 该标签标识卡片的自定义信息。metadata内部结构参考表5。 | 对象 | 可缺省,缺省为空。 | -| formConfigAbility | 该标签标识卡片调整的Ability名称。标签值为字符串类型(最长127字符)。该标签值必须满足下面的格式 :
ability://单个ability名字
单个ability名字必须为本应用的ability。 | 字符串 | 可缺省,缺省为空。 | -| formVisibleNotify | 该标签标识卡片是否被允许使用卡片可见性通知。标签值为true或false | 布尔值 | 该标签可缺省,默认值为false。 | - -表13 window内部结构说明 - -| 属性名称 | 含义 | 数据类型 | 是否可缺省 | -| --------------- | ------------------------------------------------------------ | -------- | -------------------- | -| designWidth | 指示页面设计的基线宽度,以像素为单位。 元素的大小由实际设备宽度缩放。 这个标签是一个整数。 | 数值 | 可缺省,缺省值为空。 | -| autoDesignWidth | 指定是否自动计算页面设计的基线宽度。 如果设置为true,则designWidth属性无效。基线宽度根据设备宽度和屏幕密度计算。 | 布尔值 | 可缺省,缺省值为空。 | +| name | 标识卡片的名称。最大长度为127字节。 | 字符串 | 不可缺省。 | +| description | 标识卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。最大长度为255字节。 | 字符串 | 可缺省,缺省值为空。 | +| src | 该标签标识JS卡片对应的UI代码。建议开发者通过自适应布局显示不同规格卡片,如果不同规格卡片布局相差较大,建议通过不同卡片来区分。 | 字符串 | 可缺省,缺省值为空。 | +| window | 该标签标识JS卡片的自适应能力。参考[window对象内部结构](#window对象内部结构)。 | 对象 | 可缺省,缺省值为空。 | +| isDefault | 标识该卡片是否为默认卡片,每个Ability有且只有一个默认卡片。 true :默认卡片。 false :非默认卡片。 | 布尔值 | 不可缺省。 | +| colorMode | 标识卡片的主题样式,取值范围如下 :
auto :自适应。
dark :深色主题。
light :浅色主题。
| 字符串 | 可缺省,缺省值为“auto”。 | +| supportDimensions | 标识卡片支持的外观规格,取值范围 :
1 * 2 :表示1行2列的二宫格。
2 * 1 :表示2行1列的二宫格。
2 * 2 :表示2行2列的四宫格。
2 * 4 :表示2行4列的八宫格。
4 * 4 :表示4行4列的十六宫格。 | 字符串数组 | 不可缺省。 | +| defaultDimension | 标识卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。 | 字符串 | 不可缺省。 | +| updateEnabled | 该标签标识该卡片是否支持实时刷新,true标识卡片支持实时刷新,false表示不支持。 | 布尔值 | 不可缺省。 | +| scheduledUpdateTime | 该标签标识卡片定点刷新的时间,采用24小时计数,精确到分钟。 | 字符串 | 可缺省,缺省值为空。 | +| updateDuration | 该标签标识卡片定时刷新的更新频率,单位为30分钟,取值为30的倍数。卡片的最高频率为每30分钟刷新一次,和定点刷新二选一,二者都配置的情况下,定时优先。 | 数值 | 可缺省,缺省值为空。 | +| metadata | 该标签标识卡片的元信息。参考[metadata对象内部结构](#metadata对象内部结构)。 | 对象数组 | 可缺省,缺省值为空。 | +| formConfigAbility | 该标签标识卡片调整的Ability名称。最大长度127字节。该标签值必须满足下面的格式 :
ability://单个ability名字
单个ability名字必须为本应用的ability。 | 字符串 | 可缺省,缺省值为空。 | +| formVisibleNotify | 该标签标识卡片是否被允许使用卡片可见性通知。 | 布尔值 | 可缺省,缺省值为false。 | form示例 : -在开发视图的resources/base/profile下面定义配置文件form_config.json(文件名称可由开发者定义) +1.在开发视图的resources/base/profile下面定义配置文件form_config.json(文件名称可由开发者定义): ```json { "forms": [ { "name": "Form_Js", - "description": "$string:form_description", + "description": "$string:description", "src": "./js/pages/card/index", "window": { "designWidth": 720, "autoDesignWidth": true }, "colorMode": "auto", - "formConfigAbility": "ability://xxxxx", + "formConfigAbility": "ability://xxx", "formVisibleNotify": false, "isDefault": true, "updateEnabled": true, @@ -593,200 +672,221 @@ form示例 : "updateDuration": 1, "defaultDimension": "2*2", "updateEnabled": true, - "scheduledUpdateTime": "21:33", "supportDimensions": [ "2*2" ], "metadata": [ - { - "name": "string", - "value": "string", - "resource": "$profile:config_file" - } + { + "name": "name", + "value": "value", + "resource": "$profile:resource" + } ] } ] } ``` -在module.json5的extension组件下面定义metadata信息 +2.在module.json5的extensionAbilities标签下定义metadata信息 : ```json { - "extensionAbilities": [{ - "name": "MyForm", - "type": "form", - "metadata": [{ - "name": "ohos.extability.form", - "resource": "$profile:form_config" - }] - }] + "module": { + "extensionAbilities": [ + { + "type": "form", + "metadata": [ + { + "name": "ohos.extability.form", + "resource": "$profile:form_config" + } + ] + } + ] + } } ``` #### shortcuts对象内部结构 -标识应用的快捷方式信息。标签值为数组,最多可以配置四个快捷方式。其包含四个子标签shortcutId、label、icon、wants。 - -metadata中指定shortcut信息,其中 : -1)name :指定shortcuts的名称。使用ohos.ability.shortcuts作为shortcuts信息的标识。 -2)resource :指定shortcuts信息的资源位置。 +标识应用的快捷方式信息。最多可以配置四个快捷方式。
+配置方式如下:
+ability标签配置metadata信息。name :"ohos.ability.shortcuts"。resource :指定shortcuts信息的资源位置。 -表14 shortcuts对象的内部结构说明 +表15 shortcut对象内部结构说明 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ---------- | ------------------------------------------------------------ | -------- | -------------------------- | -| shortcutId | 标识快捷方式的ID。字符串的最大长度为63字节。 | 字符串 | 否 | -| label | 标识快捷方式的标签信息,即快捷方式对外显示的文字描述信息。取值可以是描述性内容,也可以是标识label的资源索引。字符串最大长度为63字节。 | 字符串 | 可缺省,缺省为空。 | -| icon | 该标签标识shortcut的图标,标签值为资源文件的索引。 | 字符串 | 该标签可缺省,缺省值为空。 | -| wants | 该标签标识快捷方式内定义的目标wants信息集合,每个want可配置两个子标签,bundleName,abilityName。
bundleName :快捷方式目标包名,字符串类型。
abilityName :快捷方式的目标组件名,字符串类型。 | 对象 | 该标签可缺省,缺省为空。 | +| shortcutId | 标识快捷方式的ID。最大长度为63字节。 | 字符串 | 不可缺省。 | +| label | 标识快捷方式的标签信息,即快捷方式对外显示的文字描述信息。取值可以是描述性内容,也可以是标识label的资源索引。字符串最大长度为63字节。 | 字符串 | 可缺省,缺省值为空。 | +| icon | 该标签标识shortcut的图标,标签值为资源文件的索引。 | 字符串 | 可缺省,缺省值为空。 | +| wants | 该标签标识快捷方式内定义的目标wants信息集合,每个want可配置两个子标签,bundleName,abilityName。
bundleName :快捷方式目标包名,字符串类型。
abilityName :快捷方式的目标组件名,字符串类型。 | 对象数组 | 可缺省,缺省值为空。 | -在开发视图的resources/base/profile下面定义配置文件shortcut_config.json(文件名称可由开发者定义)。 +shortcuts示例 : + +1.在开发视图的resources/base/profile下面定义配置文件shortcuts_config.json(文件名称可由开发者定义): ```json { - "shortcuts": [{ - "shortcutId": "id_test1", - "label": "$string:shortcut", - "icon": "$media:aa_icon", - "wants": [{ - "bundleName": "com.ohos.hello", - "abilityName": "MainAbility" - }] - }] + "shortcuts": [ + { + "shortcutId": "shortcut_id", + "label": "$string:label", + "icon": "$media:icon", + "wants": [ + { + "bundleName": "bundleName", + "abilityName": "abilityName" + } + ] + } + ] } ``` -在module.json5的module下面定义metadata信息,如下 : +2.在module.json5的abilities标签下定义metadata信息 : ```json { "module": { - "name": "MyAbilityStage", - "abilities": [{ - "name": "MyAbility", - "srcEntrance": "./abilities/MyAbility.ts", - "skills": [{ - "actions": ["action.system.home"], - "entities": ["entity.system.home"], - "uris": [] - }], - "metadata": [{ - "name": "ohos.ability.shortcuts", - "resource": "$profile:shortcuts_config" - }] - }] + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./abilities/MainAbility.ts", + "skills": [ + { + "actions": ["action.system.home"], + "entities": ["entity.system.home"] + } + ], + "metadata": [ + { + "name": "ohos.ability.shortcuts", + "resource": "$profile:shortcuts_config" + } + ] + } + ] } } ``` #### commonEvents对象内部结构 -commonEvents标签标识注册静态公共事件信息。标签值为数组。 -metadata中指定commonEvent信息,其中 : - -1. name :指定commonEvent的名称。使用ohos.extability.staticSubscriber作为commonEvent信息的标识。 +commonEvents标签标识注册静态公共事件信息。
+配置方式如下:
+extensionAbility标签配置type为staticSubscriber,并配置metadata信息:name :"ohos.extability.staticSubscriber"。resource :指定commonEvents信息的资源位置。 -2. resource :指定commonEvent信息的资源位置。 - -表15 commonEvents对象内部结构 +表16 commonEvent对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ---------- | ------------------------------------------------------------ | ---------- | -------------------------- | -| name | 该标签指明当前静态公共事件对应的ability名,该类需要在ability中标明。 | 字符串 | 该标签不可缺省。 | +| name | 该标签指明当前静态公共事件对应的ability名,该类需要在ability中标明。 | 字符串 | 不可缺省。 | | permission | 该标签标识实现该静态公共事件需要申请的权限,以字符串类型表示一个权限名称,通常采用反向域名方式表示(最大255字节)。 | 字符串 | 可缺省,缺省值为空。 | -| types | 该标签配置当前静态公共事件的类别数组,字符串数组类型,每个数组元素为一个类别名称。 | 字符串数组 | 该标签可缺省,缺省值为空。 | -| events | 该标签标识能够接收的意图的event值的集合,取值通常为系统预定义的event值,也允许自定义。 | 字符串数组 | 该标签不可缺省。 | +| types | 该标签配置当前静态公共事件的类别数组,字符串数组类型,每个数组元素为一个类别名称。 | 字符串数组 | 可缺省,缺省值为空。 | +| events | 该标签标识能够接收的意图的event值的集合,取值通常为系统预定义的event值,也允许自定义。 | 字符串数组 | 不可缺省。 | + +commonEvents示例 : -在开发视图的resources/base/profile下面定义配置文件common_event_config.json(文件名称可由开发者定义)。 +1.在开发视图的resources/base/profile下面定义配置文件common_event_config.json(文件名称可由开发者定义): ```json { - "commonEvents": [{ - "name": "abilityName", - "permission": "string", - "types": [ - "string", - "string" - ], - "events": [ - "string", - "string" - ] - }] + "commonEvents": [ + { + "name": "abilityName", + "permission": "permissionName", + "types": [ + "type1", + "type2" + ], + "events": [ + "event1", + "event2" + ] + } + ] } ``` -在module.json5的extension组件下面定义metadata信息,如下 : +2.在module.json5的extensionAbilities标签下定义metadata信息 : ```json -"extensionAbilities": [ - { - "name": "mySubscriber", - "srcEntrance": "./extension/my_subscriber.js", - "type": "staticSubscriber", - "metadata": [{ - "name": "ohos.extability.staticSubscriber", - "resource": "$profile:common_event_config", - }], +{ + "module": { + "extensionAbilities": [ + { + "name": "subscriber", + "srcEntrance": "./extension/subscriber.js", + "type": "staticSubscriber", + "metadata": [ + { + "name": "ohos.extability.staticSubscriber", + "resource": "$profile:common_event_config" + } + ] + } + ] } -] +} ``` #### distroFilter对象内部结构 标识应用的分发规则。 -该标签用于定义HAP包对应的细分设备规格的分发策略,以便在应用市场进行云端分发应用包时做精准匹配。该标签可配置的分发策略维度包括API Version、屏幕形状、屏幕分辨率。在进行分发时,通过deviceType与这三个属性的匹配关系,唯一确定一个用于分发到设备的HAP。 +该标签用于定义HAP包对应的细分设备规格的分发策略,以便在应用市场进行云端分发应用包时做精准匹配。该标签可配置的分发策略维度包括API Version、屏幕形状、窗口分辨率、屏幕分辨率、国家码。在进行分发时,通过deviceType与这五个属性的匹配关系,唯一确定一个用于分发到设备的HAP。
+配置方式如下:
+module标签配置metadata信息。name :"ohos.module.distro"。resource :指定distroFilter信息的资源位置。 -表16 distroFilter对象内部结构 +表17 distroFilter对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | ------------- | ------------------------------------------------------------ | -------- | -------------------------- | -| apiVersion | 标识支持的apiVersion范围。参考表16。 | 对象数组 | 该标签可缺省,缺省值为空。 | -| screenShape | 标识屏幕形状的支持策略。 | 对象数组 | 该标签可缺省,缺省值为空。 | -| screenWindow | 标识应用运行时窗口的分辨率支持策略。该字段仅支持对轻量级智能穿戴设备进行配置。 | 对象数组 | 该标签可缺省,缺省值为空。 | -| screenDensity | 该标签标识屏幕的像素密度(dpi :Dot Per Inch)。该字段可选,如果配置了该字段,取值必须合法。该标签为字符串数组,字符串范围如下。
sdpi :表示小规模的屏幕密度(Small-scale Dots per Inch),适用于dpi取值为(0,120]的设备。
mdpi :表示中规模的屏幕密度(Medium-scale Dots Per Inch),适用于dpi取值为(120,160]的设备。
ldpi :表示大规模的屏幕密度(Large-scale Dots Per Inch),适用于dpi取值为(160,240]的设备。
xldpi :表示大规模的屏幕密度(Extra Large-scale Dots Per Inch),适用于dpi取值为(240,320]的设备。
xxldpi :表示大规模的屏幕密度(Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(320,480]的设备。
xxxldpi :表示大规模的屏幕密度(Extra Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(480, 640]的设备。 | 对象数组 | 该标签可缺省,缺省值为空。 | -| countryCode | 该标签标识应用需要分发的国家地区码,具体值以ISO-3166-1标准为准。支持多个国家和地区枚举定义。该字段可选,如果配置了该字段,取值必须合法。标签值字符串数组,子串表示所支持的国家或地区,由两个大写字母组成。 | 对象数组 | 该标签可缺省,缺省值为空。 | +| apiVersion | 标识支持的apiVersion。 | 对象 | 可缺省,缺省值为空。 | +| screenShape | 标识屏幕形状的支持策略。仅支持liteWearable设备配置。 | 对象 | 可缺省,缺省值为空。 | +| screenWindow | 标识应用运行时窗口的分辨率支持策略。仅支持liteWearable设备配置。 | 对象 | 可缺省,缺省值为空。 | +| screenDensity | 标识屏幕的像素密度(dpi : Dot Per Inch)。 | 对象 | 可缺省,缺省值为空。 | +| countryCode | 标识应用需要分发的国家地区码。具体值以ISO-3166-1标准为准。 | 对象 | 可缺省,缺省值为空。 | -表17 apiVersion对象的内部结构说明 +表18 apiVersion对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------- | -| policy | 标识该子属性取值的黑白名单规则。配置为“exclude”或“include”。“include”表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | -| value | 支持的取值为API Version存在的整数值,例如4、5、6。场景示例 :某应用,针对相同设备型号,同时在网的为使用API 5和API 6开发的两个软件版本,则允许上架2个entry类型的安装包,分别支持到对应设备侧软件版本的分发。 | 数组 | 可缺省,缺省值为空。 | +| policy | 标识该子属性取值的黑白名单规则。配置为"exclude"或"include"。"include"表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | +| value | 支持的取值为API Version存在的整数值,例如4、5、6,最小取值为3。场景示例 :某应用,针对相同设备型号,同时在网的为使用API 5和API 6开发的两个软件版本,则允许上架2个entry类型的安装包,分别支持到对应设备侧软件版本的分发。 | 数值数组 | 可缺省,缺省值为空。 | -表18 screenShape对象的内部结构说明 +表19 screenShape对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------- | -| policy | 标识该子属性取值的黑白名单规则。配置为“exclude”或“include”。“include”表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | -| value | 支持的取值为circle(圆形)、rect(矩形)。场景示例 :针对智能穿戴设备,可为圆形表盘和矩形表盘分别提供不同的HAP。 | 数组 | 可缺省,缺省值为空。 | +| policy | 标识该子属性取值的黑白名单规则。配置为"exclude"或"include"。"include"表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | +| value | 支持的取值为circle(圆形屏幕)、rect(矩形屏幕)。场景示例:针对智能穿戴设备,可为圆形表盘和矩形表盘分别提供不同的HAP。 | 字符串数组 | 可缺省,缺省值为空。 | -表19 screenWindow对象的内部结构说明 +表20 screenWindow对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------- | -| policy | 标识该子属性取值的黑白名单规则。配置为“exclude”或“include”。“include”表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | -| value | 单个字符串的取值格式为 :“宽 * 高”,取值为整数像素值,例如“454 * 454”。 | 数组 | 可缺省,缺省值为空。 | +| policy | 标识该子属性取值的黑白名单规则。配置为"include"。"include"表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | +| value | 单个字符串的取值格式为 :“宽 * 高”,取值为整数像素值,例如“454 * 454”。 | 字符串数组 | 可缺省,缺省值为空。 | -表20 screenDensity对象的内部结构说明 +表21 screenDensity对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------- | -| policy | 标识该子属性取值的黑白名单规则。配置为“exclude”或“include”。“include”表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | -| value | 该标签标识屏幕的像素密度(dpi :Dot Per Inch)。 | 数组 | 可缺省,缺省值为空。 | +| policy | 标识该子属性取值的黑白名单规则。配置为"exclude"或"include"。"include"表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | +| value | 字符串范围如下:
sdpi :表示小规模的屏幕密度(Small-scale Dots per Inch),适用于dpi取值为(0,120]的设备。
mdpi :表示中规模的屏幕密度(Medium-scale Dots Per Inch),适用于dpi取值为(120,160]的设备。
ldpi :表示大规模的屏幕密度(Large-scale Dots Per Inch),适用于dpi取值为(160,240]的设备。
xldpi :表示大规模的屏幕密度(Extra Large-scale Dots Per Inch),适用于dpi取值为(240,320]的设备。
xxldpi :表示大规模的屏幕密度(Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(320,480]的设备。
xxxldpi :表示大规模的屏幕密度(Extra Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(480, 640]的设备。 | 字符串数组 | 可缺省,缺省值为空。 | -表21 countryCode对象的内部结构说明 +表22 countryCode对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ------------------------------------------------------------ | -------- | -------------------- | -| policy | 标识该子属性取值的黑白名单规则。配置为“exclude”或“include”。“include”表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | -| value | 该标签标识应用需要分发的国家地区码。 | 数组 | 可缺省,缺省值为空。 | +| policy | 标识该子属性取值的黑白名单规则。配置为"exclude"或"include"。"include"表示该字段取值为白名单,满足value枚举值匹配规则的表示匹配该属性。 | 字符串 | 可缺省,缺省值为空。 | +| value | 支持多个国家和地区枚举定义。字符串表示所支持的国家或地区,由两个大写字母组成。 | 字符串数组 | 可缺省,缺省值为空。 | distroFilter示例 : -在开发视图的resources/base/profile下面定义配置文件distroFilter_config.json(文件名称可由开发者定义)。 +1.在开发视图的resources/base/profile下面定义配置文件distro_filter_config.json(文件名称可由开发者定义): ```json "distroFilter": [ @@ -802,39 +902,50 @@ distroFilter示例 : "screenWindow": { "policy": "include", "value": ["454*454", "466*466"] + }, + "screenDensity": { + "policy": "exclude", + "value": ["ldpi", "xldpi"] + }, + "countryCode": { + "policy": "include", + "value": ["CN", "HK"] } } ] ``` -在module.json5的extensionAbilities组件下面定义metadata信息,如下 : +2.在module.json5的module标签下定义metadata信息 : ```json -"extensionAbilities": [ - { - "name": "mySubscriber", - "srcEntrance": "./extension/my_subscriber.js", - "type": "staticSubscriber", - "metadata": [{ - "name": "ohos.extability.staticSubscriber", - "resource": "$profile:distroFilter_config", - }], +{ + "module":{ + "metadata": [ + { + "name": "ohos.module.distro", + "resource": "$profile:distro_filter_config" + } + ] } -] +} ``` #### testRunner对象内部结构 -表22 testRunner对象内部结构说明 +该标签用于支持对测试框架的配置 + +表23 testRunner对象内部结构 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | | -------- | ---------------------- | -------- | ---------- | | name | 标识测试框架对象名称。 | 字符串 | 不可缺省。 | | srcPath | 标识测试框架代码路径。 | 字符串 | 不可缺省。 | +testRunner示例 : + ``` "testRunner": { - "name": "myTestRUnnerName", + "name": "testRunnerName", "srcPath": "etc/test/TestRunner.ts" } ``` diff --git a/zh-cn/application-dev/reference/apis/Readme-CN.md b/zh-cn/application-dev/reference/apis/Readme-CN.md index c5d34d86f5b43fa4406c9ac48dc9cce6628edaf9..fa059f26d31f655d191450b8b6562bf0f2680903 100755 --- a/zh-cn/application-dev/reference/apis/Readme-CN.md +++ b/zh-cn/application-dev/reference/apis/Readme-CN.md @@ -221,7 +221,7 @@ - [@ohos.multimodalInput.inputDevice (输入设备)](js-apis-inputdevice.md) - [@ohos.multimodalInput.inputDeviceCooperate (键鼠穿越管理)](js-apis-cooperate.md) - [@ohos.multimodalInput.inputEvent (输入事件)](js-apis-inputevent.md) - - [@ohos.multimodalInput.inputEventClient (注入按键)](js-apis-inputeventclient.md) + - [@ohos.multimodalInput.inputEventClient (按键注入)](js-apis-inputeventclient.md) - [@ohos.multimodalInput.inputMonitor (输入监听)](js-apis-inputmonitor.md) - [@ohos.multimodalInput.keyCode (键值)](js-apis-keycode.md) - [@ohos.multimodalInput.keyEvent (按键输入事件)](js-apis-keyevent.md) diff --git a/zh-cn/application-dev/reference/apis/js-apis-animator.md b/zh-cn/application-dev/reference/apis/js-apis-animator.md index 6689361e739a8a6746f1a6fe98b7f19b70977cbb..5a8dad19cbdb6903b750f7ab7ed19aca7acea863 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-animator.md +++ b/zh-cn/application-dev/reference/apis/js-apis-animator.md @@ -34,7 +34,7 @@ create(options: AnimatorOptions): AnimatorResult **示例:** ```js - var options = { + let options = { duration: 1500, easing: 'friction', delay: 0, @@ -79,7 +79,7 @@ reset(options: AnimatorOptions): void **示例:** ```js -var options = { +let options = { duration: 1500, easing: 'friction', delay: 0, @@ -266,7 +266,7 @@ export default { animator: null }, onInit() { - var options = { + let options = { duration: 1500, easing: 'friction', delay: 0, @@ -279,7 +279,7 @@ export default { this.animator = animator.create(options); }, Show() { - var options1 = { + let options1 = { duration: 1500, easing: 'friction', delay: 0, @@ -294,7 +294,7 @@ export default { } catch(error) { console.error(`Animator reset failed, error code: ${error.code}, message: ${error.message}.`); } - var _this = this; + let _this = this; this.animator.onframe = function(value) { _this.divWidth = value; _this.divHeight = value; @@ -353,7 +353,7 @@ createAnimator(options: AnimatorOptions): AnimatorResult **示例:** ```js -var options = { +let options = { duration: 1500, easing: 'friction', delay: 0, diff --git a/zh-cn/application-dev/reference/apis/js-apis-application-Want.md b/zh-cn/application-dev/reference/apis/js-apis-application-Want.md index be3a1a0272edf7872b269db394cf6e77c87614f0..73c71a6204d6bbd3bccb0e644bb47e204d401a8b 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-application-Want.md +++ b/zh-cn/application-dev/reference/apis/js-apis-application-Want.md @@ -24,9 +24,9 @@ import Want from '@ohos.application.Want'; | uri | 只读 | string | 否 | 表示Uri描述。如果在Want中指定了Uri,则Want将匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息。 | | type | 只读 | string | 否 | 表示MIME type类型描述,打开文件的类型,主要用于文管打开文件。比如:"text/xml" 、 "image/*"等,MIME定义参考:https://www.iana.org/assignments/media-types/media-types.xhtml?utm_source=ld246.com。 | | flags | 只读 | number | 否 | 表示处理Want的方式。默认传数字,具体参考:[flags说明](js-apis-featureAbility.md#flags说明)。 | -| action | 只读 | string | 否 | 表示action选项描述。 | -| parameters | 只读 | {[key: string]: any} | 否 | 表示WantParams描述,由开发者自行决定传入的键值对。默认会携带以下key值:
ohos.aafwk.callerPid 表示拉起方的pid。
ohos.aafwk.param.callerToken 表示拉起方的token。
ohos.aafwk.param.callerUid 表示发起方的uid。[Bundle](js-apis-Bundle.md)模块中userId参数,可用于获取应用信息、包信息等,具体参考:[Bundle](js-apis-Bundle.md)。 | -| entities | 只读 | Array\ | 否 | 表示entities相关描述。 | +| action | 只读 | string | 否 | 表示要执行的通用操作(如:查看、分享、应用详情)。在隐式Want中,您可以定义该字段,配合uri或parameters来表示对数据要执行的操作。 | +| parameters | 只读 | {[key: string]: any} | 否 | 表示WantParams描述,由开发者自行决定传入的键值对。默认会携带以下key值:
ohos.aafwk.callerPid 表示拉起方的pid。
ohos.aafwk.param.callerToken 表示拉起方的token。
ohos.aafwk.param.callerUid 表示[bundleInfo](js-apis-bundle-BundleInfo.md#bundleinfo-1)中的uid,应用包里应用程序的uid。 | +| entities | 只读 | Array\ | 否 | 表示目标Ability额外的类别信息(如:浏览器、视频播放器),在隐式Want中是对action字段的补充。在隐式Want中,您可以定义该字段,来过滤匹配Ability类型。 | | moduleName9+ | 只读 | string | 否 | 表示待启动的Ability所属的模块(module)。 | **示例:** diff --git a/zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md b/zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md index 7fb56e487ec5d78cd1f6ae87edbc645faee0a5bc..978d61fb22593e3bd13d26f1cec086de57720e5d 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md +++ b/zh-cn/application-dev/reference/apis/js-apis-application-shellCmdResult.md @@ -8,17 +8,17 @@ ## 使用说明 -通过abilityDelegator中的executeShellCommand方法来获取。 +通过abilityDelegator中的[executeShellCommand](js-apis-application-abilityDelegator.md#executeshellcommand)方法来获取。 ```js -import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' -var abilityDelegator; -var cmd = "cmd"; -var timeout = 100; +import AbilityDelegatorRegistry from "@ohos.application.abilityDelegatorRegistry"; +let abilityDelegator; +let cmd = "cmd"; abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.executeShellCommand(cmd, timeout).then((data : any) => { - console.info("executeShellCommand promise"); +abilityDelegator.executeShellCommand(cmd, (err: any, data: any) => { + console.info("executeShellCommand callback, failed: ", err); + console.info("executeShellCommand callback, success: ", data); }); ``` @@ -30,5 +30,5 @@ Shell命令执行结果 | 名称 | 类型 | 可读 | 可写 | 说明 | | --------- | ------ | ---- | ---- | ------------------------------------------------------------ | -| stdResult | string | 是 | 是 | 标准输出内容 | -| exitCode | number | 是 | 是 | 结果码 | +| stdResult | string | 是 | 是 | 标准输出内容。 | +| exitCode | number | 是 | 是 | 结果码。 | diff --git a/zh-cn/application-dev/reference/apis/js-apis-audio.md b/zh-cn/application-dev/reference/apis/js-apis-audio.md index 0fddf9e9588d7165b64047f31cc65001127b671b..83ee7b3ef188b7aab26be93dbdce6cec416d79ed 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-audio.md +++ b/zh-cn/application-dev/reference/apis/js-apis-audio.md @@ -20,13 +20,11 @@ import audio from '@ohos.multimedia.audio'; ## 常量 -**系统接口:** 该接口为系统接口 - -**系统能力:** SystemCapability.Multimedia.Audio.Device - -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ----- | -------------------------- | ---- | ---- | ------------------ | -| LOCAL_NETWORK_ID9+ | string | 是 | 否 | 本地设备网络id。 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| --------------------------------------- | ----------| ---- | ---- | ------------------ | +| LOCAL_NETWORK_ID9+ | string | 是 | 否 | 本地设备网络id。
此接口为系统接口。
**系统能力:** SystemCapability.Multimedia.Audio.Device | +| DEFAULT_VOLUME_GROUP_ID9+ | number | 是 | 否 | 默认音量组id。
**系统能力:** SystemCapability.Multimedia.Audio.Volume | +| DEFAULT_INTERRUPT_GROUP_ID9+ | number | 是 | 否 | 默认音频中断组id。
**系统能力:** SystemCapability.Multimedia.Audio.Interrupt | **示例:** @@ -34,6 +32,8 @@ import audio from '@ohos.multimedia.audio'; import audio from '@ohos.multimedia.audio'; const localNetworkId = audio.LOCAL_NETWORK_ID; +const defaultVolumeGroupId = audio.DEFAULT_VOLUME_GROUP_ID; +const defaultInterruptGroupId = audio.DEFAULT_INTERRUPT_GROUP_ID; ``` ## audio.getAudioManager @@ -263,6 +263,8 @@ createTonePlayer(options: AudioRendererInfo, callback: AsyncCallback<TonePlay **系统能力:** SystemCapability.Multimedia.Audio.Tone +**系统接口:** 该接口为系统接口 + **参数:** | 参数名 | 类型 | 必填 | 说明 | @@ -281,6 +283,7 @@ let audioRendererInfo = { "rendererFlags": 0 } let tonePlayer; + audio.createTonePlayer(audioRendererInfo, (err, data) => { console.info(`callback call createTonePlayer: audioRendererInfo: ${audioRendererInfo}`); if (err) { @@ -300,6 +303,8 @@ createTonePlayer(options: AudioRendererInfo): Promise<TonePlayer> **系统能力:** SystemCapability.Multimedia.Audio.Tone +**系统接口:** 该接口为系统接口 + **参数:** | 参数名 | 类型 | 必填 | 说明 | @@ -338,18 +343,31 @@ async function createTonePlayer(){ | RINGTONE | 2 | 铃声。 | | MEDIA | 3 | 媒体。 | | VOICE_ASSISTANT8+ | 9 | 语音助手。 | -| ALL9+ | 100 | 所有公共音频流。
此接口为系统接口,三方应用不支持调用。| +| ALL9+ | 100 | 所有公共音频流。
此接口为系统接口。| + +## InterruptRequestResultType9+ + +枚举,音频中断请求结果类型。 + +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt + +**系统接口:** 该接口为系统接口 + +| 名称 | 默认值 | 描述 | +| ---------------------------- | ------ | ---------- | +| INTERRUPT_REQUEST_GRANT | 0 | 请求音频中断成功。 | +| INTERRUPT_REQUEST_REJECT | 1 | 请求音频中断失败,可能具有较高优先级类型。 | ## InterruptMode9+ 枚举,焦点模型。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt | 名称 | 默认值 | 描述 | | ---------------------------- | ------ | ---------- | -| SHARE_MODE | 0 | 共享焦点模式。 | -| INDEPENDENT_MODE| 1 | 独立焦点模式。 | +| SHARE_MODE | 0 | 共享焦点模式。 | +| INDEPENDENT_MODE | 1 | 独立焦点模式。 | ## DeviceFlag @@ -359,14 +377,13 @@ async function createTonePlayer(){ | 名称 | 默认值 | 描述 | | ------------------------------- | ------ | ------------------------------------------------- | -| NONE_DEVICES_FLAG9+ | 0 | 无
此接口为系统接口,三方应用不支持调用。 | +| NONE_DEVICES_FLAG9+ | 0 | 无
此接口为系统接口。 | | OUTPUT_DEVICES_FLAG | 1 | 输出设备。 | | INPUT_DEVICES_FLAG | 2 | 输入设备。 | | ALL_DEVICES_FLAG | 3 | 所有设备。 | -| DISTRIBUTED_OUTPUT_DEVICES_FLAG9+ | 4 | 分布式输出设备。
此接口为系统接口,三方应用不支持调用。 | -| DISTRIBUTED_INPUT_DEVICES_FLAG9+ | 8 | 分布式输入设备。
此接口为系统接口,三方应用不支持调用。 | -| ALL_DISTRIBUTED_DEVICES_FLAG9+ | 12 | 分布式输入和输出设备。
此接口为系统接口,三方应用不支持调用。 | - +| DISTRIBUTED_OUTPUT_DEVICES_FLAG9+ | 4 | 分布式输出设备。
此接口为系统接口。 | +| DISTRIBUTED_INPUT_DEVICES_FLAG9+ | 8 | 分布式输入设备。
此接口为系统接口。 | +| ALL_DISTRIBUTED_DEVICES_FLAG9+ | 12 | 分布式输入和输出设备。
此接口为系统接口。 | ## DeviceRole @@ -379,7 +396,6 @@ async function createTonePlayer(){ | INPUT_DEVICE | 1 | 输入设备角色。 | | OUTPUT_DEVICE | 2 | 输出设备角色。 | - ## DeviceType 枚举,设备类型。 @@ -399,16 +415,15 @@ async function createTonePlayer(){ | USB_HEADSET | 22 | USB耳机,带麦克风。 | | DEFAULT9+ | 1000 | 默认设备类型。 | -## ActiveDeviceType +## CommunicationDeviceType9+ -枚举,活跃设备类型。 +枚举,用于通信的可用设备类型。 -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Device +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Communication -| 名称 | 默认值 | 描述 | -| ------------- | ------ | ---------------------------------------------------- | -| SPEAKER | 2 | 扬声器。 | -| BLUETOOTH_SCO | 7 | 蓝牙设备SCO(Synchronous Connection Oriented)连接。 | +| 名称 | 默认值 | 描述 | +| ------------- | ------ | -------------| +| SPEAKER | 2 | 扬声器。 | ## AudioRingMode @@ -437,6 +452,22 @@ async function createTonePlayer(){ | SAMPLE_FORMAT_S32LE | 3 | 带符号的32位整数,小尾数。
由于系统限制,该采样格式仅部分设备支持,请根据实际情况使用。| | SAMPLE_FORMAT_F32LE9+ | 4 | 带符号的32位整数,小尾数。
由于系统限制,该采样格式仅部分设备支持,请根据实际情况使用。| +## AudioErrors9+ + +枚举,音频错误码。 + +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Core + +| 错误信息 | 错误码 | 错误描述 | +| ---------------------| --------| ----------------- | +| ERROR_INVALID_PARAM | 6800101 | 无效入参。 | +| ERROR_NO_MEMORY | 6800102 | 分配内存失败。 | +| ERROR_ILLEGAL_STATE | 6800103 | 状态不支持。 | +| ERROR_UNSUPPORTED | 6800104 | 参数选项不支持。 | +| ERROR_TIMEOUT | 6800105 | 处理超时。 | +| ERROR_STREAM_LIMIT | 6800201 | 音频流数量达到限制。| +| ERROR_SYSTEM | 6800301 | 系统处理异常。 | + ## AudioChannel8+ 枚举, 音频声道。 @@ -508,18 +539,17 @@ async function createTonePlayer(){ | STREAM_USAGE_VOICE_ASSISTANT9+ | 3 | 语音播报。 | | STREAM_USAGE_NOTIFICATION_RINGTONE | 6 | 通知铃声。 | -## FocusType9+ +## InterruptRequestType9+ -表示焦点类型的枚举。 +枚举,音频中断请求类型。 **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Core - -| 名称 | 默认值 | 描述 | -| ---------------------------------- | ------ | ------------------------------- | -| FOCUS_TYPE_RECORDING | 0 | 在录制场景使用,可打断其他音频。 | +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt +| 名称 | 默认值 | 描述 | +| ---------------------------------- | ------ | ------------------------- | +| INTERRUPT_REQUEST_TYPE_DEFAULT | 0 | 默认类型,可中断音频请求。 | ## AudioState8+ @@ -586,29 +616,18 @@ async function createTonePlayer(){ | INTERRUPT_HINT_DUCK | 4 | 提示音频躲避。(躲避:音量减弱,而不会停止) | | INTERRUPT_HINT_UNDUCK8+ | 5 | 提示音量恢复。 | -## InterruptActionType - -枚举,中断事件返回类型。 - -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer - -| 名称 | 默认值 | 描述 | -| -------------- | ------ | ------------------ | -| TYPE_ACTIVATED | 0 | 表示触发焦点事件。 | -| TYPE_INTERRUPT | 1 | 表示音频打断事件。 | - ## AudioStreamInfo8+ 音频流信息。 **系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Core -| 名称 | 类型 | 必填 | 说明 | -| ------------ | ---------------------------------------- | ---- | ------------------ | -| samplingRate | [AudioSamplingRate](#audiosamplingrate8) | 是 | 音频文件的采样率。 | -| channels | [AudioChannel](#audiochannel8) | 是 | 音频文件的通道数。 | -| sampleFormat | [AudioSampleFormat](#audiosampleformat8) | 是 | 音频采样格式。 | -| encodingType | [AudioEncodingType](#audioencodingtype8) | 是 | 音频编码格式。 | +| 名称 | 类型 | 必填 | 说明 | +| ------------ | ------------------------------------------------- | ---- | ------------------ | +| samplingRate | [AudioSamplingRate](#audiosamplingrate8) | 是 | 音频文件的采样率。 | +| channels | [AudioChannel](#audiochannel8) | 是 | 音频文件的通道数。 | +| sampleFormat | [AudioSampleFormat](#audiosampleformat8) | 是 | 音频采样格式。 | +| encodingType | [AudioEncodingType](#audioencodingtype8) | 是 | 音频编码格式。 | ## AudioRendererInfo8+ @@ -622,6 +641,19 @@ async function createTonePlayer(){ | usage | [StreamUsage](#streamusage) | 是 | 音频流使用类型。 | | rendererFlags | number | 是 | 音频渲染器标志。 | +## InterruptResult9+ + +音频中断结果。 + +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Interrupt + +**系统接口:** 该接口为系统接口 + +| 名称 | 类型 | 必填 | 说明 | +| --------------| -------------------------------------------------------------- | ---- | ---------------- | +| requestResult | [InterruptRequestResultType](#interruptrequestresulttype9) | 是 | 表示音频请求中断类型。 | +| interruptNode | number | 是 | 音频请求中断的节点。 | + ## AudioRendererOptions8+ 音频渲染器选项信息。 @@ -645,31 +677,6 @@ async function createTonePlayer(){ | forceType | [InterruptForceType](#interruptforcetype9) | 是 | 操作是由系统执行或是由应用程序执行。 | | hintType | [InterruptHint](#interrupthint) | 是 | 中断提示。 | -## AudioInterrupt - -音频监听事件传入的参数。 - -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer - -| 名称 | 类型 | 必填 | 说明 | -| --------------- | --------------------------- | ---- | ------------------------------------------------------------ | -| streamUsage | [StreamUsage](#streamusage) | 是 | 音频流使用类型。 | -| contentType | [ContentType](#contenttype) | 是 | 音频打断媒体类型。 | -| pauseWhenDucked | boolean | 是 | 音频打断时是否可以暂停音频播放(true表示音频播放可以在音频打断期间暂停,false表示相反)。 | - -## InterruptAction - -音频打断/获取焦点事件的回调方法。 - -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer - -| 名称 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | -| actionType | [InterruptActionType](#interruptactiontype) | 是 | 事件返回类型。TYPE_ACTIVATED为焦点触发事件,TYPE_INTERRUPT为音频打断事件。 | -| type | [InterruptType](#interrupttype) | 否 | 打断事件类型。 | -| hint | [InterruptHint](#interrupthint) | 否 | 打断事件提示。 | -| activated | boolean | 否 | 获得/释放焦点。true表示焦点获取/释放成功,false表示焦点获得/释放失败。 | - ## VolumeEvent8+ 音量改变时,应用接收的事件。 @@ -702,7 +709,7 @@ async function createTonePlayer(){ **系统接口:** 该接口为系统接口 -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Device +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Volume | 名称 | 默认值 | 描述 | | :------------------------------ | :----- | :--------------------- | @@ -739,7 +746,7 @@ async function createTonePlayer(){ import audio from '@ohos.multimedia.audio'; async function getVolumeGroupInfos(){ - let volumegroupinfos = await audio.getAudioManager().getVolumeGroups(audio.LOCAL_NETWORK_ID); + let volumegroupinfos = await audio.getAudioManager().getVolumeManager().getVolumeGroupInfos(audio.LOCAL_NETWORK_ID); console.info('Promise returned to indicate that the volumeGroup list is obtained.'+JSON.stringify(volumegroupinfos)) } getVolumeGroupInfos(); @@ -811,889 +818,968 @@ getVolumeGroupInfos(); | 名称 | 默认值 | 描述 | | :--------------------- | :----- | :-------------------------------------------- | | AUDIO_SCENE_DEFAULT | 0 | 默认音频场景。 | -| AUDIO_SCENE_RINGING | 1 | 响铃模式。
此接口为系统接口,三方应用不支持调用。 | -| AUDIO_SCENE_PHONE_CALL | 2 | 电话模式。
此接口为系统接口,三方应用不支持调用。 | +| AUDIO_SCENE_RINGING | 1 | 响铃模式。
此接口为系统接口。 | +| AUDIO_SCENE_PHONE_CALL | 2 | 电话模式。
此接口为系统接口。 | | AUDIO_SCENE_VOICE_CHAT | 3 | 语音聊天模式。 | ## AudioManager 管理音频音量和音频设备。在调用AudioManager的接口前,需要先通过[getAudioManager](#audiogetaudiomanager)创建实例。 -### getRoutingManager9+ +### setAudioParameter + +setAudioParameter(key: string, value: string, callback: AsyncCallback<void>): void -getRoutingManager(callback: AsyncCallback<AudioRoutingManager>): void +音频参数设置,使用callback方式异步返回结果。 -获取AudioRoutingManager对象,使用callback方式异步返回结果。 +本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**需要权限:** ohos.permission.MODIFY_AUDIO_SETTINGS + +**系统能力:** SystemCapability.Multimedia.Audio.Core **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ---------------------------------------------------------------- | ---- | --------------------------------- | -| callback | AsyncCallback<[AudioRoutingManager](#audioroutingmanager9)> | 是 | 回调,返回AudioRoutingManager对象。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------- | ---- | ------------------------ | +| key | string | 是 | 被设置的音频参数的键。 | +| value | string | 是 | 被设置的音频参数的值。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** + ```js -audioManager.getRoutingManager((err, callback) => { +audioManager.setAudioParameter('key_example', 'value_example', (err) => { if (err) { - console.error(`Result ERROR: ${err}`); + console.error(`Failed to set the audio parameter. ${err}`); + return; } - console.info('getRoutingManager Callback SUCCESS.'); - let audioRoutingManager; - audioRoutingManager = callback; + console.info('Callback invoked to indicate a successful setting of the audio parameter.'); }); ``` -### getRoutingManager9+ +### setAudioParameter -getRoutingManager(): Promise<AudioRoutingManager> +setAudioParameter(key: string, value: string): Promise<void> -获取AudioRoutingManager对象,使用Promise方式异步返回结果。 +音频参数设置,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 + +**需要权限:** ohos.permission.MODIFY_AUDIO_SETTINGS + +**系统能力:** SystemCapability.Multimedia.Audio.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------------- | +| key | string | 是 | 被设置的音频参数的键。 | +| value | string | 是 | 被设置的音频参数的值。 | **返回值:** -| 类型 | 说明 | -| ----------------------------------------------------------- | --------------------------------------- | -| Promise<[AudioRoutingManager](#audioroutingmanager9)> | Promise回调返回AudioRoutingManager对象。 | +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | **示例:** + ```js -let audioManager = audio.getAudioManager(); -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - let routingManager = value; - console.info('getRoutingManager Promise SUCCESS.'); - }).catch((err) => { - console.error(`Result ERROR: ${err}`); - }); -} +audioManager.setAudioParameter('key_example', 'value_example').then(() => { + console.info('Promise returned to indicate a successful setting of the audio parameter.'); +}); ``` -### setVolume - -setVolume(volumeType: AudioVolumeType, volume: number, callback: AsyncCallback<void>): void +### getAudioParameter -设置指定流的音量,使用callback方式异步返回结果。 +getAudioParameter(key: string, callback: AsyncCallback<string>): void -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +获取指定音频参数值,使用callback方式异步返回结果。 -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Core **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | -| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------- | ---- | ---------------------------- | +| key | string | 是 | 待获取的音频参数的键。 | +| callback | AsyncCallback<string> | 是 | 回调返回获取的音频参数的值。 | **示例:** ```js -audioManager.setVolume(audio.AudioVolumeType.MEDIA, 10, (err) => { +audioManager.getAudioParameter('key_example', (err, value) => { if (err) { - console.error(`Failed to set the volume. ${err}`); + console.error(`Failed to obtain the value of the audio parameter. ${err}`); return; } - console.info('Callback invoked to indicate a successful volume setting.'); + console.info(`Callback invoked to indicate that the value of the audio parameter is obtained ${value}.`); }); ``` -### setVolume - -setVolume(volumeType: AudioVolumeType, volume: number): Promise<void> +### getAudioParameter -设置指定流的音量,使用Promise方式异步返回结果。 +getAudioParameter(key: string): Promise<string> -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +获取指定音频参数值,使用Promise方式异步返回结果。 -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Core **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------------- | +| key | string | 是 | 待获取的音频参数的键。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise<void> | Promise回调表示成功还是失败。 | +| 类型 | 说明 | +| --------------------- | ----------------------------------- | +| Promise<string> | Promise回调返回获取的音频参数的值。 | **示例:** ```js -audioManager.setVolume(audio.AudioVolumeType.MEDIA, 10).then(() => { - console.info('Promise returned to indicate a successful volume setting.'); +audioManager.getAudioParameter('key_example').then((value) => { + console.info(`Promise returned to indicate that the value of the audio parameter is obtained ${value}.`); }); ``` -### getVolume +### setAudioScene8+ -getVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +setAudioScene\(scene: AudioScene, callback: AsyncCallback\): void -获取指定流的音量,使用callback方式异步返回结果。 +设置音频场景模式,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回音量大小。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :----------------------------------- | :--- | :------------------- | +| scene | AudioScene | 是 | 音频场景模式。 | +| callback | AsyncCallback | 是 | 用于返回结果的回调。 | **示例:** ```js -audioManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { +let audioManager = audio.getAudioManager(); +audioManager.setAudioScene(audio.AudioScene.AUDIO_SCENE_PHONE_CALL, (err) => { if (err) { - console.error(`Failed to obtain the volume. ${err}`); + console.error(`Failed to set the audio scene mode.​ ${err}`); return; } - console.info('Callback invoked to indicate that the volume is obtained.'); + console.info('Callback invoked to indicate a successful setting of the audio scene mode.'); }); ``` -### getVolume +### setAudioScene8+ -getVolume(volumeType: AudioVolumeType): Promise<number> +setAudioScene\(scene: AudioScene\): Promise -获取指定流的音量,使用Promise方式异步返回结果。 +设置音频场景模式,使用Promise方式返回异步结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| :----- | :----------------------------------- | :--- | :------------- | +| scene | AudioScene | 是 | 音频场景模式。 | **返回值:** -| 类型 | 说明 | -| --------------------- | ------------------------- | -| Promise<number> | Promise回调返回音量大小。 | +| 类型 | 说明 | +| :------------- | :------------------- | +| Promise | 用于返回结果的回调。 | **示例:** ```js -audioManager.getVolume(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promise returned to indicate that the volume is obtained ${value} .`); +let audioManager = audio.getAudioManager(); +audioManager.setAudioScene(audio.AudioScene.AUDIO_SCENE_PHONE_CALL).then(() => { + console.info('Promise returned to indicate a successful setting of the audio scene mode.'); +}).catch ((err) => { + console.error(`Failed to set the audio scene mode ${err}`); }); ``` -### getMinVolume +### getAudioScene8+ -getMinVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +getAudioScene\(callback: AsyncCallback\): void -获取指定流的最小音量,使用callback方式异步返回结果。 +获取音频场景模式,使用callback方式返回异步结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回最小音量。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :-------------------------------------------------- | :--- | :--------------------------- | +| callback | AsyncCallback<AudioScene> | 是 | 用于返回音频场景模式的回调。 | **示例:** ```js -audioManager.getMinVolume(audio.AudioVolumeType.MEDIA, (err, value) => { +let audioManager = audio.getAudioManager(); +audioManager.getAudioScene((err, value) => { if (err) { - console.error(`Failed to obtain the minimum volume. ${err}`); + console.error(`Failed to obtain the audio scene mode.​ ${err}`); return; } - console.info(`Callback invoked to indicate that the minimum volume is obtained. ${value}`); + console.info(`Callback invoked to indicate that the audio scene mode is obtained ${value}.`); }); ``` -### getMinVolume +### getAudioScene8+ -getMinVolume(volumeType: AudioVolumeType): Promise<number> - -获取指定流的最小音量,使用Promise方式异步返回结果。 - -**系统能力:** SystemCapability.Multimedia.Audio.Volume +getAudioScene\(\): Promise -**参数:** +获取音频场景模式,使用Promise方式返回异步结果。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +**系统能力:** SystemCapability.Multimedia.Audio.Communication **返回值:** -| 类型 | 说明 | -| --------------------- | ------------------------- | -| Promise<number> | Promise回调返回最小音量。 | +| 类型 | 说明 | +| :-------------------------------------------- | :--------------------------- | +| Promise<AudioScene> | 用于返回音频场景模式的回调。 | **示例:** ```js -audioManager.getMinVolume(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promised returned to indicate that the minimum volume is obtained. ${value}`); +let audioManager = audio.getAudioManager(); +audioManager.getAudioScene().then((value) => { + console.info(`Promise returned to indicate that the audio scene mode is obtained ${value}.`); +}).catch ((err) => { + console.error(`Failed to obtain the audio scene mode ${err}`); }); ``` -### getMaxVolume +### getVolumeManager9+ -getMaxVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +getVolumeManager(): AudioVolumeManager -获取指定流的最大音量,使用callback方式异步返回结果。 +获取音频音量管理器。 **系统能力:** SystemCapability.Multimedia.Audio.Volume -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ---------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回最大音量大小。 | - **示例:** ```js -audioManager.getMaxVolume(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`Failed to obtain the maximum volume. ${err}`); - return; - } - console.info(`Callback invoked to indicate that the maximum volume is obtained. ${value}`); -}); +let audioVolumeManager = audioManager.getVolumeManager(); ``` -### getMaxVolume +### getStreamManager9+ -getMaxVolume(volumeType: AudioVolumeType): Promise<number> +getStreamManager(): AudioStreamManager -获取指定流的最大音量,使用Promise方式异步返回结果。 +获取音频流管理器。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Core -**参数:** +**示例:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +```js +let audioStreamManager = audioManager.getStreamManager(); +``` -**返回值:** +### getRoutingManager9+ -| 类型 | 说明 | -| --------------------- | ----------------------------- | -| Promise<number> | Promise回调返回最大音量大小。 | +getRoutingManager(): AudioRoutingManager + +获取音频路由设备管理器。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **示例:** ```js -audioManager.getMaxVolume(audio.AudioVolumeType.MEDIA).then((data) => { - console.info('Promised returned to indicate that the maximum volume is obtained.'); -}); +let audioRoutingManager = audioManager.getRoutingManager(); ``` -### mute +## AudioVolumeManager9+ -mute(volumeType: AudioVolumeType, mute: boolean, callback: AsyncCallback<void>): void +音量管理。在使用AudioVolumeManager的接口前,需要使用[getVolumeManager](#getvolumemanager9)获取AudioVolumeManager实例。 -设置指定音量流静音,使用callback方式异步返回结果。 +### getVolumeGroupInfos9+ -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +getVolumeGroupInfos(networkId: string, callback: AsyncCallback\): void -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +获取音量组信息列表,使用callback方式异步返回结果。 + +**系统接口:** 该接口为系统接口 **系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | -| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------------------------------ | ---- | -------------------- | +| networkId | string | 是 | 设备的网络id。本地设备audio.LOCAL_NETWORK_ID。 | +| callback | AsyncCallback<[VolumeGroupInfos](#volumegroupinfos9)> | 是 | 回调,返回音量组信息列表。 | **示例:** - ```js -audioManager.mute(audio.AudioVolumeType.MEDIA, true, (err) => { +audioVolumeManager.getVolumeGroupInfos(audio.LOCAL_NETWORK_ID, (err, value) => { if (err) { - console.error(`Failed to mute the stream. ${err}`); + console.error(`Failed to obtain the volume group infos list. ${err}`); return; } - console.info('Callback invoked to indicate that the stream is muted.'); + console.info('Callback invoked to indicate that the volume group infos list is obtained.'); }); ``` -### mute +### getVolumeGroupInfos9+ -mute(volumeType: AudioVolumeType, mute: boolean): Promise<void> - -设置指定音量流静音,使用Promise方式异步返回结果。 +getVolumeGroupInfos(networkId: string\): Promise -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +获取音量组信息列表,使用promise方式异步返回结果。 -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +**系统接口:** 该接口为系统接口 **系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------| ---- | -------------------- | +| networkId | string | 是 | 设备的网络id。本地设备audio.LOCAL_NETWORK_ID。 | **返回值:** | 类型 | 说明 | | ------------------- | ----------------------------- | -| Promise<void> | Promise回调表示成功还是失败。 | +| Promise<[VolumeGroupInfos](#volumegroupinfos9)> | 音量组信息列表。 | **示例:** - ```js -audioManager.mute(audio.AudioVolumeType.MEDIA, true).then(() => { - console.info('Promise returned to indicate that the stream is muted.'); -}); +async function getVolumeGroupInfos(){ + let volumegroupinfos = await audio.getAudioManager().getVolumeManager().getVolumeGroupInfos(audio.LOCAL_NETWORK_ID); + console.info('Promise returned to indicate that the volumeGroup list is obtained.'+JSON.stringify(volumegroupinfos)) +} ``` +### getVolumeGroupManager9+ -### isMute +getVolumeGroupManager(groupId: number, callback: AsyncCallback\): void -isMute(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void - -获取指定音量流是否被静音,使用callback方式异步返回结果。 +获取音频组管理器,使用callback方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ----------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调返回流静音状态,true为静音,false为非静音。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------------------------------ | ---- | -------------------- | +| groupId | number | 是 | 音量组id。 | +| callback | AsyncCallback< [AudioVolumeGroupManager](#audiovolumegroupmanager9) > | 是 | 回调,返回一个音量组实例。 | **示例:** ```js -audioManager.isMute(audio.AudioVolumeType.MEDIA, (err, value) => { +let groupid = audio.DEFAULT_VOLUME_GROUP_ID; +audioVolumeManager.getVolumeGroupManager(groupid, (err, value) => { if (err) { - console.error(`Failed to obtain the mute status. ${err}`); + console.error(`Failed to obtain the volume group infos list. ${err}`); return; } - console.info(`Callback invoked to indicate that the mute status of the stream is obtained. ${value}`); + console.info('Callback invoked to indicate that the volume group infos list is obtained.'); }); -``` +``` -### isMute +### getVolumeGroupManager9+ -isMute(volumeType: AudioVolumeType): Promise<boolean> +getVolumeGroupManager(groupId: number\): Promise -获取指定音量流是否被静音,使用Promise方式异步返回结果。 +获取音频组管理器,使用promise方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ---------------------------------------- | ---- | ---------------- | +| groupId | number | 是 | 音量组id。 | **返回值:** -| 类型 | 说明 | -| ---------------------- | ------------------------------------------------------ | -| Promise<boolean> | Promise回调返回流静音状态,true为静音,false为非静音。 | +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise< [AudioVolumeGroupManager](#audiovolumegroupmanager9) > | 音量组实例。 | **示例:** ```js -audioManager.isMute(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promise returned to indicate that the mute status of the stream is obtained ${value}.`); -}); +let groupid = audio.DEFAULT_VOLUME_GROUP_ID; +let audioVolumeGroupManager = await audioVolumeManager.getVolumeGroupManager(groupid); +console.info('Callback invoked to indicate that the volume group infos list is obtained.'); ``` -### isActive +### on('volumeChange')9+ -isActive(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void +on(type: 'volumeChange', callback: Callback\): void -获取指定音量流是否为活跃状态,使用callback方式异步返回结果。 +监听系统音量变化事件,使用callback方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调返回流的活跃状态,true为活跃,false为不活跃。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'volumeChange'。 | +| callback | Callback<[VolumeEvent](#volumeevent8)> | 是 | 回调方法。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -audioManager.isActive(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`Failed to obtain the active status of the stream. ${err}`); - return; - } - console.info(`Callback invoked to indicate that the active status of the stream is obtained ${value}.`); +audioVolumeManager.on('volumeChange', (volumeEvent) => { + console.info(`VolumeType of stream: ${volumeEvent.volumeType} `); + console.info(`Volume level: ${volumeEvent.volume} `); + console.info(`Whether to updateUI: ${volumeEvent.updateUi} `); }); ``` -### isActive +## AudioVolumeGroupManager9+ -isActive(volumeType: AudioVolumeType): Promise<boolean> +管理音频组音量。在调用AudioVolumeGroupManager的接口前,需要先通过 [getVolumeGroupManager](#getvolumegroupmanager9) 创建实例。 -获取指定音量流是否为活跃状态,使用Promise方式异步返回结果。 +**系统接口:** 该接口为系统接口 **系统能力:** SystemCapability.Multimedia.Audio.Volume -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | - -**返回值:** - -| 类型 | 说明 | -| ---------------------- | -------------------------------------------------------- | -| Promise<boolean> | Promise回调返回流的活跃状态,true为活跃,false为不活跃。 | - -**示例:** - -```js -audioManager.isActive(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promise returned to indicate that the active status of the stream is obtained ${value}.`); -}); -``` - -### setRingerMode +### setVolume9+ -setRingerMode(mode: AudioRingMode, callback: AsyncCallback<void>): void +setVolume(volumeType: AudioVolumeType, volume: number, callback: AsyncCallback<void>): void -设置铃声模式,使用callback方式异步返回结果。 +设置指定流的音量,使用callback方式异步返回结果。 **需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -仅在静音和非静音状态切换时需要该权限。 +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------------- | ---- | ------------------------ | -| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | -| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | +| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | **示例:** ```js -audioManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL, (err) => { +audioVolumeGroupManager.setVolume(audio.AudioVolumeType.MEDIA, 10, (err) => { if (err) { - console.error(`Failed to set the ringer mode.​ ${err}`); + console.error(`Failed to set the volume. ${err}`); return; } - console.info('Callback invoked to indicate a successful setting of the ringer mode.'); + console.info('Callback invoked to indicate a successful volume setting.'); }); ``` -### setRingerMode +### setVolume9+ -setRingerMode(mode: AudioRingMode): Promise<void> +setVolume(volumeType: AudioVolumeType, volume: number): Promise<void> -设置铃声模式,使用Promise方式异步返回结果。 +设置指定流的音量,使用Promise方式异步返回结果。 **需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -仅在静音和非静音状态切换时需要该权限。 +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------------------------------- | ---- | -------------- | -| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ------------------------------- | -| Promise<void> | Promise回调返回设置成功或失败。 | +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | Promise回调表示成功还是失败。 | **示例:** ```js -audioManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL).then(() => { - console.info('Promise returned to indicate a successful setting of the ringer mode.'); +audioVolumeGroupManager.setVolume(audio.AudioVolumeType.MEDIA, 10).then(() => { + console.info('Promise returned to indicate a successful volume setting.'); }); ``` +### getVolume9+ -### getRingerMode - -getRingerMode(callback: AsyncCallback<AudioRingMode>): void +getVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -获取铃声模式,使用callback方式异步返回结果。 +获取指定流的音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------------------- | ---- | ------------------------ | -| callback | AsyncCallback<[AudioRingMode](#audioringmode)> | 是 | 回调返回系统的铃声模式。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回音量大小。 | **示例:** ```js -audioManager.getRingerMode((err, value) => { +audioVolumeGroupManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error(`Failed to obtain the ringer mode.​ ${err}`); + console.error(`Failed to obtain the volume. ${err}`); return; } - console.info(`Callback invoked to indicate that the ringer mode is obtained ${value}.`); + console.info('Callback invoked to indicate that the volume is obtained.'); }); ``` +### getVolume9+ -### getRingerMode +getVolume(volumeType: AudioVolumeType): Promise<number> -getRingerMode(): Promise<AudioRingMode> +获取指定流的音量,使用Promise方式异步返回结果。 -获取铃声模式,使用Promise方式异步返回结果。 +**系统能力:** SystemCapability.Multimedia.Audio.Volume -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| ---------------------------------------------- | ------------------------------- | -| Promise<[AudioRingMode](#audioringmode)> | Promise回调返回系统的铃声模式。 | +| 类型 | 说明 | +| --------------------- | ------------------------- | +| Promise<number> | Promise回调返回音量大小。 | **示例:** ```js -audioManager.getRingerMode().then((value) => { - console.info(`Promise returned to indicate that the ringer mode is obtained ${value}.`); +audioVolumeGroupManager.getVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the volume is obtained ${value}.`); }); ``` -### setAudioParameter - -setAudioParameter(key: string, value: string, callback: AsyncCallback<void>): void - -音频参数设置,使用callback方式异步返回结果。 +### getMinVolume9+ -本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 +getMinVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -**需要权限:** ohos.permission.MODIFY_AUDIO_SETTINGS +获取指定流的最小音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------- | ---- | ------------------------ | -| key | string | 是 | 被设置的音频参数的键。 | -| value | string | 是 | 被设置的音频参数的值。 | -| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回最小音量。 | **示例:** ```js -audioManager.setAudioParameter('key_example', 'value_example', (err) => { +audioVolumeGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error(`Failed to set the audio parameter. ${err}`); + console.error(`Failed to obtain the minimum volume. ${err}`); return; } - console.info('Callback invoked to indicate a successful setting of the audio parameter.'); + console.info(`Callback invoked to indicate that the minimum volume is obtained. ${value}`); }); ``` -### setAudioParameter - -setAudioParameter(key: string, value: string): Promise<void> - -音频参数设置,使用Promise方式异步返回结果。 +### getMinVolume9+ -本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 +getMinVolume(volumeType: AudioVolumeType): Promise<number> -**需要权限:** ohos.permission.MODIFY_AUDIO_SETTINGS +获取指定流的最小音量,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------ | ---- | ---------------------- | -| key | string | 是 | 被设置的音频参数的键。 | -| value | string | 是 | 被设置的音频参数的值。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ------------------------------- | -| Promise<void> | Promise回调返回设置成功或失败。 | +| 类型 | 说明 | +| --------------------- | ------------------------- | +| Promise<number> | Promise回调返回最小音量。 | **示例:** ```js -audioManager.setAudioParameter('key_example', 'value_example').then(() => { - console.info('Promise returned to indicate a successful setting of the audio parameter.'); +audioVolumeGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promised returned to indicate that the minimum volume is obtained ${value}.`); }); ``` -### getAudioParameter - -getAudioParameter(key: string, callback: AsyncCallback<string>): void +### getMaxVolume9+ -获取指定音频参数值,使用callback方式异步返回结果。 +getMaxVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 +获取指定流的最大音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------- | ---- | ---------------------------- | -| key | string | 是 | 待获取的音频参数的键。 | -| callback | AsyncCallback<string> | 是 | 回调返回获取的音频参数的值。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ---------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回最大音量大小。 | **示例:** ```js -audioManager.getAudioParameter('key_example', (err, value) => { +audioVolumeGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error(`Failed to obtain the value of the audio parameter. ${err}`); + console.error(`Failed to obtain the maximum volume. ${err}`); return; } - console.info(`Callback invoked to indicate that the value of the audio parameter is obtained ${value}.`); + console.info(`Callback invoked to indicate that the maximum volume is obtained. ${value}`); }); ``` -### getAudioParameter - -getAudioParameter(key: string): Promise<string> +### getMaxVolume9+ -获取指定音频参数值,使用Promise方式异步返回结果。 +getMaxVolume(volumeType: AudioVolumeType): Promise<number> -本接口的使用场景为根据硬件设备支持能力扩展音频配置。在不同的设备平台上,所支持的音频参数会存在差异。示例代码内使用样例参数,实际支持的音频配置参数见具体设备平台的资料描述。 +获取指定流的最大音量,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ------ | ---- | ---------------------- | -| key | string | 是 | 待获取的音频参数的键。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| --------------------- | ----------------------------------- | -| Promise<string> | Promise回调返回获取的音频参数的值。 | +| 类型 | 说明 | +| --------------------- | ----------------------------- | +| Promise<number> | Promise回调返回最大音量大小。 | **示例:** ```js -audioManager.getAudioParameter('key_example').then((value) => { - console.info(`Promise returned to indicate that the value of the audio parameter is obtained ${value}.`); +audioVolumeGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA).then((data) => { + console.info('Promised returned to indicate that the maximum volume is obtained.'); }); ``` -### getDevices +### mute9+ -getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void +mute(volumeType: AudioVolumeType, mute: boolean, callback: AsyncCallback<void>): void -获取音频设备列表,使用callback方式异步返回结果。 +设置指定音量流静音,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 + +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------------------------------ | ---- | -------------------- | -| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | -| callback | AsyncCallback<[AudioDeviceDescriptors](#audiodevicedescriptors)> | 是 | 回调,返回设备列表。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | +| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | **示例:** + ```js -audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (err, value) => { +audioVolumeGroupManager.mute(audio.AudioVolumeType.MEDIA, true, (err) => { if (err) { - console.error(`Failed to obtain the device list. ${err}`); + console.error(`Failed to mute the stream. ${err}`); return; } - console.info('Callback invoked to indicate that the device list is obtained.'); + console.info('Callback invoked to indicate that the stream is muted.'); }); ``` -### getDevices +### mute9+ + +mute(volumeType: AudioVolumeType, mute: boolean): Promise<void> -getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors> +设置指定音量流静音,使用Promise方式异步返回结果。 -获取音频设备列表,使用Promise方式异步返回结果。 +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -**系统能力:** SystemCapability.Multimedia.Audio.Device +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 + +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------- | ---- | ---------------- | -| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | **返回值:** -| 类型 | 说明 | -| ------------------------------------------------------------ | ------------------------- | -| Promise<[AudioDeviceDescriptors](#audiodevicedescriptors)> | Promise回调返回设备列表。 | +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | Promise回调表示成功还是失败。 | **示例:** ```js -audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { - console.info('Promise returned to indicate that the device list is obtained.'); +audioVolumeGroupManager.mute(audio.AudioVolumeType.MEDIA, true).then(() => { + console.info('Promise returned to indicate that the stream is muted.'); }); ``` -### setDeviceActive +### isMute9+ -setDeviceActive(deviceType: ActiveDeviceType, active: boolean, callback: AsyncCallback<void>): void +isMute(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void -设置设备激活状态,使用callback方式异步返回结果。 +获取指定音量流是否被静音,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------- | ---- | ------------------------ | -| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | -| active | boolean | 是 | 设备激活状态。 | -| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ----------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回流静音状态,true为静音,false为非静音。 | **示例:** ```js -audioManager.setDeviceActive(audio.ActiveDeviceType.SPEAKER, true, (err) => { +audioVolumeGroupManager.isMute(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error(`Failed to set the active status of the device. ${err}`); + console.error(`Failed to obtain the mute status. ${err}`); return; } - console.info('Callback invoked to indicate that the device is set to the active status.'); + console.info(`Callback invoked to indicate that the mute status of the stream is obtained ${value}.`); }); ``` -### setDeviceActive +### isMute9+ -setDeviceActive(deviceType: ActiveDeviceType, active: boolean): Promise<void> +isMute(volumeType: AudioVolumeType): Promise<boolean> -设置设备激活状态,使用Promise方式异步返回结果。 +获取指定音量流是否被静音,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------- | ---- | ------------------ | -| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | -| active | boolean | 是 | 设备激活状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ------------------------------- | -| Promise<void> | Promise回调返回设置成功或失败。 | +| 类型 | 说明 | +| ---------------------- | ------------------------------------------------------ | +| Promise<boolean> | Promise回调返回流静音状态,true为静音,false为非静音。 | **示例:** - ```js -audioManager.setDeviceActive(audio.ActiveDeviceType.SPEAKER, true).then(() => { - console.info('Promise returned to indicate that the device is set to the active status.'); +audioVolumeGroupManager.isMute(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the mute status of the stream is obtained ${value}.`); }); ``` -### isDeviceActive +### setRingerMode9+ -isDeviceActive(deviceType: ActiveDeviceType, callback: AsyncCallback<boolean>): void +setRingerMode(mode: AudioRingMode, callback: AsyncCallback<void>): void -获取指定设备的激活状态,使用callback方式异步返回结果。 +设置铃声模式,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅在静音和非静音状态切换时需要该权限。 + +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------- | ---- | ------------------------ | -| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调返回设备的激活状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------- | ---- | ------------------------ | +| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** ```js -audioManager.isDeviceActive(audio.ActiveDeviceType.SPEAKER, (err, value) => { +audioVolumeGroupManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL, (err) => { if (err) { - console.error(`Failed to obtain the active status of the device. ${err}`); + console.error(`Failed to set the ringer mode.​ ${err}`); return; } - console.info('Callback invoked to indicate that the active status of the device is obtained.'); + console.info('Callback invoked to indicate a successful setting of the ringer mode.'); }); ``` +### setRingerMode9+ -### isDeviceActive +setRingerMode(mode: AudioRingMode): Promise<void> -isDeviceActive(deviceType: ActiveDeviceType): Promise<boolean> +设置铃声模式,使用Promise方式异步返回结果。 -获取指定设备的激活状态,使用Promise方式异步返回结果。 +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -**系统能力:** SystemCapability.Multimedia.Audio.Device +仅在静音和非静音状态切换时需要该权限。 + +**系统接口:** 该接口为系统接口 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------- | ---- | ------------------ | -| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------------------------------- | ---- | -------------- | +| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | **返回值:** -| Type | Description | -| ---------------------- | ------------------------------- | -| Promise<boolean> | Promise回调返回设备的激活状态。 | +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | **示例:** ```js -audioManager.isDeviceActive(audio.ActiveDeviceType.SPEAKER).then((value) => { - console.info(`Promise returned to indicate that the active status of the device is obtained ${value}.`); +audioVolumeGroupManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL).then(() => { + console.info('Promise returned to indicate a successful setting of the ringer mode.'); +}); +``` + +### getRingerMode9+ + +getRingerMode(callback: AsyncCallback<AudioRingMode>): void + +获取铃声模式,使用callback方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------------------- | ---- | ------------------------ | +| callback | AsyncCallback<[AudioRingMode](#audioringmode)> | 是 | 回调返回系统的铃声模式。 | + +**示例:** + +```js +audioVolumeGroupManager.getRingerMode((err, value) => { + if (err) { + console.error(`Failed to obtain the ringer mode.​ ${err}`); + return; + } + console.info(`Callback invoked to indicate that the ringer mode is obtained ${value}.`); +}); +``` + +### getRingerMode9+ + +getRingerMode(): Promise<AudioRingMode> + +获取铃声模式,使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**返回值:** + +| 类型 | 说明 | +| ---------------------------------------------- | ------------------------------- | +| Promise<[AudioRingMode](#audioringmode)> | Promise回调返回系统的铃声模式。 | + +**示例:** + +```js +audioVolumeGroupManager.getRingerMode().then((value) => { + console.info(`Promise returned to indicate that the ringer mode is obtained ${value}.`); }); ``` -### setMicrophoneMute +### on('ringerModeChange')9+ + +on(type: 'ringerModeChange', callback: Callback\): void + +监听铃声模式变化事件。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'ringerModeChange'(铃声模式变化事件,检测到铃声模式改变时,触发该事件)。 | +| callback | Callback<[AudioRingMode](#audioringmode)> | 是 | 回调方法。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | + +**示例:** + +```js +audioVolumeGroupManager.on('ringerModeChange', (ringerMode) => { + console.info(`Updated ringermode: ${ringerMode}`); +}); +``` +### setMicrophoneMute9+ setMicrophoneMute(mute: boolean, callback: AsyncCallback<void>): void 设置麦克风静音状态,使用callback方式异步返回结果。 -**需要权限:** ohos.permission.MICROPHONE +**需要权限:** ohos.permission.MANAGE_AUDIO_CONFIG -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** @@ -1705,7 +1791,7 @@ setMicrophoneMute(mute: boolean, callback: AsyncCallback<void>): void **示例:** ```js -audioManager.setMicrophoneMute(true, (err) => { +audioVolumeGroupManager.setMicrophoneMute(true, (err) => { if (err) { console.error(`Failed to mute the microphone. ${err}`); return; @@ -1714,15 +1800,15 @@ audioManager.setMicrophoneMute(true, (err) => { }); ``` -### setMicrophoneMute +### setMicrophoneMute9+ setMicrophoneMute(mute: boolean): Promise<void> 设置麦克风静音状态,使用Promise方式异步返回结果。 -**需要权限:** ohos.permission.MICROPHONE +**需要权限:** ohos.permission.MANAGE_AUDIO_CONFIG -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** @@ -1739,20 +1825,18 @@ setMicrophoneMute(mute: boolean): Promise<void> **示例:** ```js -audioManager.setMicrophoneMute(true).then(() => { +audioVolumeGroupManager.setMicrophoneMute(true).then(() => { console.info('Promise returned to indicate that the microphone is muted.'); }); ``` -### isMicrophoneMute +### isMicrophoneMute9+ isMicrophoneMute(callback: AsyncCallback<boolean>): void 获取麦克风静音状态,使用callback方式异步返回结果。 -**需要权限:** ohos.permission.MICROPHONE - -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** @@ -1763,7 +1847,7 @@ isMicrophoneMute(callback: AsyncCallback<boolean>): void **示例:** ```js -audioManager.isMicrophoneMute((err, value) => { +audioVolumeGroupManager.isMicrophoneMute((err, value) => { if (err) { console.error(`Failed to obtain the mute status of the microphone. ${err}`); return; @@ -1772,15 +1856,13 @@ audioManager.isMicrophoneMute((err, value) => { }); ``` -### isMicrophoneMute +### isMicrophoneMute9+ isMicrophoneMute(): Promise<boolean> 获取麦克风静音状态,使用Promise方式异步返回结果。 -**需要权限:** ohos.permission.MICROPHONE - -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Volume **返回值:** @@ -1790,20 +1872,17 @@ isMicrophoneMute(): Promise<boolean> **示例:** - ```js -audioManager.isMicrophoneMute().then((value) => { +audioVolumeGroupManager.isMicrophoneMute().then((value) => { console.info(`Promise returned to indicate that the mute status of the microphone is obtained ${value}.`); }); ``` -### on('volumeChange')8+ - -on(type: 'volumeChange', callback: Callback\): void +### on('micStateChange')9+ -监听系统音量变化事件。 +on(type: 'micStateChange', callback: Callback<MicStateChangeEvent>): void -**系统接口:** 该接口为系统接口 +监听系统麦克风状态更改事件。 目前此订阅接口在单进程多AudioManager实例的使用场景下,仅最后一个实例的订阅生效,其他实例的订阅会被覆盖(即使最后一个实例没有进行订阅),因此推荐使用单一AudioManager实例进行开发。 @@ -1813,3675 +1892,4120 @@ on(type: 'volumeChange', callback: Callback\): void | 参数名 | 类型 | 必填 | 说明 | | -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'volumeChange'(系统音量变化事件,检测到系统音量改变时,触发该事件)。 | -| callback | Callback<[VolumeEvent](#volumeevent8)> | 是 | 回调方法。 | - -**示例:** - -```js -audioManager.on('volumeChange', (volumeEvent) => { - console.info(`VolumeType of stream: ${volumeEvent.volumeType} `); - console.info(`Volume level: ${volumeEvent.volume} `); - console.info(`Whether to updateUI: ${volumeEvent.updateUi} `); -}); -``` - -### on('ringerModeChange')8+ - -on(type: 'ringerModeChange', callback: Callback\): void - -监听铃声模式变化事件。 - -**系统接口:** 该接口为系统接口 +| type | string | 是 | 事件回调类型,支持的事件为:'micStateChange'(系统麦克风状态变化事件,检测到系统麦克风状态改变时,触发该事件)。 | +| callback | Callback<[MicStateChangeEvent](#micstatechangeevent9)> | 是 | 回调方法,返回变更后的麦克风状态。 | -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**错误码:** -**参数:** +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'ringerModeChange'(铃声模式变化事件,检测到铃声模式改变时,触发该事件)。 | -| callback | Callback<[AudioRingMode](#audioringmode)> | 是 | 回调方法。 | +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -audioManager.on('ringerModeChange', (ringerMode) => { - console.info(`Updated ringermode: ${ringerMode}`); +audioVolumeGroupManager.on('micStateChange', (micStateChange) => { + console.info(`Current microphone status is: ${micStateChange.mute} `); }); ``` -### on('deviceChange') +## AudioStreamManager9+ -on(type: 'deviceChange', callback: Callback): void +管理音频流。在使用AudioStreamManager的API前,需要使用[getStreamManager](#getstreammanager9)获取AudioStreamManager实例。 -设备更改。音频设备连接状态变化。 +### getCurrentAudioRendererInfoArray9+ -**系统能力:** SystemCapability.Multimedia.Audio.Device +getCurrentAudioRendererInfoArray(callback: AsyncCallback<AudioRendererChangeInfoArray>): void + +获取当前音频渲染器的信息。使用callback异步回调。 + +**系统能力**: SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------------------------------------- | :--- | :----------------------------------------- | -| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | -| callback | Callback<[DeviceChangeAction](#devicechangeaction)\> | 是 | 获取设备更新详情。 | +| 名称 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------- | -------- | --------------------------- | +| callback | AsyncCallback<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | 是 | 回调函数,返回当前音频渲染器的信息。 | **示例:** ```js -audioManager.on('deviceChange', (deviceChanged) => { - console.info(`device change type : ${deviceChanged.type} `); - console.info(`device descriptor size : ${deviceChanged.deviceDescriptors.length} `); - console.info(`device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceRole} `); - console.info(`device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceType} `); +audioStreamManager.getCurrentAudioRendererInfoArray(async (err, AudioRendererChangeInfoArray) => { + console.info('getCurrentAudioRendererInfoArray **** Get Callback Called ****'); + if (err) { + console.error(`getCurrentAudioRendererInfoArray :ERROR: ${err}`); + } else { + if (AudioRendererChangeInfoArray != null) { + for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { + let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; + console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); + console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); + console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); + console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); + console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); + console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); + for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); + } + } + } + } }); ``` -### off('deviceChange') +### getCurrentAudioRendererInfoArray9+ -off(type: 'deviceChange', callback?: Callback): void +getCurrentAudioRendererInfoArray(): Promise<AudioRendererChangeInfoArray> -取消订阅音频设备连接变化事件。 +获取当前音频渲染器的信息。使用Promise异步回调。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------------------------------- | ---- | ------------------------------------------ | -| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | -| callback | Callback<[DeviceChangeAction](#devicechangeaction)> | 否 | 获取设备更新详情。 | +| 类型 | 说明 | +| ---------------------------------------------------------------------------------| --------------------------------------- | +| Promise<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | Promise对象,返回当前音频渲染器信息。 | **示例:** ```js -audioManager.off('deviceChange', (deviceChanged) => { - console.info('Should be no callback.'); -}); +async function getCurrentAudioRendererInfoArray(){ + await audioStreamManager.getCurrentAudioRendererInfoArray().then( function (AudioRendererChangeInfoArray) { + console.info(`getCurrentAudioRendererInfoArray ######### Get Promise is called ##########`); + if (AudioRendererChangeInfoArray != null) { + for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { + let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; + console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); + console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); + console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); + console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); + console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); + console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); + for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); + } + } + } + }).catch((err) => { + console.error(`getCurrentAudioRendererInfoArray :ERROR: ${err}`); + }); +} ``` -### on('interrupt') +### getCurrentAudioCapturerInfoArray9+ -on(type: 'interrupt', interrupt: AudioInterrupt, callback: Callback\): void +getCurrentAudioCapturerInfoArray(callback: AsyncCallback<AudioCapturerChangeInfoArray>): void -请求焦点并开始监听音频打断事件(当应用程序的音频被另一个播放事件中断,回调通知此应用程序) +获取当前音频采集器的信息。使用callback异步回调。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| --------- | --------------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 音频打断事件回调类型,支持的事件为:'interrupt'(多应用之间第二个应用会打断第一个应用,触发该事件)。 | -| interrupt | AudioInterrupt | 是 | 音频打断事件类型的参数。 | -| callback | Callback<[InterruptAction](#interruptaction)> | 是 | 音频打断事件回调方法。 | +| 名称 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | --------- | -------------------------------------------------------- | +| callback | AsyncCallback<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | 是 | 回调函数,返回当前音频采集器的信息。 | **示例:** ```js -let interAudioInterrupt = { - streamUsage:2, - contentType:0, - pauseWhenDucked:true -}; -audioManager.on('interrupt', interAudioInterrupt, (InterruptAction) => { - if (InterruptAction.actionType === 0) { - console.info('An event to gain the audio focus starts.'); - console.info(`Focus gain event: ${InterruptAction} `); - } - if (InterruptAction.actionType === 1) { - console.info('An audio interruption event starts.'); - console.info(`Audio interruption event: ${InterruptAction} `); +audioStreamManager.getCurrentAudioCapturerInfoArray(async (err, AudioCapturerChangeInfoArray) => { + console.info('getCurrentAudioCapturerInfoArray **** Get Callback Called ****'); + if (err) { + console.error(`getCurrentAudioCapturerInfoArray :ERROR: ${err}`); + } else { + if (AudioCapturerChangeInfoArray != null) { + for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { + console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); + console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); + console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); + console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); + console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); + for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); + } + } + } } }); ``` -### off('interrupt') +### getCurrentAudioCapturerInfoArray9+ -off(type: 'interrupt', interrupt: AudioInterrupt, callback?: Callback\): void +getCurrentAudioCapturerInfoArray(): Promise<AudioCapturerChangeInfoArray> -取消监听音频打断事件(删除监听事件,取消打断) +获取当前音频采集器的信息。使用Promise异步回调。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| --------- | --------------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 音频打断事件回调类型,支持的事件为:'interrupt'(多应用之间第二个应用会打断第一个应用,触发该事件)。 | -| interrupt | AudioInterrupt | 是 | 音频打断事件类型的参数。 | -| callback | Callback<[InterruptAction](#interruptaction)> | 否 | 音频打断事件回调方法。 | +| 类型 | 说明 | +| -----------------------------------------------------------------------------| ----------------------------------- | +| Promise<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | Promise对象,返回当前音频渲染器信息。 | **示例:** ```js -let interAudioInterrupt = { - streamUsage:2, - contentType:0, - pauseWhenDucked:true -}; -audioManager.off('interrupt', interAudioInterrupt, (InterruptAction) => { - if (InterruptAction.actionType === 0) { - console.info('An event to release the audio focus starts.'); - console.info(`Focus release event: ${InterruptAction} `); - } -}); +async function getCurrentAudioCapturerInfoArray(){ + await audioStreamManager.getCurrentAudioCapturerInfoArray().then( function (AudioCapturerChangeInfoArray) { + console.info('getCurrentAudioCapturerInfoArray **** Get Promise Called ****'); + if (AudioCapturerChangeInfoArray != null) { + for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { + console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); + console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); + console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); + console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); + console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); + for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); + } + } + } + }).catch((err) => { + console.error(`getCurrentAudioCapturerInfoArray :ERROR: ${err}`); + }); +} ``` -### setAudioScene8+ - -setAudioScene\(scene: AudioScene, callback: AsyncCallback\): void +### on('audioRendererChange')9+ -设置音频场景模式,使用callback方式异步返回结果。 +on(type: "audioRendererChange", callback: Callback<AudioRendererChangeInfoArray>): void -**系统接口:** 该接口为系统接口 +监听音频渲染器更改事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :----------------------------------- | :--- | :------------------- | -| scene | AudioScene | 是 | 音频场景模式。 | -| callback | AsyncCallback | 是 | 用于返回结果的回调。 | +| 名称 | 类型 | 必填 | 说明 | +| -------- | ---------- | --------- | ------------------------------------------------------------------------ | +| type | string | 是 | 事件类型,支持的事件`'audioRendererChange'`:当音频渲染器发生更改时触发。 | +| callback | Callback<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | 是 | 回调函数。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.setAudioScene(audio.AudioScene.AUDIO_SCENE_PHONE_CALL, (err) => { - if (err) { - console.error(`Failed to set the audio scene mode.​ ${err}`); - return; +audioStreamManager.on('audioRendererChange', (AudioRendererChangeInfoArray) => { + for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { + let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; + console.info(`## RendererChange on is called for ${i} ##`); + console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); + console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); + console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); + console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); + console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); + console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); + for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); + } } - console.info('Callback invoked to indicate a successful setting of the audio scene mode.'); }); ``` -### setAudioScene8+ - -setAudioScene\(scene: AudioScene\): Promise +### off('audioRendererChange')9+ -设置音频场景模式,使用Promise方式返回异步结果。 +off(type: "audioRendererChange"): void -**系统接口:** 该接口为系统接口 +取消监听音频渲染器更改事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :----- | :----------------------------------- | :--- | :------------- | -| scene | AudioScene | 是 | 音频场景模式。 | +| 名称 | 类型 | 必填 | 说明 | +| -------- | ------- | ---- | ---------------- | +| type | string | 是 | 事件类型,支持的事件`'audioRendererChange'`:音频渲染器更改事件。 | -**返回值:** +**错误码:** -| 类型 | 说明 | -| :------------- | :------------------- | -| Promise | 用于返回结果的回调。 | +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.setAudioScene(audio.AudioScene.AUDIO_SCENE_PHONE_CALL).then(() => { - console.info('Promise returned to indicate a successful setting of the audio scene mode.'); -}).catch ((err) => { - console.error(`Failed to set the audio scene mode ${err}`); -}); +audioStreamManager.off('audioRendererChange'); +console.info('######### RendererChange Off is called #########'); ``` -### getAudioScene8+ +### on('audioCapturerChange')9+ -getAudioScene\(callback: AsyncCallback\): void +on(type: "audioCapturerChange", callback: Callback<AudioCapturerChangeInfoArray>): void -获取音频场景模式,使用callback方式返回异步结果。 +监听音频采集器更改事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :-------------------------------------------------- | :--- | :--------------------------- | -| callback | AsyncCallback<AudioScene> | 是 | 用于返回音频场景模式的回调。 | +| 名称 | 类型 | 必填 | 说明 | +| -------- | ------- | --------- | ----------------------------------------------------------------------- | +| type | string | 是 | 事件类型,支持的事件`'audioCapturerChange'`:当音频采集器发生更改时触发。 | +| callback | Callback<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | 是 | 回调函数。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getAudioScene((err, value) => { - if (err) { - console.error(`Failed to obtain the audio scene mode.​ ${err}`); - return; +audioStreamManager.on('audioCapturerChange', (AudioCapturerChangeInfoArray) => { + for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { + console.info(`## CapChange on is called for element ${i} ##`); + console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); + console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); + console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); + console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); + console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); + let devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors; + for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); + console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); + console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); + console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); + console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); + } } - console.info(`Callback invoked to indicate that the audio scene mode is obtained ${value}.`); }); ``` +### off('audioCapturerChange')9+ -### getAudioScene8+ - -getAudioScene\(\): Promise +off(type: "audioCapturerChange"): void; -获取音频场景模式,使用Promise方式返回异步结果。 +取消监听音频采集器更改事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Communication +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -**返回值:** +**参数:** -| 类型 | 说明 | -| :-------------------------------------------- | :--------------------------- | -| Promise<AudioScene> | 用于返回音频场景模式的回调。 | +| 名称 | 类型 | 必填 | 说明 | +| -------- | -------- | --- | ------------------------------------------------------------- | +| type | string |是 | 事件类型,支持的事件`'audioCapturerChange'`:音频采集器更改事件。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getAudioScene().then((value) => { - console.info(`Promise returned to indicate that the audio scene mode is obtained ${value}.`); -}).catch ((err) => { - console.error(`Failed to obtain the audio scene mode ${err}`); -}); -``` +audioStreamManager.off('audioCapturerChange'); +console.info('######### CapturerChange Off is called #########'); -### getVolumeGroups9+ +``` -getVolumeGroups(networkId: string, callback: AsyncCallback\): void +### isActive9+ -获取音量组信息列表,使用callback方式异步返回结果。 +isActive(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void -**系统接口:** 该接口为系统接口 +获取指定音量流是否为活跃状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------------------------------ | ---- | -------------------- | -| networkId | string | 是 | 设备的网络id。本地设备audio.LOCAL_NETWORK_ID ,也可以通过getRoutingManager().getDevices()获取全部networkId。 | -| callback | AsyncCallback<[VolumeGroupInfos](#volumegroupinfos9)> | 是 | 回调,返回音量组信息列表。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回流的活跃状态,true为活跃,false为不活跃。 | **示例:** + ```js -let audioManager = audio.getAudioManager(); -audioManager.getVolumeGroups(audio.LOCAL_NETWORK_ID, (err, value) => { +audioStreamManager.isActive(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error(`Failed to obtain the volume group infos list. ${err}`); + console.error(`Failed to obtain the active status of the stream. ${err}`); return; } - console.info('Callback invoked to indicate that the volume group infos list is obtained.'); + console.info(`Callback invoked to indicate that the active status of the stream is obtained ${value}.`); }); ``` -### getVolumeGroups9+ - -getVolumeGroups(networkId: string\): Promise +### isActive9+ -获取音量组信息列表,使用promise方式异步返回结果。 +isActive(volumeType: AudioVolumeType): Promise<boolean> -**系统接口:** 该接口为系统接口 +获取指定音量流是否为活跃状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------------------------------ | ---- | -------------------- | -| networkId | string | 是 | 设备的网络id。本地设备audio.LOCAL_NETWORK_ID ,也可以通过getRoutingManager().getDevices()获取全部networkId。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise<[VolumeGroupInfos](#volumegroupinfos9)> | 音量组信息列表。 | +| 类型 | 说明 | +| ---------------------- | -------------------------------------------------------- | +| Promise<boolean> | Promise回调返回流的活跃状态,true为活跃,false为不活跃。 | **示例:** ```js -async function getVolumeGroupInfos(){ - let volumegroupinfos = await audio.getAudioManager().getVolumeGroups(audio.LOCAL_NETWORK_ID); - console.info('Promise returned to indicate that the volumeGroup list is obtained.'+JSON.stringify(volumegroupinfos)) -} +audioStreamManager.isActive(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the active status of the stream is obtained ${value}.`); +}); ``` -### getGroupManager9+ +## AudioRoutingManager9+ -getGroupManager(groupId: number, callback: AsyncCallback\): void +音频路由管理。在使用AudioRoutingManager的接口前,需要使用[getRoutingManager](#getroutingmanager9)获取AudioRoutingManager实例。 -获取音频组管理器,使用callback方式异步返回结果。 +### getDevices9+ -**系统接口:** 该接口为系统接口 +getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void -**系统能力:** SystemCapability.Multimedia.Audio.Volume +获取音频设备列表,使用callback方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** | 参数名 | 类型 | 必填 | 说明 | | ---------- | ------------------------------------------------------------ | ---- | -------------------- | -| groupId | number | 是 | 音量组id。 | -| callback | AsyncCallback< [AudioGroupManager](#audiogroupmanager9) > | 是 | 回调,返回一个音量组实例。 | +| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | +| callback | AsyncCallback<[AudioDeviceDescriptors](#audiodevicedescriptors)> | 是 | 回调,返回设备列表。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -let audioGroupManager; -async function getGroupManager(){ - let value = await audioManager.getVolumeGroups(audio.LOCAL_NETWORK_ID); - if (value.length > 0) { - let groupid = value[0].groupId; - audioManager.getGroupManager(groupid, (err, value) => { - if (err) { - console.error(`Failed to obtain the volume group infos list. ${err}`); - return; - } - audioGroupManager = value - console.info('Callback invoked to indicate that the volume group infos list is obtained.'); - }); +audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (err, value) => { + if (err) { + console.error(`Failed to obtain the device list. ${err}`); + return; } -} + console.info('Callback invoked to indicate that the device list is obtained.'); +}); ``` -### getGroupManager9+ - -getGroupManager(groupId: number\): Promise +### getDevices9+ -获取音频组管理器,使用promise方式异步返回结果。 +getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors> -**系统接口:** 该接口为系统接口 +获取音频设备列表,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ---------------------------------------- | ---- | ---------------- | -| groupId | number | 是 | 音量组id。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------- | ---- | ---------------- | +| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise< [AudioGroupManager](#audiogroupmanager9) > | 音量组实例。 | +| 类型 | 说明 | +| ------------------------------------------------------------ | ------------------------- | +| Promise<[AudioDeviceDescriptors](#audiodevicedescriptors)> | Promise回调返回设备列表。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -async function getGroupManager(){ - let value = await audioManager.getVolumeGroups(audio.LOCAL_NETWORK_ID); - if (value.length > 0) { - let groupid = value[0].groupId; - let audioGroupManager = await audioManager.getGroupManager(groupid) - console.info('Callback invoked to indicate that the volume group infos list is obtained.'); - } -} +audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { + console.info('Promise returned to indicate that the device list is obtained.'); +}); ``` -### getStreamManager9+ +### on9+ -getStreamManager(callback: AsyncCallback\): void +on(type: 'deviceChange', deviceFlag: DeviceFlag, callback: Callback): void -获取音频流管理器实例。使用callback方式异步返回结果。 +设备更改。音频设备连接状态变化。 -**系统能力:** SystemCapability.Multimedia.Audio.Core +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------------------------------------- | ---- | ---------------- | -| callback | AsyncCallback<[AudioStreamManager](#audiostreammanager9)> | 是 | 返回音频流管理器实例。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :----------------------------------------- | +| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | +| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | +| callback | Callback<[DeviceChangeAction](#devicechangeaction)\> | 是 | 获取设备更新详情。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -let audioManager = audio.getAudioManager(); -let audioStreamManager; -audioManager.getStreamManager((err, data) => { - if (err) { - console.error(`getStreamManager : Error: ${err}`); - } else { - console.info('getStreamManager : Success : SUCCESS'); - audioStreamManager = data; - } +audioRoutingManager.on('deviceChange', audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (deviceChanged) => { + console.info('device change type : ' + deviceChanged.type); + console.info('device descriptor size : ' + deviceChanged.deviceDescriptors.length); + console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceRole); + console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceType); }); ``` -### getStreamManager9+ +### off9+ + +off(type: 'deviceChange', callback?: Callback): void -getStreamManager(): Promise +取消订阅音频设备连接变化事件。 -获取音频流管理器实例。使用Promise方式异步返回结果。 +**系统能力:** SystemCapability.Multimedia.Audio.Device -**系统能力:** SystemCapability.Multimedia.Audio.Core +**参数:** -**返回值:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------------------------- | ---- | ------------------------------------------ | +| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | +| callback | Callback<[DeviceChangeAction](#devicechangeaction)> | 否 | 获取设备更新详情。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 -| 类型 | 说明 | -| ---------------------------------------------------- | ---------------- | -| Promise<[AudioStreamManager](#audiostreammanager9)> | 返回音频流管理器实例。 | +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | **示例:** ```js -let audioManager = audio.getAudioManager(); -let audioStreamManager; -audioManager.getStreamManager().then((data) => { - audioStreamManager = data; - console.info('getStreamManager: Success!'); -}).catch((err) => { - console.error(`getStreamManager: ERROR : ${err}`); +audioRoutingManager.off('deviceChange', (deviceChanged) => { + console.info('Should be no callback.'); }); - ``` -### requestIndependentInterrupt9+ +### selectInputDevice9+ -requestIndependentInterrupt(focusType: FocusType, callback: AsyncCallback\): void +selectInputDevice(inputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void -申请独立焦点,获取独立SessionID,使用callback方式异步返回结果。 +选择音频输入设备,当前只能选择一个输入设备,使用callback方式异步返回结果。 **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------------------------- | ---- | ----------------- | -| focusType | [FocusType](#focustype) | 是 | 焦点类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调,返回焦点申请成功/失败状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | +| inputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输入设备类。 | +| callback | AsyncCallback<void> | 是 | 回调,返回选择输入设备结果。 | **示例:** - ```js -async function requestIndependentInterrupt(){ - let value = await audioManager.requestIndependentInterrupt(audio.FocusType.FOCUS_TYPE_RECORDING); - if (value) { - console.info('requestIndependentInterrupt interface for result callback: SUCCESS'); - } else { - console.error('Result ERROR'); - } +let inputAudioDeviceDescriptor = [{ + "deviceRole":audio.DeviceRole.INPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; + +async function selectInputDevice(){ + audioRoutingManager.selectInputDevice(inputAudioDeviceDescriptor, (err) => { + if (err) { + console.error(`Result ERROR: ${err}`); + } else { + console.info('Select input devices result callback: SUCCESS'); } + }); } ``` -### requestIndependentInterrupt9+ -requestIndependentInterrupt(focusType: FocusType): Promise +### selectInputDevice9+ -申请独立焦点,获取独立SessionID,使用promise方式异步返回结果。 +selectInputDevice(inputAudioDevices: AudioDeviceDescriptors): Promise<void> **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +选择音频输入设备,当前只能选择一个输入设备,使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ---- | ---- | ---- | -| focusType | [FocusType](#focustype) | 是 | 焦点类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | +| inputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输入设备类。 | **返回值:** -| 类型 | 说明 | -| --------------------------------------------------------- | ------------ | -| Promise<boolean> | 返回申请焦点成功/失败状态。 | +| 类型 | 说明 | +| --------------------- | --------------------------- | +| Promise<void> | Promise返回选择输入设备结果。 | **示例:** ```js -async function requestIndependentInterrupt(){ - audioManager.requestIndependentInterrupt(audio.FocusType.FOCUS_TYPE_RECORDING).then((value) => { - console.info('Promise returned to succeed '); - }).catch ((err) => { - console.error('Failed to requestIndependentInterrupt'); - }); +let inputAudioDeviceDescriptor =[{ + "deviceRole":audio.DeviceRole.INPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; + +async function getRoutingManager(){ + audioRoutingManager.selectInputDevice(inputAudioDeviceDescriptor).then(() => { + console.info('Select input devices result promise: SUCCESS'); + }).catch((err) => { + console.error(`Result ERROR: ${err}`); + }); } ``` -### abandonIndependentInterrupt9+ -abandonIndependentInterrupt(focusType: FocusType, callback: AsyncCallback\): void +### setCommunicationDevice9+ -废除独立焦点,使用callback方式异步返回结果。 +setCommunicationDevice(deviceType: CommunicationDeviceType, active: boolean, callback: AsyncCallback<void>): void -**系统接口:** 该接口为系统接口 +设置通信设备激活状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------------------------- | ---- | ----------------- | -| focusType | [FocusType](#focustype) | 是 | 焦点类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调,返回废除焦点成功/失败状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------- | ---- | ------------------------ | +| deviceType | [CommunicationDeviceType](#communicationdevicetype9) | 是 | 音频设备类型。 | +| active | boolean | 是 | 设备激活状态。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** ```js -async function abandonIndependentInterrupt(){ - let value = await audioManager.abandonIndependentInterrupt(audio.FocusType.FOCUS_TYPE_RECORDING); - if (value) { - console.info('abandonIndependentInterrupt interface for result callback: SUCCESS'); - } else { - console.error('Result ERROR'); +audioRoutingManager.setCommunicationDevice(audio.CommunicationDeviceType.SPEAKER, true, (err) => { + if (err) { + console.error(`Failed to set the active status of the device. ${err}`); + return; } -} + console.info('Callback invoked to indicate that the device is set to the active status.'); +}); ``` -### abandonIndependentInterrupt9+ -abandonIndependentInterrupt(focusType: FocusType): Promise +### setCommunicationDevice9+ -废除独立焦点,使用promise方式异步返回结果。 +setCommunicationDevice(deviceType: CommunicationDeviceType, active: boolean): Promise<void> -**系统接口:** 该接口为系统接口 +设置通信设备激活状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ---- | ---- | ---- | -| focusType | [FocusType](#focustype) | 是 | 焦点类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------------------------- | ---- | ------------------ | +| deviceType | [CommunicationDeviceType](#communicationdevicetype9) | 是 | 活跃音频设备类型。 | +| active | boolean | 是 | 设备激活状态。 | **返回值:** -| 类型 | 说明 | -| --------------------------------------------------------- | ------------ | -| Promise<boolean> | 返回废除焦点成功/失败状态。 | +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | **示例:** ```js -async function abandonIndependentInterrupt(){ - audioManager.abandonIndependentInterrupt(audio.FocusType.FOCUS_TYPE_RECORDING).then((value) => { - console.info('Promise returned to succeed'); - }).catch ((err) => { - console.error('Failed to abandonIndependentInterrupt'); - }); -} +audioRoutingManager.setCommunicationDevice(audio.CommunicationDeviceType.SPEAKER, true).then(() => { + console.info('Promise returned to indicate that the device is set to the active status.'); +}); ``` -## AudioGroupManager9+ -管理音频组音量。在调用AudioGroupManager的接口前,需要先通过 [getGroupManager](#getgroupmanager9) 创建实例。 - -**系统接口:** 该接口为系统接口 - -**系统能力:** SystemCapability.Multimedia.Audio.Volume - -### setVolume9+ - -setVolume(volumeType: AudioVolumeType, volume: number, callback: AsyncCallback<void>): void - -设置指定流的音量,使用callback方式异步返回结果。 -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +### isCommunicationDeviceActive9+ -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +isCommunicationDeviceActive(deviceType: CommunicationDeviceType, callback: AsyncCallback<boolean>): void -**系统接口:** 该接口为系统接口 +获取指定通信设备的激活状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | -| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ---------------------------------------------------- | ---- | ------------------------ | +| deviceType | [CommunicationDeviceType](#communicationdevicetype9) | 是 | 活跃音频设备类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回设备的激活状态。 | **示例:** ```js -audioGroupManager.setVolume(audio.AudioVolumeType.MEDIA, 10, (err) => { +audioRoutingManager.isCommunicationDeviceActive(audio.CommunicationDeviceType.SPEAKER, (err, value) => { if (err) { - console.error(`Failed to set the volume. ${err}`); + console.error(`Failed to obtain the active status of the device. ${err}`); return; } - console.info('Callback invoked to indicate a successful volume setting.'); + console.info('Callback invoked to indicate that the active status of the device is obtained.'); }); ``` -### setVolume9+ - -setVolume(volumeType: AudioVolumeType, volume: number): Promise<void> - -设置指定流的音量,使用Promise方式异步返回结果。 - -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +### isCommunicationDeviceActive9+ -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +isCommunicationDeviceActive(deviceType: CommunicationDeviceType): Promise<boolean> -**系统接口:** 该接口为系统接口 +获取指定通信设备的激活状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ---------------------------------------------------- | ---- | ------------------ | +| deviceType | [CommunicationDeviceType](#communicationdevicetype9) | 是 | 活跃音频设备类型。 | **返回值:** -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise<void> | Promise回调表示成功还是失败。 | +| Type | Description | +| ---------------------- | ------------------------------- | +| Promise<boolean> | Promise回调返回设备的激活状态。 | **示例:** ```js -audioGroupManager.setVolume(audio.AudioVolumeType.MEDIA, 10).then(() => { - console.info('Promise returned to indicate a successful volume setting.'); +audioRoutingManager.isCommunicationDeviceActive(audio.CommunicationDeviceType.SPEAKER).then((value) => { + console.info(`Promise returned to indicate that the active status of the device is obtained ${value}.`); }); ``` -### getVolume9+ +### selectOutputDevice9+ -getVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +selectOutputDevice(outputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void -获取指定流的音量,使用callback方式异步返回结果。 +选择音频输出设备,当前只能选择一个输出设备,使用callback方式异步返回结果。 **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回音量大小。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | +| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | +| callback | AsyncCallback<void> | 是 | 回调,返回获取输出设备结果。 | **示例:** - ```js -audioGroupManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`Failed to obtain the volume. ${err}`); - return; - } - console.info('Callback invoked to indicate that the volume is obtained.'); -}); +let outputAudioDeviceDescriptor = [{ + "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; +async function selectOutputDevice(){ + audioRoutingManager.selectOutputDevice(outputAudioDeviceDescriptor, (err) => { + if (err) { + console.error(`Result ERROR: ${err}`); + } else { + console.info('Select output devices result callback: SUCCESS'); } + }); +} ``` -### getVolume9+ - -getVolume(volumeType: AudioVolumeType): Promise<number> +### selectOutputDevice9+ -获取指定流的音量,使用Promise方式异步返回结果。 +selectOutputDevice(outputAudioDevices: AudioDeviceDescriptors): Promise<void> **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +选择音频输出设备,当前只能选择一个输出设备,使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | +| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | **返回值:** -| 类型 | 说明 | -| --------------------- | ------------------------- | -| Promise<number> | Promise回调返回音量大小。 | +| 类型 | 说明 | +| --------------------- | --------------------------- | +| Promise<void> | Promise返回选择输出设备结果。 | **示例:** ```js -audioGroupManager.getVolume(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promise returned to indicate that the volume is obtained ${value}.`); -}); -``` +let outputAudioDeviceDescriptor =[{ + "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; -### getMinVolume9+ +async function selectOutputDevice(){ + audioRoutingManager.selectOutputDevice(outputAudioDeviceDescriptor).then(() => { + console.info('Select output devices result promise: SUCCESS'); + }).catch((err) => { + console.error(`Result ERROR: ${err}`); + }); +} +``` -getMinVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +### selectOutputDeviceByFilter9+ -获取指定流的最小音量,使用callback方式异步返回结果。 +selectOutputDeviceByFilter(filter: AudioRendererFilter, outputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +根据过滤条件,选择音频输出设备,当前只能选择一个输出设备,使用callback方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回最小音量。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | +| filter | [AudioRendererFilter](#audiorendererfilter9) | 是 | 过滤条件类。 | +| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | +| callback | AsyncCallback<void> | 是 | 回调,返回获取输出设备结果。 | **示例:** - ```js -audioGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`Failed to obtain the minimum volume. ${err}`); - return; - } - console.info(`Callback invoked to indicate that the minimum volume is obtained. ${value}`); -}); -``` +let outputAudioRendererFilter = { + "uid":20010041, + "rendererInfo": { + "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, + "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, + "rendererFlags":0 }, + "rendererId":0 }; +let outputAudioDeviceDescriptor = [{ + "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; -### getMinVolume9+ +async function selectOutputDeviceByFilter(){ + audioRoutingManager.selectOutputDeviceByFilter(outputAudioRendererFilter, outputAudioDeviceDescriptor, (err) => { + if (err) { + console.error(`Result ERROR: ${err}`); + } else { + console.info('Select output devices by filter result callback: SUCCESS'); } + }); +} +``` -getMinVolume(volumeType: AudioVolumeType): Promise<number> +### selectOutputDeviceByFilter9+ -获取指定流的最小音量,使用Promise方式异步返回结果。 +selectOutputDeviceByFilter(filter: AudioRendererFilter, outputAudioDevices: AudioDeviceDescriptors): Promise<void> **系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +根据过滤条件,选择音频输出设备,当前只能选择一个输出设备,使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| 参数名 | 类型 | 必填 | 说明 | +| ----------------------| ------------------------------------------------------------ | ---- | ------------------------- | +| filter | [AudioRendererFilter](#audiorendererfilter9) | 是 | 过滤条件类。 | +| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | **返回值:** -| 类型 | 说明 | -| --------------------- | ------------------------- | -| Promise<number> | Promise回调返回最小音量。 | +| 类型 | 说明 | +| --------------------- | --------------------------- | +| Promise<void> | Promise返回选择输出设备结果。 | **示例:** ```js -audioGroupManager.getMinVolume(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promised returned to indicate that the minimum volume is obtained ${value}.`); -}); +let outputAudioRendererFilter = { + "uid":20010041, + "rendererInfo": { + "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, + "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, + "rendererFlags":0 }, + "rendererId":0 }; +let outputAudioDeviceDescriptor = [{ + "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, + "networkId":audio.LOCAL_NETWORK_ID, + "interruptGroupId":1, + "volumeGroupId":1 }]; + +async function selectOutputDeviceByFilter(){ + audioRoutingManager.selectOutputDeviceByFilter(outputAudioRendererFilter, outputAudioDeviceDescriptor).then(() => { + console.info('Select output devices by filter result promise: SUCCESS'); + }).catch((err) => { + console.error(`Result ERROR: ${err}`); + }) +} ``` -### getMaxVolume9+ +## AudioRendererChangeInfo9+ -getMaxVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void +描述音频渲染器更改信息。 -获取指定流的最大音量,使用callback方式异步返回结果。 +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer -**系统接口:** 该接口为系统接口 +| 名称 | 类型 | 可读 | 可写 | 说明 | +| -------------------| ----------------------------------------- | ---- | ---- | ---------------------------- | +| streamId | number | 是 | 否 | 音频流唯一id。 | +| clientUid | number | 是 | 否 | 音频渲染器客户端应用程序的Uid。
此接口为系统接口。 | +| rendererInfo | [AudioRendererInfo](#audiorendererinfo8) | 是 | 否 | 音频渲染器信息。 | +| rendererState | [AudioState](#audiostate) | 是 | 否 | 音频状态。
此接口为系统接口。| -**系统能力:** SystemCapability.Multimedia.Audio.Volume +## AudioRendererChangeInfoArray9+ -**参数:** +AudioRenderChangeInfo数组,只读。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ---------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<number> | 是 | 回调返回最大音量大小。 | +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **示例:** ```js -audioGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA, (err, value) => { +import audio from '@ohos.multimedia.audio'; + +let audioStreamManager; +let resultFlag = false; +let audioManager = audio.getAudioManager(); + +audioManager.getStreamManager((err, data) => { if (err) { - console.error(`Failed to obtain the maximum volume. ${err}`); - return; + console.error(`Get AudioStream Manager : ERROR : ${err}`); + } else { + audioStreamManager = data; + console.info('Get AudioStream Manager : Success'); } - console.info(`Callback invoked to indicate that the maximum volume is obtained. ${value}`); }); -``` -### getMaxVolume9+ - -getMaxVolume(volumeType: AudioVolumeType): Promise<number> +audioStreamManager.on('audioRendererChange', (AudioRendererChangeInfoArray) => { + for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { + console.info(`## RendererChange on is called for ${i} ##`); + console.info(`StreamId for ${i} is: ${AudioRendererChangeInfoArray[i].streamId}`); + console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfoArray[i].clientUid}`); + console.info(`Content for ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.content}`); + console.info(`Stream for ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.usage}`); + console.info(`Flag ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.rendererFlags}`); + console.info(`State for ${i} is: ${AudioRendererChangeInfoArray[i].rendererState}`); + let devDescriptor = AudioRendererChangeInfoArray[i].deviceDescriptors; + for (let j = 0; j < AudioRendererChangeInfoArray[i].deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].name}`); + console.info(`Addr: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].address}`); + console.info(`SR: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); + console.info(`C ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); + console.info(`CM: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); + } + if (AudioRendererChangeInfoArray[i].rendererState == 1 && devDescriptor != null) { + resultFlag = true; + console.info(`ResultFlag for ${i} is: ${resultFlag}`); + } + } +}); +``` -获取指定流的最大音量,使用Promise方式异步返回结果。 +## AudioCapturerChangeInfo9+ -**系统接口:** 该接口为系统接口 +描述音频采集器更改信息。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Capturer -**参数:** +| 名称 | 类型 | 可读 | 可写 | 说明 | +| -------------------| ----------------------------------------- | ---- | ---- | ---------------------------- | +| streamId | number | 是 | 否 | 音频流唯一id。 | +| clientUid | number | 是 | 否 | 音频采集器客户端应用程序的Uid。
此接口为系统接口。 | +| capturerInfo | [AudioCapturerInfo](#audiocapturerinfo8) | 是 | 否 | 音频采集器信息。 | +| capturerState | [AudioState](#audiostate) | 是 | 否 | 音频状态。
此接口为系统接口。| -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +## AudioCapturerChangeInfoArray9+ -**返回值:** +AudioCapturerChangeInfo数组,只读。 -| 类型 | 说明 | -| --------------------- | ----------------------------- | -| Promise<number> | Promise回调返回最大音量大小。 | +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **示例:** ```js -audioGroupManager.getMaxVolume(audio.AudioVolumeType.MEDIA).then((data) => { - console.info('Promised returned to indicate that the maximum volume is obtained.'); +import audio from '@ohos.multimedia.audio'; + +const audioManager = audio.getAudioManager(); +let audioStreamManager; +audioManager.getStreamManager((err, data) => { + if (err) { + console.error(`getStreamManager : Error: ${err}`); + } else { + console.info('getStreamManager : Success : SUCCESS'); + audioStreamManager = data; + } +}); + +let resultFlag = false; +audioStreamManager.on('audioCapturerChange', (AudioCapturerChangeInfoArray) => { + for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { + console.info(`## CapChange on is called for element ${i} ##`); + console.info(`StrId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); + console.info(`CUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); + console.info(`Src for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); + console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); + console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); + let devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors; + for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { + console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); + console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); + console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); + console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); + console.info(`Addr: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); + console.info(`SR: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); + console.info(`C ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); + console.info(`CM ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); + } + if (AudioCapturerChangeInfoArray[i].capturerState == 1 && devDescriptor != null) { + resultFlag = true; + console.info(`ResultFlag for element ${i} is: ${resultFlag}`); + } + } }); ``` -### mute9+ +## AudioDeviceDescriptor -mute(volumeType: AudioVolumeType, mute: boolean, callback: AsyncCallback<void>): void +描述音频设备。 -设置指定音量流静音,使用callback方式异步返回结果。 +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Device -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ----------------------------- | -------------------------- | ---- | ---- | ---------- | +| deviceRole | [DeviceRole](#devicerole) | 是 | 否 | 设备角色。 | +| deviceType | [DeviceType](#devicetype) | 是 | 否 | 设备类型。 | +| id9+ | number | 是 | 否 | 设备id。 | +| name9+ | string | 是 | 否 | 设备名称。 | +| address9+ | string | 是 | 否 | 设备地址。 | +| sampleRates9+ | Array<number> | 是 | 否 | 支持的采样率。 | +| channelCounts9+ | Array<number> | 是 | 否 | 支持的通道数。 | +| channelMasks9+ | Array<number> | 是 | 否 | 支持的通道掩码。 | +| networkId9+ | string | 是 | 否 | 设备组网的ID。
此接口为系统接口。 | +| interruptGroupId9+ | number | 是 | 否 | 设备所处的焦点组ID。
此接口为系统接口。 | +| volumeGroupId9+ | number | 是 | 否 | 设备所处的音量组ID。
此接口为系统接口。 | -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +## AudioDeviceDescriptors -**系统接口:** 该接口为系统接口 +设备属性数组类型,为[AudioDeviceDescriptor](#audiodevicedescriptor)的数组,只读。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**示例:** -**参数:** +```js +import audio from '@ohos.multimedia.audio'; -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | -| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | - -**示例:** +function displayDeviceProp(value) { + deviceRoleValue = value.deviceRole; + deviceTypeValue = value.deviceType; +} -```js -audioGroupManager.mute(audio.AudioVolumeType.MEDIA, true, (err) => { - if (err) { - console.error(`Failed to mute the stream. ${err}`); - return; +let deviceRoleValue = null; +let deviceTypeValue = null; +const promise = audio.getAudioManager().getDevices(1); +promise.then(function (value) { + console.info('AudioFrameworkTest: Promise: getDevices OUTPUT_DEVICES_FLAG'); + value.forEach(displayDeviceProp); + if (deviceTypeValue != null && deviceRoleValue != null){ + console.info('AudioFrameworkTest: Promise: getDevices : OUTPUT_DEVICES_FLAG : PASS'); + } else { + console.error('AudioFrameworkTest: Promise: getDevices : OUTPUT_DEVICES_FLAG : FAIL'); } - console.info('Callback invoked to indicate that the stream is muted.'); }); ``` -### mute9+ +## AudioRendererFilter9+ -mute(volumeType: AudioVolumeType, mute: boolean): Promise<void> +过滤条件类。在调用selectOutputDeviceByFilter接口前,需要先创建AudioRendererFilter实例。 -设置指定音量流静音,使用Promise方式异步返回结果。 +**系统接口:** 该接口为系统接口 -**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY +| 名称 | 类型 | 必填 | 说明 | +| -------------| ---------------------------------------- | ---- | -------------- | +| uid | number | 是 | 表示应用ID。
**系统能力:** SystemCapability.Multimedia.Audio.Core| +| rendererInfo | [AudioRendererInfo](#audiorendererinfo8) | 否 | 表示渲染器信息。
**系统能力:** SystemCapability.Multimedia.Audio.Renderer| +| rendererId | number | 否 | 音频流唯一id。
**系统能力:** SystemCapability.Multimedia.Audio.Renderer| -仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 +**示例:** -**系统接口:** 该接口为系统接口 +```js +let outputAudioRendererFilter = { + "uid":20010041, + "rendererInfo": { + "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, + "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, + "rendererFlags":0 }, + "rendererId":0 }; +``` -**系统能力:** SystemCapability.Multimedia.Audio.Volume +## AudioRenderer8+ -**参数:** +提供音频渲染的相关接口。在调用AudioRenderer的接口前,需要先通过[createAudioRenderer](#audiocreateaudiorenderer8)创建实例。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | +### 属性 -**返回值:** +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise<void> | Promise回调表示成功还是失败。 | +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ----- | -------------------------- | ---- | ---- | ------------------ | +| state8+ | [AudioState](#audiostate8) | 是 | 否 | 音频渲染器的状态。 | **示例:** ```js -audioGroupManager.mute(audio.AudioVolumeType.MEDIA, true).then(() => { - console.info('Promise returned to indicate that the stream is muted.'); -}); +let state = audioRenderer.state; ``` -### isMute9+ - -isMute(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void +### getRendererInfo8+ -获取指定音量流是否被静音,使用callback方式异步返回结果。 +getRendererInfo(callback: AsyncCallback): void -**系统接口:** 该接口为系统接口 +获取当前被创建的音频渲染器的信息,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Volume +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ----------------------------------------------- | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | -| callback | AsyncCallback<boolean> | 是 | 回调返回流静音状态,true为静音,false为非静音。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------------------------------------------- | :--- | :--------------------- | +| callback | AsyncCallback<[AudioRendererInfo](#audiorendererinfo8)\> | 是 | 返回音频渲染器的信息。 | **示例:** ```js -audioGroupManager.isMute(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`Failed to obtain the mute status. ${err}`); - return; - } - console.info(`Callback invoked to indicate that the mute status of the stream is obtained ${value}.`); +audioRenderer.getRendererInfo((err, rendererInfo) => { + console.info('Renderer GetRendererInfo:'); + console.info(`Renderer content: ${rendererInfo.content}`); + console.info(`Renderer usage: ${rendererInfo.usage}`); + console.info(`Renderer flags: ${rendererInfo.rendererFlags}`); }); ``` -### isMute9+ - -isMute(volumeType: AudioVolumeType): Promise<boolean> - -获取指定音量流是否被静音,使用Promise方式异步返回结果。 - -**系统接口:** 该接口为系统接口 +### getRendererInfo8+ -**系统能力:** SystemCapability.Multimedia.Audio.Volume +getRendererInfo(): Promise -**参数:** +获取当前被创建的音频渲染器的信息,使用Promise方式异步返回结果。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | ---- | ------------ | -| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **返回值:** -| 类型 | 说明 | -| ---------------------- | ------------------------------------------------------ | -| Promise<boolean> | Promise回调返回流静音状态,true为静音,false为非静音。 | +| 类型 | 说明 | +| -------------------------------------------------- | ------------------------------- | +| Promise<[AudioRendererInfo](#audiorendererinfo8)\> | Promise用于返回音频渲染器信息。 | **示例:** ```js -audioGroupManager.isMute(audio.AudioVolumeType.MEDIA).then((value) => { - console.info(`Promise returned to indicate that the mute status of the stream is obtained ${value}.`); +audioRenderer.getRendererInfo().then((rendererInfo) => { + console.info('Renderer GetRendererInfo:'); + console.info(`Renderer content: ${rendererInfo.content}`); + console.info(`Renderer usage: ${rendererInfo.usage}`); + console.info(`Renderer flags: ${rendererInfo.rendererFlags}`) +}).catch((err) => { + console.error(`AudioFrameworkRenderLog: RendererInfo :ERROR: ${err}`); }); ``` -## AudioStreamManager9+ - -管理音频流。在使用AudioStreamManager的API前,需要使用[getStreamManager](#getstreammanager9)获取AudioStreamManager实例。 - -### getCurrentAudioRendererInfoArray9+ +### getStreamInfo8+ -getCurrentAudioRendererInfoArray(callback: AsyncCallback<AudioRendererChangeInfoArray>): void +getStreamInfo(callback: AsyncCallback): void -获取当前音频渲染器的信息。使用callback异步回调。 +获取音频流信息,使用callback方式异步返回结果。 -**系统能力**: SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 名称 | 类型 | 必填 | 说明 | -| -------- | ----------------------------------- | -------- | --------------------------- | -| callback | AsyncCallback<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | 是 | 回调函数,返回当前音频渲染器的信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :------------------- | +| callback | AsyncCallback<[AudioStreamInfo](#audiostreaminfo8)\> | 是 | 回调返回音频流信息。 | **示例:** ```js -audioStreamManager.getCurrentAudioRendererInfoArray(async (err, AudioRendererChangeInfoArray) => { - console.info('getCurrentAudioRendererInfoArray **** Get Callback Called ****'); - if (err) { - console.error(`getCurrentAudioRendererInfoArray :ERROR: ${err}`); - } else { - if (AudioRendererChangeInfoArray != null) { - for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { - let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; - console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); - console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); - console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); - console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); - console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); - console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); - for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); - } - } - } - } +audioRenderer.getStreamInfo((err, streamInfo) => { + console.info('Renderer GetStreamInfo:'); + console.info(`Renderer sampling rate: ${streamInfo.samplingRate}`); + console.info(`Renderer channel: ${streamInfo.channels}`); + console.info(`Renderer format: ${streamInfo.sampleFormat}`); + console.info(`Renderer encoding type: ${streamInfo.encodingType}`); }); ``` -### getCurrentAudioRendererInfoArray9+ +### getStreamInfo8+ -getCurrentAudioRendererInfoArray(): Promise<AudioRendererChangeInfoArray> +getStreamInfo(): Promise -获取当前音频渲染器的信息。使用Promise异步回调。 +获取音频流信息,使用Promise方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer **返回值:** -| 类型 | 说明 | -| ---------------------------------------------------------------------------------| --------------------------------------- | -| Promise<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | Promise对象,返回当前音频渲染器信息。 | +| 类型 | 说明 | +| :--------------------------------------------- | :--------------------- | +| Promise<[AudioStreamInfo](#audiostreaminfo8)\> | Promise返回音频流信息. | **示例:** ```js -async function getCurrentAudioRendererInfoArray(){ - await audioStreamManager.getCurrentAudioRendererInfoArray().then( function (AudioRendererChangeInfoArray) { - console.info(`getCurrentAudioRendererInfoArray ######### Get Promise is called ##########`); - if (AudioRendererChangeInfoArray != null) { - for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { - let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; - console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); - console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); - console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); - console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); - console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); - console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); - for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); - } - } - } - }).catch((err) => { - console.error(`getCurrentAudioRendererInfoArray :ERROR: ${err}`); - }); -} +audioRenderer.getStreamInfo().then((streamInfo) => { + console.info('Renderer GetStreamInfo:'); + console.info(`Renderer sampling rate: ${streamInfo.samplingRate}`); + console.info(`Renderer channel: ${streamInfo.channels}`); + console.info(`Renderer format: ${streamInfo.sampleFormat}`); + console.info(`Renderer encoding type: ${streamInfo.encodingType}`); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### getCurrentAudioCapturerInfoArray9+ +### getAudioStreamId9+ -getCurrentAudioCapturerInfoArray(callback: AsyncCallback<AudioCapturerChangeInfoArray>): void +getAudioStreamId(callback: AsyncCallback): void -获取当前音频采集器的信息。使用callback异步回调。 +获取音频流id,使用callback方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 名称 | 类型 | 必填 | 说明 | -| ---------- | ----------------------------------- | --------- | -------------------------------------------------------- | -| callback | AsyncCallback<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | 是 | 回调函数,返回当前音频采集器的信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :------------------- | +| callback | AsyncCallback | 是 | 回调返回音频流id。 | **示例:** ```js -audioStreamManager.getCurrentAudioCapturerInfoArray(async (err, AudioCapturerChangeInfoArray) => { - console.info('getCurrentAudioCapturerInfoArray **** Get Callback Called ****'); - if (err) { - console.error(`getCurrentAudioCapturerInfoArray :ERROR: ${err}`); - } else { - if (AudioCapturerChangeInfoArray != null) { - for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { - console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); - console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); - console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); - console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); - console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); - for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); - } - } - } - } +audioRenderer.getAudioStreamId((err, streamid) => { + console.info(`Renderer GetStreamId: ${streamid}`); }); ``` -### getCurrentAudioCapturerInfoArray9+ +### getAudioStreamId9+ -getCurrentAudioCapturerInfoArray(): Promise<AudioCapturerChangeInfoArray> +getAudioStreamId(): Promise -获取当前音频采集器的信息。使用Promise异步回调。 +获取音频流id,使用Promise方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer **返回值:** -| 类型 | 说明 | -| -----------------------------------------------------------------------------| ----------------------------------- | -| Promise<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | Promise对象,返回当前音频渲染器信息。 | +| 类型 | 说明 | +| :--------------------------------------------- | :--------------------- | +| Promise | Promise返回音频流id。 | **示例:** ```js -async function getCurrentAudioCapturerInfoArray(){ - await audioStreamManager.getCurrentAudioCapturerInfoArray().then( function (AudioCapturerChangeInfoArray) { - console.info('getCurrentAudioCapturerInfoArray **** Get Promise Called ****'); - if (AudioCapturerChangeInfoArray != null) { - for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { - console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); - console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); - console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); - console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); - console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); - for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); - } - } - } - }).catch((err) => { - console.error(`getCurrentAudioCapturerInfoArray :ERROR: ${err}`); - }); -} +audioRenderer.getAudioStreamId().then((streamid) => { + console.info(`Renderer getAudioStreamId: ${streamid}`); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### on('audioRendererChange')9+ +### start8+ -on(type: "audioRendererChange", callback: Callback<AudioRendererChangeInfoArray>): void +start(callback: AsyncCallback): void -监听音频渲染器更改事件。 +启动音频渲染器。使用callback方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 名称 | 类型 | 必填 | 说明 | -| -------- | ---------- | --------- | ------------------------------------------------------------------------ | -| type | string | 是 | 事件类型,支持的事件`'audioRendererChange'`:当音频渲染器发生更改时触发。 | -| callback | Callback<[AudioRendererChangeInfoArray](#audiorendererchangeinfoarray9)> | 是 | 回调函数。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------- | +| callback | AsyncCallback\ | 是 | 回调函数。 | **示例:** ```js -audioStreamManager.on('audioRendererChange', (AudioRendererChangeInfoArray) => { - for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { - let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i]; - console.info(`## RendererChange on is called for ${i} ##`); - console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`); - console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfo.clientUid}`); - console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`); - console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`); - console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); - console.info(`State for ${i} is: ${AudioRendererChangeInfo.rendererState}`); - for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`); - } +audioRenderer.start((err) => { + if (err) { + console.error('Renderer start failed.'); + } else { + console.info('Renderer start success.'); } }); ``` -### off('audioRendererChange')9+ +### start8+ -off(type: "audioRendererChange"); +start(): Promise -取消监听音频渲染器更改事件。 +启动音频渲染器。使用Promise方式异步返回结果。 **系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 名称 | 类型 | 必填 | 说明 | -| -------- | ------- | ---- | ---------------- | -| type | string | 是 | 事件类型,支持的事件`'audioRendererChange'`:音频渲染器更改事件。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise方式异步返回结果。 | **示例:** ```js -audioStreamManager.off('audioRendererChange'); -console.info('######### RendererChange Off is called #########'); +audioRenderer.start().then(() => { + console.info('Renderer started'); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### on('audioCapturerChange')9+ +### pause8+ -on(type: "audioCapturerChange", callback: Callback<AudioCapturerChangeInfoArray>): void +pause(callback: AsyncCallback\): void -监听音频采集器更改事件。 +暂停渲染。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 名称 | 类型 | 必填 | 说明 | -| -------- | ------- | --------- | ----------------------------------------------------------------------- | -| type | string | 是 | 事件类型,支持的事件`'audioCapturerChange'`:当音频采集器发生更改时触发。 | -| callback | Callback<[AudioCapturerChangeInfoArray](#audiocapturerchangeinfoarray9)> | 是 | 回调函数。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------- | +| callback | AsyncCallback\ | 是 | 返回回调的结果。 | **示例:** ```js -audioStreamManager.on('audioCapturerChange', (AudioCapturerChangeInfoArray) => { - for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { - console.info(`## CapChange on is called for element ${i} ##`); - console.info(`StreamId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); - console.info(`ClientUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); - console.info(`Source for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); - console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); - console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); - var devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors; - for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); - console.info(`Address: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); - console.info(`SampleRates: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); - console.info(`ChannelCounts ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); - console.info(`ChannelMask: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); - } +audioRenderer.pause((err) => { + if (err) { + console.error('Renderer pause failed'); + } else { + console.info('Renderer paused.'); } }); ``` -### off('audioCapturerChange')9+ +### pause8+ -off(type: "audioCapturerChange"); +pause(): Promise\ -取消监听音频采集器更改事件。 +暂停渲染。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 名称 | 类型 | 必填 | 说明 | -| -------- | -------- | --- | ------------------------------------------------------------- | -| type | string |是 | 事件类型,支持的事件`'audioCapturerChange'`:音频采集器更改事件。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise方式异步返回结果。 | **示例:** ```js -audioStreamManager.off('audioCapturerChange'); -console.info('######### CapturerChange Off is called #########'); - +audioRenderer.pause().then(() => { + console.info('Renderer paused'); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -## AudioRoutingManager9+ - -音频路由管理。在使用AudioRoutingManager的接口前,需要使用[getRoutingManager](#getroutingmanager9)获取AudioRoutingManager实例。 -### getDevices9+ +### drain8+ -getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void +drain(callback: AsyncCallback\): void -获取音频设备列表,使用callback方式异步返回结果。 +检查缓冲区是否已被耗尽。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------------------------------------------ | ---- | -------------------- | -| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | -| callback | AsyncCallback<[AudioDeviceDescriptors](#audiodevicedescriptors)> | 是 | 回调,返回设备列表。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------- | +| callback | AsyncCallback\ | 是 | 返回回调的结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getRoutingManager((err,AudioRoutingManager)=>{ +audioRenderer.drain((err) => { if (err) { - console.error(`AudioFrameworkTest:Callback:failed to get RoutingManager ${err}`); + console.error('Renderer drain failed'); } else { - AudioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (err, value) => { - if (err) { - console.error(`Failed to obtain the device list. ${err}`); - return; - } - console.info('Callback invoked to indicate that the device list is obtained.'); - }); + console.info('Renderer drained.'); } -}) +}); ``` -### getDevices9+ - -getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors> - -获取音频设备列表,使用Promise方式异步返回结果。 +### drain8+ -**系统能力:** SystemCapability.Multimedia.Audio.Device +drain(): Promise\ -**参数:** +检查缓冲区是否已被耗尽。使用Promise方式异步返回结果。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ------------------------- | ---- | ---------------- | -| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **返回值:** -| 类型 | 说明 | -| ------------------------------------------------------------ | ------------------------- | -| Promise<[AudioDeviceDescriptors](#audiodevicedescriptors)> | Promise回调返回设备列表。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise方式异步返回结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getRoutingManager((err,AudioRoutingManager)=>{ - if (err) { - console.error(`AudioFrameworkTest:Callback:failed to get RoutingManager ${err}`); - } - else { - AudioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { - console.info('Promise returned to indicate that the device list is obtained.'); - }); - } +audioRenderer.drain().then(() => { + console.info('Renderer drained successfully'); +}).catch((err) => { + console.error(`ERROR: ${err}`); }); ``` -### on9+ +### stop8+ -on(type: 'deviceChange', deviceFlag: DeviceFlag, callback: Callback): void +stop(callback: AsyncCallback\): void -设备更改。音频设备连接状态变化。 +停止渲染。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------------------------------------- | :--- | :----------------------------------------- | -| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | -| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | -| callback | Callback<[DeviceChangeAction](#devicechangeaction)\> | 是 | 获取设备更新详情。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------- | +| callback | AsyncCallback\ | 是 | 返回回调的结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getRoutingManager((err,AudioRoutingManager)=>{ +audioRenderer.stop((err) => { if (err) { - console.error(`AudioFrameworkTest:Callback:failed to get RoutingManager ${err}`); - } - else { - AudioRoutingManager.on('deviceChange', audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (deviceChanged) => { - console.info('device change type : ' + deviceChanged.type); - console.info('device descriptor size : ' + deviceChanged.deviceDescriptors.length); - console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceRole); - console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceType); - }); + console.error('Renderer stop failed'); + } else { + console.info('Renderer stopped.'); } }); ``` -### off9+ +### stop8+ -off(type: 'deviceChange', callback?: Callback): void +stop(): Promise\ -取消订阅音频设备连接变化事件。 +停止渲染。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | --------------------------------------------------- | ---- | ------------------------------------------ | -| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | -| callback | Callback<[DeviceChangeAction](#devicechangeaction)> | 否 | 获取设备更新详情。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise方式异步返回结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getRoutingManager((err,AudioRoutingManager)=>{ - if (err) { - console.error(`AudioFrameworkTest:Callback:failed to get RoutingManager ${err}`); - } else { - AudioRoutingManager.off('deviceChange', (deviceChanged) => { - console.info('Should be no callback.'); - }); - } +audioRenderer.stop().then(() => { + console.info('Renderer stopped successfully'); +}).catch((err) => { + console.error(`ERROR: ${err}`); }); ``` -### selectInputDevice9+ - -selectInputDevice(inputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void +### release8+ -选择音频输入设备,当前只能选择一个输入设备,使用callback方式异步返回结果。 +release(callback: AsyncCallback\): void -**系统接口:** 该接口为系统接口 +释放音频渲染器。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | -| inputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输入设备类。 | -| callback | AsyncCallback<void> | 是 | 回调,返回选择输入设备结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------- | +| callback | AsyncCallback\ | 是 | 返回回调的结果。 | **示例:** -```js -let audioManager = audio.getAudioManager(); -let inputAudioDeviceDescriptor = [{ - "deviceRole":audio.DeviceRole.INPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectInputDevice(inputAudioDeviceDescriptor, (err) => { - if (err) { - console.error(`Result ERROR: ${err}`); - } else { - console.info('Select input devices result callback: SUCCESS'); } - }); - }); -} +```js +audioRenderer.release((err) => { + if (err) { + console.error('Renderer release failed'); + } else { + console.info('Renderer released.'); + } +}); ``` -### on('micStateChange')9+ - -on(type: 'micStateChange', callback: Callback<MicStateChangeEvent>): void +### release8+ -监听系统麦克风状态更改事件 +release(): Promise\ -目前此订阅接口在单进程多AudioManager实例的使用场景下,仅最后一个实例的订阅生效,其他实例的订阅会被覆盖(即使最后一个实例没有进行订阅),因此推荐使用单一AudioManager实例进行开发。 +释放渲染器。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'micStateChange'(系统麦克风状态变化事件,检测到系统麦克风状态改变时,触发该事件)。 | -| callback | Callback<[MicStateChangeEvent](#micstatechangeevent9)> | 是 | 回调方法,返回变更后的麦克风状态。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise方式异步返回结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -audioManager.getRoutingManager.on('micStateChange', (micStateChange) => { - console.info(`Current microphone status is: ${micStateChange.mute} `); +audioRenderer.release().then(() => { + console.info('Renderer released successfully'); +}).catch((err) => { + console.error(`ERROR: ${err}`); }); ``` -### selectInputDevice9+ - -selectInputDevice(inputAudioDevices: AudioDeviceDescriptors): Promise<void> +### write8+ -**系统接口:** 该接口为系统接口 +write(buffer: ArrayBuffer, callback: AsyncCallback\): void -选择音频输入设备,当前只能选择一个输入设备,使用Promise方式异步返回结果。 +写入缓冲区。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | -| inputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输入设备类。 | - -**返回值:** - -| 类型 | 说明 | -| --------------------- | --------------------------- | -| Promise<void> | Promise返回选择输入设备结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------- | ---- | --------------------------------------------------- | +| buffer | ArrayBuffer | 是 | 要写入缓冲区的数据。 | +| callback | AsyncCallback\ | 是 | 回调如果成功,返回写入的字节数,否则返回errorcode。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -let inputAudioDeviceDescriptor =[{ - "deviceRole":audio.DeviceRole.INPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; - -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectInputDevice(inputAudioDeviceDescriptor).then(() => { - console.info('Select input devices result promise: SUCCESS'); - }).catch((err) => { - console.error(`Result ERROR: ${err}`); - }); +let bufferSize; +audioRenderer.getBufferSize().then((data)=> { + console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); + bufferSize = data; + }).catch((err) => { + console.error(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); }); +console.info(`Buffer size: ${bufferSize}`); +let context = featureAbility.getContext(); +let path; +async function getCacheDir(){ + path = await context.getCacheDir(); } +let filePath = path + '/StarWars10s-2C-48000-4SW.wav'; +let ss = fileio.createStreamSync(filePath, 'r'); +let buf = new ArrayBuffer(bufferSize); +ss.readSync(buf); +audioRenderer.write(buf, (err, writtenbytes) => { + if (writtenbytes < 0) { + console.error('write failed.'); + } else { + console.info(`Actual written bytes: ${writtenbytes}`); + } +}); ``` -### selectOutputDevice9+ - -selectOutputDevice(outputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void +### write8+ -选择音频输出设备,当前只能选择一个输出设备,使用callback方式异步返回结果。 +write(buffer: ArrayBuffer): Promise\ -**系统接口:** 该接口为系统接口 +写入缓冲区。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**参数:** +**返回值:** -| 参数名 | 类型 | 必填 | 说明 | -| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | -| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | -| callback | AsyncCallback<void> | 是 | 回调,返回获取输出设备结果。 | +| 类型 | 说明 | +| ---------------- | ------------------------------------------------------------ | +| Promise\ | Promise返回结果,如果成功,返回写入的字节数,否则返回errorcode。 | **示例:** -```js -let audioManager = audio.getAudioManager(); -let outputAudioDeviceDescriptor = [{ - "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectOutputDevice(outputAudioDeviceDescriptor, (err) => { - if (err) { - console.error(`Result ERROR: ${err}`); - } else { - console.info('Select output devices result callback: SUCCESS'); } - }); +```js +let bufferSize; +audioRenderer.getBufferSize().then((data) => { + console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); + bufferSize = data; + }).catch((err) => { + console.info(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); }); +console.info(`BufferSize: ${bufferSize}`); +let context = featureAbility.getContext(); +let path; +async function getCacheDir(){ + path = await context.getCacheDir(); } +let filePath = path + '/StarWars10s-2C-48000-4SW.wav'; +let ss = fileio.createStreamSync(filePath, 'r'); +let buf = new ArrayBuffer(bufferSize); +ss.readSync(buf); +audioRenderer.write(buf).then((writtenbytes) => { + if (writtenbytes < 0) { + console.error('write failed.'); + } else { + console.info(`Actual written bytes: ${writtenbytes}`); + } +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### selectOutputDevice9+ - -selectOutputDevice(outputAudioDevices: AudioDeviceDescriptors): Promise<void> +### getAudioTime8+ -**系统接口:** 该接口为系统接口 +getAudioTime(callback: AsyncCallback\): void -选择音频输出设备,当前只能选择一个输出设备,使用Promise方式异步返回结果。 +获取时间戳(从 1970 年 1 月 1 日开始)。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | -| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------- | ---- | ---------------- | +| callback | AsyncCallback\ | 是 | 回调返回时间戳。 | + +**示例:** + +```js +audioRenderer.getAudioTime((err, timestamp) => { + console.info(`Current timestamp: ${timestamp}`); +}); +``` + +### getAudioTime8+ + +getAudioTime(): Promise\ + +获取时间戳(从 1970 年 1 月 1 日开始)。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **返回值:** -| 类型 | 说明 | -| --------------------- | --------------------------- | -| Promise<void> | Promise返回选择输出设备结果。 | +| 类型 | 描述 | +| ---------------- | ----------------------- | +| Promise\ | Promise回调返回时间戳。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -let outputAudioDeviceDescriptor =[{ - "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; - -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectOutputDevice(outputAudioDeviceDescriptor).then(() => { - console.info('Select output devices result promise: SUCCESS'); - }).catch((err) => { - console.error(`Result ERROR: ${err}`); - }); - }); -} +audioRenderer.getAudioTime().then((timestamp) => { + console.info(`Current timestamp: ${timestamp}`); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### selectOutputDeviceByFilter9+ - -selectOutputDeviceByFilter(filter: AudioRendererFilter, outputAudioDevices: AudioDeviceDescriptors, callback: AsyncCallback<void>): void +### getBufferSize8+ -**系统接口:** 该接口为系统接口 +getBufferSize(callback: AsyncCallback\): void -根据过滤条件,选择音频输出设备,当前只能选择一个输出设备,使用callback方式异步返回结果。 +获取音频渲染器的最小缓冲区大小。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Device +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| --------------------------- | ------------------------------------------------------------ | ---- | ------------------------- | -| filter | [AudioRendererFilter](#audiorendererfilter9) | 是 | 过滤条件类。 | -| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | -| callback | AsyncCallback<void> | 是 | 回调,返回获取输出设备结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------- | ---- | -------------------- | +| callback | AsyncCallback\ | 是 | 回调返回缓冲区大小。 | **示例:** + ```js -let audioManager = audio.getAudioManager(); -let outputAudioRendererFilter = { - "uid":20010041, - "rendererInfo": { - "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, - "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, - "rendererFlags":0 }, - "rendererId":0 }; -let outputAudioDeviceDescriptor = [{ - "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; +let bufferSize = audioRenderer.getBufferSize(async(err, bufferSize) => { + if (err) { + console.error('getBufferSize error'); + } +}); +``` -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectOutputDeviceByFilter(outputAudioRendererFilter, outputAudioDeviceDescriptor, (err) => { - if (err) { - console.error(`Result ERROR: ${err}`); - } else { - console.info('Select output devices by filter result callback: SUCCESS'); } - }); - }); -} +### getBufferSize8+ + +getBufferSize(): Promise\ + +获取音频渲染器的最小缓冲区大小。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**返回值:** + +| 类型 | 说明 | +| ---------------- | --------------------------- | +| Promise\ | promise回调返回缓冲区大小。 | + +**示例:** + +```js +let bufferSize; +audioRenderer.getBufferSize().then((data) => { + console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); + bufferSize = data; +}).catch((err) => { + console.error(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); +}); ``` -### selectOutputDeviceByFilter9+ +### setRenderRate8+ -selectOutputDeviceByFilter(filter: AudioRendererFilter, outputAudioDevices: AudioDeviceDescriptors): Promise<void> +setRenderRate(rate: AudioRendererRate, callback: AsyncCallback\): void -**系统接口:** 该接口为系统接口 +设置音频渲染速率。使用callback方式异步返回结果。 -根据过滤条件,选择音频输出设备,当前只能选择一个输出设备,使用Promise方式异步返回结果。 +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -**系统能力:** SystemCapability.Multimedia.Audio.Device +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------- | ---- | ------------------------ | +| rate | [AudioRendererRate](#audiorendererrate8) | 是 | 渲染的速率。 | +| callback | AsyncCallback\ | 是 | 用于返回执行结果的回调。 | + +**示例:** + +```js +audioRenderer.setRenderRate(audio.AudioRendererRate.RENDER_RATE_NORMAL, (err) => { + if (err) { + console.error('Failed to set params'); + } else { + console.info('Callback invoked to indicate a successful render rate setting.'); + } +}); +``` + +### setRenderRate8+ + +setRenderRate(rate: AudioRendererRate): Promise\ + +设置音频渲染速率。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| ----------------------| ------------------------------------------------------------ | ---- | ------------------------- | -| filter | [AudioRendererFilter](#audiorendererfilter9) | 是 | 过滤条件类。 | -| outputAudioDevices | [AudioDeviceDescriptors](#audiodevicedescriptors) | 是 | 输出设备类。 | +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ---------------------------------------- | ---- | ------------ | +| rate | [AudioRendererRate](#audiorendererrate8) | 是 | 渲染的速率。 | **返回值:** -| 类型 | 说明 | -| --------------------- | --------------------------- | -| Promise<void> | Promise返回选择输出设备结果。 | +| 类型 | 说明 | +| -------------- | ------------------------- | +| Promise\ | Promise用于返回执行结果。 | **示例:** ```js -let audioManager = audio.getAudioManager(); -let outputAudioRendererFilter = { - "uid":20010041, - "rendererInfo": { - "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, - "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, - "rendererFlags":0 }, - "rendererId":0 }; -let outputAudioDeviceDescriptor = [{ - "deviceRole":audio.DeviceRole.OUTPUT_DEVICE, - "networkId":audio.LOCAL_NETWORK_ID, - "interruptGroupId":1, - "volumeGroupId":1 }]; -let audioRoutingManager; +audioRenderer.setRenderRate(audio.AudioRendererRate.RENDER_RATE_NORMAL).then(() => { + console.info('setRenderRate SUCCESS'); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); +``` -async function getRoutingManager(){ - await audioManager.getRoutingManager().then((value) => { - audioRoutingManager = value; - audioRoutingManager.selectOutputDeviceByFilter(outputAudioRendererFilter, outputAudioDeviceDescriptor).then(() => { - console.info('Select output devices by filter result promise: SUCCESS'); - }).catch((err) => { - console.error(`Result ERROR: ${err}`); - }) - }); -} +### getRenderRate8+ + +getRenderRate(callback: AsyncCallback\): void + +获取当前渲染速率。使用callback方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------------- | ---- | ------------------ | +| callback | AsyncCallback<[AudioRendererRate](#audiorendererrate8)> | 是 | 回调返回渲染速率。 | + +**示例:** + +```js +audioRenderer.getRenderRate((err, renderrate) => { + console.info(`getRenderRate: ${renderrate}`); +}); ``` -## AudioRendererChangeInfo9+ +### getRenderRate8+ + +getRenderRate(): Promise\ + +获取当前渲染速率。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------- | ------------------------- | +| Promise<[AudioRendererRate](#audiorendererrate8)> | Promise回调返回渲染速率。 | + +**示例:** + +```js +audioRenderer.getRenderRate().then((renderRate) => { + console.info(`getRenderRate: ${renderRate}`); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); +``` +### setInterruptMode9+ + +setInterruptMode(mode: InterruptMode): Promise<void> + +设置应用的焦点模型。使用Promise异步回调。 + +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ---------------------------------- | ------ | ---------- | +| mode | [InterruptMode](#interruptmode9) | 是 | 焦点模型。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | 以Promise对象返回结果,设置成功时返回undefined,否则返回error。 | + +**示例:** + +```js +let mode = 0; +audioRenderer.setInterruptMode(mode).then(data=>{ + console.info('setInterruptMode Success!'); +}).catch((err) => { + console.error(`setInterruptMode Fail: ${err}`); +}); +``` +### setInterruptMode9+ + +setInterruptMode(mode: InterruptMode, callback: AsyncCallback\): void + +设置应用的焦点模型。使用Callback回调返回执行结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ----------------------------------- | ------ | -------------- | +|mode | [InterruptMode](#interruptmode9) | 是 | 焦点模型。| +|callback | AsyncCallback\ | 是 |回调返回执行结果。| + +**示例:** + +```js +let mode = 1; +audioRenderer.setInterruptMode(mode, (err, data)=>{ + if(err){ + console.error(`setInterruptMode Fail: ${err}`); + } + console.info('setInterruptMode Success!'); +}); +``` + +### setVolume9+ + +setVolume(volume: number): Promise<void> + +设置应用的音量。使用Promise异步回调。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------- | ------ | ---------- | +| volume | number | 是 | 音量值。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | 以Promise对象返回结果,设置成功时返回undefined,否则返回error。 | + +**示例:** + +```js +audioRenderer.setVolume(10).then(data=>{ + console.info('setVolume Success!'); +}).catch((err) => { + console.error(`setVolume Fail: ${err}`); +}); +``` +### setVolume9+ + +setVolume(volume: number, callback: AsyncCallback\): void + +设置应用的音量。使用Callback回调返回执行结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | -----------| ------ | -------------- | +|volume | number | 是 | 音量值。| +|callback | AsyncCallback\ | 是 |回调返回执行结果。| + +**示例:** + +```js +audioRenderer.setVolume(10, (err, data)=>{ + if(err){ + console.error(`setVolume Fail: ${err}`); + } + console.info('setVolume Success!'); +}); +``` + +### on('audioInterrupt')9+ + +on(type: 'audioInterrupt', callback: Callback\): void + +监听音频中断事件。使用callback获取中断事件。 + +**系统能力:** SystemCapability.Multimedia.Audio.Interrupt + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'audioInterrupt'(中断事件被触发,音频播放被中断。) | +| callback | Callback<[InterruptEvent](#interruptevent9)> | 是 | 被监听的中断事件的回调。 | + +**错误码:** + +以下错误码的详细介绍请参见[音频错误码](../errorcodes/errorcode-audio.md)。 + +| 错误码ID | 错误信息 | +| ------- | --------------------------------------------| +| 6800101 | if input parameter value error. | + +**示例:** + +```js +let isPlay; +let started; +audioRenderer.on('audioInterrupt', async(interruptEvent) => { + if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_FORCE) { + switch (interruptEvent.hintType) { + case audio.InterruptHint.INTERRUPT_HINT_PAUSE: + console.info('Force paused. Stop writing'); + isPlay = false; + break; + case audio.InterruptHint.INTERRUPT_HINT_STOP: + console.info('Force stopped. Stop writing'); + isPlay = false; + break; + } + } else if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_SHARE) { + switch (interruptEvent.hintType) { + case audio.InterruptHint.INTERRUPT_HINT_RESUME: + console.info('Resume force paused renderer or ignore'); + await audioRenderer.start().then(async function () { + console.info('AudioInterruptMusic: renderInstant started :SUCCESS '); + started = true; + }).catch((err) => { + console.error(`AudioInterruptMusic: renderInstant start :ERROR : ${err}`); + started = false; + }); + if (started) { + isPlay = true; + console.info(`AudioInterruptMusic Renderer started : isPlay : ${isPlay}`); + } else { + console.error('AudioInterruptMusic Renderer start failed'); + } + break; + case audio.InterruptHint.INTERRUPT_HINT_PAUSE: + console.info('Choose to pause or ignore'); + if (isPlay == true) { + isPlay == false; + console.info('AudioInterruptMusic: Media PAUSE : TRUE'); + } else { + isPlay = true; + console.info('AudioInterruptMusic: Media PLAY : TRUE'); + } + break; + } + } +}); +``` + +### on('markReach')8+ + +on(type: "markReach", frame: number, callback: Callback<number>): void + +订阅到达标记的事件。 当渲染的帧数达到 frame 参数的值时,回调被调用。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :----------------------- | :--- | :---------------------------------------- | +| type | string | 是 | 事件回调类型,支持的事件为:'markReach'。 | +| frame | number | 是 | 触发事件的帧数。 该值必须大于 0。 | +| callback | Callback\ | 是 | 触发事件时调用的回调。 | + +**示例:** + +```js +audioRenderer.on('markReach', 1000, (position) => { + if (position == 1000) { + console.info('ON Triggered successfully'); + } +}); +``` + + +### off('markReach') 8+ + +off(type: 'markReach'): void + +取消订阅标记事件。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :----- | :----- | :--- | :------------------------------------------------ | +| type | string | 是 | 要取消订阅事件的类型。支持的事件为:'markReach'。 | + +**示例:** + +```js +audioRenderer.off('markReach'); +``` + +### on('periodReach') 8+ + +on(type: "periodReach", frame: number, callback: Callback<number>): void + +订阅到达标记的事件。 当渲染的帧数达到 frame 参数的值时,回调被循环调用。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :----------------------- | :--- | :------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'periodReach'。 | +| frame | number | 是 | 触发事件的帧数。 该值必须大于 0。 | +| callback | Callback\ | 是 | 触发事件时调用的回调。 | + +**示例:** + +```js +audioRenderer.on('periodReach', 1000, (position) => { + if (position == 1000) { + console.info('ON Triggered successfully'); + } +}); +``` + +### off('periodReach') 8+ + +off(type: 'periodReach'): void + +取消订阅标记事件。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :----- | :----- | :--- | :-------------------------------------------------- | +| type | string | 是 | 要取消订阅事件的类型。支持的事件为:'periodReach'。 | + +**示例:** + +```js +audioRenderer.off('periodReach') +``` + +### on('stateChange') 8+ + +on(type: 'stateChange', callback: Callback): void + +订阅监听状态变化。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------------- | :--- | :------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'stateChange'。 | +| callback | [AudioState](#audiostate8) | 是 | 返回监听的状态。 | + +**示例:** + +```js +audioRenderer.on('stateChange', (state) => { + if (state == 1) { + console.info('audio renderer state is: STATE_PREPARED'); + } + if (state == 2) { + console.info('audio renderer state is: STATE_RUNNING'); + } +}); +``` + +## AudioCapturer8+ + +提供音频采集的相关接口。在调用AudioCapturer的接口前,需要先通过[createAudioCapturer](#audiocreateaudiocapturer8)创建实例。 + +### 属性 + +**系统能力:** SystemCapability.Multimedia.Audio.Capturer + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| :---- | :------------------------- | :--- | :--- | :--------------- | +| state8+ | [AudioState](#audiostate8) | 是 | 否 | 音频采集器状态。 | + +**示例:** + +```js +let state = audioCapturer.state; +``` -描述音频渲染器更改信息。 +### getCapturerInfo8+ -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer +getCapturerInfo(callback: AsyncCallback): void -| 名称 | 类型 | 可读 | 可写 | 说明 | -| -------------------| ----------------------------------------- | ---- | ---- | ---------------------------- | -| streamId | number | 是 | 否 | 音频流唯一id。 | -| clientUid | number | 是 | 否 | 音频渲染器客户端应用程序的Uid。
此接口为系统接口,三方应用不支持调用。 | -| rendererInfo | [AudioRendererInfo](#audiorendererinfo8) | 是 | 否 | 音频渲染器信息。 | -| rendererState | [AudioState](#audiostate) | 是 | 否 | 音频状态。
此接口为系统接口,三方应用不支持调用。| +获取采集器信息。使用callback方式异步返回结果。 -## AudioRendererChangeInfoArray9+ +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -AudioRenderChangeInfo数组,只读。 +**参数:** -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :-------------------------------- | :--- | :----------------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回采集器信息。 | **示例:** ```js -import audio from '@ohos.multimedia.audio'; - -let audioStreamManager; -let resultFlag = false; -let audioManager = audio.getAudioManager(); - -audioManager.getStreamManager((err, data) => { +audioCapturer.getCapturerInfo((err, capturerInfo) => { if (err) { - console.error(`Get AudioStream Manager : ERROR : ${err}`); + console.error('Failed to get capture info'); } else { - audioStreamManager = data; - console.info('Get AudioStream Manager : Success'); - } -}); - -audioStreamManager.on('audioRendererChange', (AudioRendererChangeInfoArray) => { - for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) { - console.info(`## RendererChange on is called for ${i} ##`); - console.info(`StreamId for ${i} is: ${AudioRendererChangeInfoArray[i].streamId}`); - console.info(`ClientUid for ${i} is: ${AudioRendererChangeInfoArray[i].clientUid}`); - console.info(`Content for ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.content}`); - console.info(`Stream for ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.usage}`); - console.info(`Flag ${i} is: ${AudioRendererChangeInfoArray[i].rendererInfo.rendererFlags}`); - console.info(`State for ${i} is: ${AudioRendererChangeInfoArray[i].rendererState}`); - var devDescriptor = AudioRendererChangeInfoArray[i].deviceDescriptors; - for (let j = 0; j < AudioRendererChangeInfoArray[i].deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].name}`); - console.info(`Addr: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].address}`); - console.info(`SR: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); - console.info(`C ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); - console.info(`CM: ${i} : ${AudioRendererChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); - } - if (AudioRendererChangeInfoArray[i].rendererState == 1 && devDescriptor != null) { - resultFlag = true; - console.info(`ResultFlag for ${i} is: ${resultFlag}`); - } + console.info('Capturer getCapturerInfo:'); + console.info(`Capturer source: ${capturerInfo.source}`); + console.info(`Capturer flags: ${capturerInfo.capturerFlags}`); } }); ``` -## AudioCapturerChangeInfo9+ -描述音频采集器更改信息。 +### getCapturerInfo8+ -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Capturer +getCapturerInfo(): Promise -| 名称 | 类型 | 可读 | 可写 | 说明 | -| -------------------| ----------------------------------------- | ---- | ---- | ---------------------------- | -| streamId | number | 是 | 否 | 音频流唯一id。 | -| clientUid | number | 是 | 否 | 音频采集器客户端应用程序的Uid。
此接口为系统接口,三方应用不支持调用。 | -| capturerInfo | [AudioCapturerInfo](#audiocapturerinfo8) | 是 | 否 | 音频采集器信息。 | -| capturerState | [AudioState](#audiostate) | 是 | 否 | 音频状态。
此接口为系统接口,三方应用不支持调用。| +获取采集器信息。使用Promise方式异步返回结果。 -## AudioCapturerChangeInfoArray9+ +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -AudioCapturerChangeInfo数组,只读。 +**返回值:** -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +| 类型 | 说明 | +| :------------------------------------------------ | :---------------------------------- | +| Promise<[AudioCapturerInfo](#audiocapturerinfo)\> | 使用Promise方式异步返回采集器信息。 | **示例:** ```js -import audio from '@ohos.multimedia.audio'; - -const audioManager = audio.getAudioManager(); -let audioStreamManager; -audioManager.getStreamManager((err, data) => { - if (err) { - console.error(`getStreamManager : Error: ${err}`); +audioCapturer.getCapturerInfo().then((audioParamsGet) => { + if (audioParamsGet != undefined) { + console.info('AudioFrameworkRecLog: Capturer CapturerInfo:'); + console.info(`AudioFrameworkRecLog: Capturer SourceType: ${audioParamsGet.source}`); + console.info(`AudioFrameworkRecLog: Capturer capturerFlags: ${audioParamsGet.capturerFlags}`); } else { - console.info('getStreamManager : Success : SUCCESS'); - audioStreamManager = data; + console.info(`AudioFrameworkRecLog: audioParamsGet is : ${audioParamsGet}`); + console.info('AudioFrameworkRecLog: audioParams getCapturerInfo are incorrect'); } +}).catch((err) => { + console.error(`AudioFrameworkRecLog: CapturerInfo :ERROR: ${err}`); }); +``` -let resultFlag = false; -audioStreamManager.on('audioCapturerChange', (AudioCapturerChangeInfoArray) => { - for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) { - console.info(`## CapChange on is called for element ${i} ##`); - console.info(`StrId for ${i} is: ${AudioCapturerChangeInfoArray[i].streamId}`); - console.info(`CUid for ${i} is: ${AudioCapturerChangeInfoArray[i].clientUid}`); - console.info(`Src for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.source}`); - console.info(`Flag ${i} is: ${AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags}`); - console.info(`State for ${i} is: ${AudioCapturerChangeInfoArray[i].capturerState}`); - var devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors; - for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) { - console.info(`Id: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id}`); - console.info(`Type: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType}`); - console.info(`Role: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole}`); - console.info(`Name: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name}`); - console.info(`Addr: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address}`); - console.info(`SR: ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]}`); - console.info(`C ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]}`); - console.info(`CM ${i} : ${AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks}`); - } - if (AudioCapturerChangeInfoArray[i].capturerState == 1 && devDescriptor != null) { - resultFlag = true; - console.info(`ResultFlag for element ${i} is: ${resultFlag}`); - } +### getStreamInfo8+ + +getStreamInfo(callback: AsyncCallback): void + +获取采集器流信息。使用callback方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Capturer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :------------------------------- | +| callback | AsyncCallback<[AudioStreamInfo](#audiostreaminfo8)\> | 是 | 使用callback方式异步返回流信息。 | + +**示例:** + +```js +audioCapturer.getStreamInfo((err, streamInfo) => { + if (err) { + console.error('Failed to get stream info'); + } else { + console.info('Capturer GetStreamInfo:'); + console.info(`Capturer sampling rate: ${streamInfo.samplingRate}`); + console.info(`Capturer channel: ${streamInfo.channels}`); + console.info(`Capturer format: ${streamInfo.sampleFormat}`); + console.info(`Capturer encoding type: ${streamInfo.encodingType}`); } }); ``` -## AudioDeviceDescriptor +### getStreamInfo8+ -描述音频设备。 +getStreamInfo(): Promise -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Device +获取采集器流信息。使用Promise方式异步返回结果。 -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ----------------------------- | -------------------------- | ---- | ---- | ---------- | -| deviceRole | [DeviceRole](#devicerole) | 是 | 否 | 设备角色。 | -| deviceType | [DeviceType](#devicetype) | 是 | 否 | 设备类型。 | -| id9+ | number | 是 | 否 | 设备id。 | -| name9+ | string | 是 | 否 | 设备名称。 | -| address9+ | string | 是 | 否 | 设备地址。 | -| sampleRates9+ | Array<number> | 是 | 否 | 支持的采样率。 | -| channelCounts9+ | Array<number> | 是 | 否 | 支持的通道数。 | -| channelMasks9+ | Array<number> | 是 | 否 | 支持的通道掩码。 | -| networkId9+ | string | 是 | 否 | 设备组网的ID。
此接口为系统接口,三方应用不支持调用。 | -| interruptGroupId9+ | number | 是 | 否 | 设备所处的焦点组ID。
此接口为系统接口,三方应用不支持调用。 | -| volumeGroupId9+ | number | 是 | 否 | 设备所处的音量组ID。
此接口为系统接口,三方应用不支持调用。 | +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -## AudioDeviceDescriptors +**返回值:** -设备属性数组类型,为[AudioDeviceDescriptor](#audiodevicedescriptor)的数组,只读。 +| 类型 | 说明 | +| :--------------------------------------------- | :------------------------------ | +| Promise<[AudioStreamInfo](#audiostreaminfo8)\> | 使用Promise方式异步返回流信息。 | **示例:** ```js -import audio from '@ohos.multimedia.audio'; - -function displayDeviceProp(value) { - deviceRoleValue = value.deviceRole; - deviceTypeValue = value.deviceType; -} - -let deviceRoleValue = null; -let deviceTypeValue = null; -const promise = audio.getAudioManager().getDevices(1); -promise.then(function (value) { - console.info('AudioFrameworkTest: Promise: getDevices OUTPUT_DEVICES_FLAG'); - value.forEach(displayDeviceProp); - if (deviceTypeValue != null && deviceRoleValue != null){ - console.info('AudioFrameworkTest: Promise: getDevices : OUTPUT_DEVICES_FLAG : PASS'); - } else { - console.error('AudioFrameworkTest: Promise: getDevices : OUTPUT_DEVICES_FLAG : FAIL'); - } +audioCapturer.getStreamInfo().then((audioParamsGet) => { + console.info('getStreamInfo:'); + console.info(`sampleFormat: ${audioParamsGet.sampleFormat}`); + console.info(`samplingRate: ${audioParamsGet.samplingRate}`); + console.info(`channels: ${audioParamsGet.channels}`); + console.info(`encodingType: ${audioParamsGet.encodingType}`); +}).catch((err) => { + console.error(`getStreamInfo :ERROR: ${err}`); }); ``` -## AudioRendererFilter9+ +### getAudioStreamId9+ -过滤条件类。在调用selectOutputDeviceByFilter接口前,需要先创建AudioRendererFilter实例。 +getAudioStreamId(callback: AsyncCallback): void -**系统接口:** 该接口为系统接口 +获取音频流id,使用callback方式异步返回结果。 -| 名称 | 类型 | 必填 | 说明 | -| -------------| ---------------------------------------- | ---- | -------------- | -| uid | number | 是 | 表示应用ID。
**系统能力:** SystemCapability.Multimedia.Audio.Core| -| rendererInfo | [AudioRendererInfo](#audiorendererinfo8) | 否 | 表示渲染器信息。
**系统能力:** SystemCapability.Multimedia.Audio.Renderer| -| rendererId | number | 否 | 音频流唯一id。
**系统能力:** SystemCapability.Multimedia.Audio.Renderer| +**系统能力:** SystemCapability.Multimedia.Audio.Capturer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :------------------- | +| callback | AsyncCallback | 是 | 回调返回音频流id。 | **示例:** ```js -let outputAudioRendererFilter = { - "uid":20010041, - "rendererInfo": { - "contentType":audio.ContentType.CONTENT_TYPE_MUSIC, - "streamUsage":audio.StreamUsage.STREAM_USAGE_MEDIA, - "rendererFlags":0 }, - "rendererId":0 }; +audioCapturer.getAudioStreamId((err, streamid) => { + console.info(`audioCapturer GetStreamId: ${streamid}`); +}); ``` -## AudioRenderer8+ +### getAudioStreamId9+ -提供音频渲染的相关接口。在调用AudioRenderer的接口前,需要先通过[createAudioRenderer](#audiocreateaudiorenderer8)创建实例。 +getAudioStreamId(): Promise -### 属性 +获取音频流id,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -| 名称 | 类型 | 可读 | 可写 | 说明 | -| ----- | -------------------------- | ---- | ---- | ------------------ | -| state8+ | [AudioState](#audiostate8) | 是 | 否 | 音频渲染器的状态。 | +**返回值:** + +| 类型 | 说明 | +| :----------------| :--------------------- | +| Promise | Promise返回音频流id。 | **示例:** ```js -let state = audioRenderer.state; +audioCapturer.getAudioStreamId().then((streamid) => { + console.info(`audioCapturer getAudioStreamId: ${streamid}`); +}).catch((err) => { + console.error(`ERROR: ${err}`); +}); ``` -### getRendererInfo8+ +### start8+ -getRendererInfo(callback: AsyncCallback): void +start(callback: AsyncCallback): void -获取当前被创建的音频渲染器的信息,使用callback方式异步返回结果。 +启动音频采集器。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------------------------------------------- | :--- | :--------------------- | -| callback | AsyncCallback<[AudioRendererInfo](#audiorendererinfo8)\> | 是 | 返回音频渲染器的信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :----------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -audioRenderer.getRendererInfo((err, rendererInfo) => { - console.info('Renderer GetRendererInfo:'); - console.info(`Renderer content: ${rendererInfo.content}`); - console.info(`Renderer usage: ${rendererInfo.usage}`); - console.info(`Renderer flags: ${rendererInfo.rendererFlags}`); +audioCapturer.start((err) => { + if (err) { + console.error('Capturer start failed.'); + } else { + console.info('Capturer start success.'); + } }); ``` -### getRendererInfo8+ -getRendererInfo(): Promise +### start8+ + +start(): Promise -获取当前被创建的音频渲染器的信息,使用Promise方式异步返回结果。 +启动音频采集器。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **返回值:** -| 类型 | 说明 | -| -------------------------------------------------- | ------------------------------- | -| Promise<[AudioRendererInfo](#audiorendererinfo8)\> | Promise用于返回音频渲染器信息。 | +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.getRendererInfo().then((rendererInfo) => { - console.info('Renderer GetRendererInfo:'); - console.info(`Renderer content: ${rendererInfo.content}`); - console.info(`Renderer usage: ${rendererInfo.usage}`); - console.info(`Renderer flags: ${rendererInfo.rendererFlags}`) +audioCapturer.start().then(() => { + console.info('AudioFrameworkRecLog: ---------START---------'); + console.info('AudioFrameworkRecLog: Capturer started: SUCCESS'); + console.info(`AudioFrameworkRecLog: AudioCapturer: STATE: ${audioCapturer.state}`); + console.info('AudioFrameworkRecLog: Capturer started: SUCCESS'); + if ((audioCapturer.state == audio.AudioState.STATE_RUNNING)) { + console.info('AudioFrameworkRecLog: AudioCapturer is in Running State'); + } }).catch((err) => { - console.error(`AudioFrameworkRenderLog: RendererInfo :ERROR: ${err}`); + console.info(`AudioFrameworkRecLog: Capturer start :ERROR : ${err}`); }); ``` -### getStreamInfo8+ +### stop8+ -getStreamInfo(callback: AsyncCallback): void +stop(callback: AsyncCallback): void -获取音频流信息,使用callback方式异步返回结果。 +停止采集。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------------------------------------- | :--- | :------------------- | -| callback | AsyncCallback<[AudioStreamInfo](#audiostreaminfo8)\> | 是 | 回调返回音频流信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :----------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -audioRenderer.getStreamInfo((err, streamInfo) => { - console.info('Renderer GetStreamInfo:'); - console.info(`Renderer sampling rate: ${streamInfo.samplingRate}`); - console.info(`Renderer channel: ${streamInfo.channels}`); - console.info(`Renderer format: ${streamInfo.sampleFormat}`); - console.info(`Renderer encoding type: ${streamInfo.encodingType}`); +audioCapturer.stop((err) => { + if (err) { + console.error('Capturer stop failed'); + } else { + console.info('Capturer stopped.'); + } }); ``` -### getStreamInfo8+ -getStreamInfo(): Promise +### stop8+ -获取音频流信息,使用Promise方式异步返回结果。 +stop(): Promise -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +停止采集。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **返回值:** -| 类型 | 说明 | -| :--------------------------------------------- | :--------------------- | -| Promise<[AudioStreamInfo](#audiostreaminfo8)\> | Promise返回音频流信息. | +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.getStreamInfo().then((streamInfo) => { - console.info('Renderer GetStreamInfo:'); - console.info(`Renderer sampling rate: ${streamInfo.samplingRate}`); - console.info(`Renderer channel: ${streamInfo.channels}`); - console.info(`Renderer format: ${streamInfo.sampleFormat}`); - console.info(`Renderer encoding type: ${streamInfo.encodingType}`); +audioCapturer.stop().then(() => { + console.info('AudioFrameworkRecLog: ---------STOP RECORD---------'); + console.info('AudioFrameworkRecLog: Capturer stopped: SUCCESS'); + if ((audioCapturer.state == audio.AudioState.STATE_STOPPED)){ + console.info('AudioFrameworkRecLog: State is Stopped:'); + } }).catch((err) => { - console.error(`ERROR: ${err}`); + console.info(`AudioFrameworkRecLog: Capturer stop: ERROR: ${err}`); }); ``` -### start8+ +### release8+ -start(callback: AsyncCallback): void +release(callback: AsyncCallback): void -启动音频渲染器。使用callback方式异步返回结果。 +释放采集器。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------- | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :---------------------------------- | +| callback | AsyncCallback | 是 | Callback used to return the result. | **示例:** ```js -audioRenderer.start((err) => { +audioCapturer.release((err) => { if (err) { - console.error('Renderer start failed.'); + console.error('capturer release failed'); } else { - console.info('Renderer start success.'); + console.info('capturer released.'); } }); ``` -### start8+ -start(): Promise +### release8+ -启动音频渲染器。使用Promise方式异步返回结果。 +release(): Promise -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +释放采集器。使用Promise方式异步返回结果。 + +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **返回值:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise方式异步返回结果。 | +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.start().then(() => { - console.info('Renderer started'); +let stateFlag; +audioCapturer.release().then(() => { + console.info('AudioFrameworkRecLog: ---------RELEASE RECORD---------'); + console.info('AudioFrameworkRecLog: Capturer release : SUCCESS'); + console.info(`AudioFrameworkRecLog: AudioCapturer : STATE : ${audioCapturer.state}`); + console.info(`AudioFrameworkRecLog: stateFlag : ${stateFlag}`); }).catch((err) => { - console.error(`ERROR: ${err}`); + console.info(`AudioFrameworkRecLog: Capturer stop: ERROR: ${err}`); }); ``` -### pause8+ +### read8+ -pause(callback: AsyncCallback\): void +read(size: number, isBlockingRead: boolean, callback: AsyncCallback): void -暂停渲染。使用callback方式异步返回结果。 +读入缓冲区。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------- | -| callback | AsyncCallback\ | 是 | 返回回调的结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------------- | :-------------------------- | :--- | :------------------------------- | +| size | number | 是 | 读入的字节数。 | +| isBlockingRead | boolean | 是 | 是否阻塞读操作。 | +| callback | AsyncCallback | 是 | 使用callback方式异步返回缓冲区。 | **示例:** ```js -audioRenderer.pause((err) => { - if (err) { - console.error('Renderer pause failed'); - } else { - console.info('Renderer paused.'); +let bufferSize; +audioCapturer.getBufferSize().then((data) => { + console.info(`AudioFrameworkRecLog: getBufferSize: SUCCESS ${data}`); + bufferSize = data; + }).catch((err) => { + console.error(`AudioFrameworkRecLog: getBufferSize: ERROR: ${err}`); + }); +audioCapturer.read(bufferSize, true, async(err, buffer) => { + if (!err) { + console.info('Success in reading the buffer data'); } }); ``` -### pause8+ +### read8+ -pause(): Promise\ +read(size: number, isBlockingRead: boolean): Promise -暂停渲染。使用Promise方式异步返回结果。 +读入缓冲区。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------------- | :------ | :--- | :--------------- | +| size | number | 是 | 读入的字节数。 | +| isBlockingRead | boolean | 是 | 是否阻塞读操作。 | **返回值:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise方式异步返回结果。 | +| 类型 | 说明 | +| :-------------------- | :----------------------------------------------------- | +| Promise | 如果操作成功,返回读取的缓冲区数据;否则返回错误代码。 | **示例:** ```js -audioRenderer.pause().then(() => { - console.info('Renderer paused'); +let bufferSize; +audioCapturer.getBufferSize().then((data) => { + console.info(`AudioFrameworkRecLog: getBufferSize: SUCCESS ${data}`); + bufferSize = data; + }).catch((err) => { + console.info(`AudioFrameworkRecLog: getBufferSize: ERROR ${err}`); + }); +console.info(`Buffer size: ${bufferSize}`); +audioCapturer.read(bufferSize, true).then((buffer) => { + console.info('buffer read successfully'); }).catch((err) => { - console.error(`ERROR: ${err}`); + console.info(`ERROR : ${err}`); }); ``` -### drain8+ +### getAudioTime8+ -drain(callback: AsyncCallback\): void +getAudioTime(callback: AsyncCallback): void -检查缓冲区是否已被耗尽。使用callback方式异步返回结果。 +获取时间戳(从1970年1月1日开始),单位为纳秒。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------- | -| callback | AsyncCallback\ | 是 | 返回回调的结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------- | :--- | :----------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -audioRenderer.drain((err) => { - if (err) { - console.error('Renderer drain failed'); - } else { - console.info('Renderer drained.'); - } +audioCapturer.getAudioTime((err, timestamp) => { + console.info(`Current timestamp: ${timestamp}`); }); ``` -### drain8+ +### getAudioTime8+ -drain(): Promise\ +getAudioTime(): Promise -检查缓冲区是否已被耗尽。使用Promise方式异步返回结果。 +获取时间戳(从1970年1月1日开始),单位为纳秒。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **返回值:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise方式异步返回结果。 | +| 类型 | 说明 | +| :--------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.drain().then(() => { - console.info('Renderer drained successfully'); +audioCapturer.getAudioTime().then((audioTime) => { + console.info(`AudioFrameworkRecLog: AudioCapturer getAudioTime : Success ${audioTime}`); }).catch((err) => { - console.error(`ERROR: ${err}`); + console.info(`AudioFrameworkRecLog: AudioCapturer Created : ERROR : ${err}`); }); ``` -### stop8+ +### getBufferSize8+ -stop(callback: AsyncCallback\): void +getBufferSize(callback: AsyncCallback): void -停止渲染。使用callback方式异步返回结果。 +获取采集器合理的最小缓冲区大小。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------- | -| callback | AsyncCallback\ | 是 | 返回回调的结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------- | :--- | :----------------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回缓冲区大小。 | **示例:** -```js -audioRenderer.stop((err) => { - if (err) { - console.error('Renderer stop failed'); - } else { - console.info('Renderer stopped.'); +```js +audioCapturer.getBufferSize((err, bufferSize) => { + if (!err) { + console.info(`BufferSize : ${bufferSize}`); + audioCapturer.read(bufferSize, true).then((buffer) => { + console.info(`Buffer read is ${buffer}`); + }).catch((err) => { + console.error(`AudioFrameworkRecLog: AudioCapturer Created : ERROR : ${err}`); + }); } }); ``` -### stop8+ +### getBufferSize8+ -stop(): Promise\ +getBufferSize(): Promise -停止渲染。使用Promise方式异步返回结果。 +获取采集器合理的最小缓冲区大小。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **返回值:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise方式异步返回结果。 | +| 类型 | 说明 | +| :--------------- | :---------------------------------- | +| Promise | 使用Promise方式异步返回缓冲区大小。 | **示例:** ```js -audioRenderer.stop().then(() => { - console.info('Renderer stopped successfully'); +let bufferSize; +audioCapturer.getBufferSize().then((data) => { + console.info(`AudioFrameworkRecLog: getBufferSize :SUCCESS ${data}`); + bufferSize = data; }).catch((err) => { - console.error(`ERROR: ${err}`); + console.info(`AudioFrameworkRecLog: getBufferSize :ERROR : ${err}`); }); ``` -### release8+ +### on('markReach')8+ -release(callback: AsyncCallback\): void +on(type: "markReach", frame: number, callback: Callback<number>): void -释放音频渲染器。使用callback方式异步返回结果。 +订阅标记到达的事件。 当采集的帧数达到 frame 参数的值时,回调被触发。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | ---------------- | -| callback | AsyncCallback\ | 是 | 返回回调的结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :---------------------- | :--- | :----------------------------------------- | +| type | string | 是 | 事件回调类型,支持的事件为:'markReach'。 | +| frame | number | 是 | 触发事件的帧数。 该值必须大于0。 | +| callback | Callback\ | 是 | 使用callback方式异步返回被触发事件的回调。 | **示例:** ```js -audioRenderer.release((err) => { - if (err) { - console.error('Renderer release failed'); - } else { - console.info('Renderer released.'); +audioCapturer.on('markReach', 1000, (position) => { + if (position == 1000) { + console.info('ON Triggered successfully'); } }); ``` -### release8+ +### off('markReach')8+ -release(): Promise\ +off(type: 'markReach'): void -释放渲染器。使用Promise方式异步返回结果。 +取消订阅标记到达的事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -**返回值:** +**参数:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :----- | :----- | :--- | :-------------------------------------------- | +| type | string | 是 | 取消事件回调类型,支持的事件为:'markReach'。 | **示例:** ```js -audioRenderer.release().then(() => { - console.info('Renderer released successfully'); -}).catch((err) => { - console.error(`ERROR: ${err}`); -}); +audioCapturer.off('markReach'); ``` -### write8+ +### on('periodReach')8+ -write(buffer: ArrayBuffer, callback: AsyncCallback\): void +on(type: "periodReach", frame: number, callback: Callback<number>): void -写入缓冲区。使用callback方式异步返回结果。 +订阅到达标记的事件。 当采集的帧数达到 frame 参数的值时,回调被循环调用。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ---------------------- | ---- | --------------------------------------------------- | -| buffer | ArrayBuffer | 是 | 要写入缓冲区的数据。 | -| callback | AsyncCallback\ | 是 | 回调如果成功,返回写入的字节数,否则返回errorcode。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :----------------------- | :--- | :------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'periodReach'。 | +| frame | number | 是 | 触发事件的帧数。 该值必须大于0。 | +| callback | Callback\ | 是 | 使用callback方式异步返回被触发事件的回调 | **示例:** ```js -let bufferSize; -audioRenderer.getBufferSize().then((data)=> { - console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); - bufferSize = data; - }).catch((err) => { - console.error(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); - }); -console.info(`Buffer size: ${bufferSize}`); -let context = featureAbility.getContext(); -let path; -async function getCacheDir(){ - path = await context.getCacheDir(); -} -let filePath = path + '/StarWars10s-2C-48000-4SW.wav'; -let ss = fileio.createStreamSync(filePath, 'r'); -let buf = new ArrayBuffer(bufferSize); -ss.readSync(buf); -audioRenderer.write(buf, (err, writtenbytes) => { - if (writtenbytes < 0) { - console.error('write failed.'); - } else { - console.info(`Actual written bytes: ${writtenbytes}`); +audioCapturer.on('periodReach', 1000, (position) => { + if (position == 1000) { + console.info('ON Triggered successfully'); } }); ``` -### write8+ +### off('periodReach')8+ -write(buffer: ArrayBuffer): Promise\ +off(type: 'periodReach'): void -写入缓冲区。使用Promise方式异步返回结果。 +取消订阅标记到达的事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer -**返回值:** +**参数:** -| 类型 | 说明 | -| ---------------- | ------------------------------------------------------------ | -| Promise\ | Promise返回结果,如果成功,返回写入的字节数,否则返回errorcode。 | +| 参数名 | 类型 | 必填 | 说明 | +| :----- | :----- | :--- | :---------------------------------------------- | +| type | string | 是 | 取消事件回调类型,支持的事件为:'periodReach'。 | **示例:** ```js -let bufferSize; -audioRenderer.getBufferSize().then((data) => { - console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); - bufferSize = data; - }).catch((err) => { - console.info(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); - }); -console.info(`BufferSize: ${bufferSize}`); -let context = featureAbility.getContext(); -let path; -async function getCacheDir(){ - path = await context.getCacheDir(); -} -let filePath = path + '/StarWars10s-2C-48000-4SW.wav'; -let ss = fileio.createStreamSync(filePath, 'r'); -let buf = new ArrayBuffer(bufferSize); -ss.readSync(buf); -audioRenderer.write(buf).then((writtenbytes) => { - if (writtenbytes < 0) { - console.error('write failed.'); - } else { - console.info(`Actual written bytes: ${writtenbytes}`); - } -}).catch((err) => { - console.error(`ERROR: ${err}`); -}); +audioCapturer.off('periodReach') ``` -### getAudioTime8+ +### on('stateChange') 8+ -getAudioTime(callback: AsyncCallback\): void +on(type: 'stateChange', callback: Callback): void -获取时间戳(从 1970 年 1 月 1 日开始)。使用callback方式异步返回结果。 +订阅监听状态变化。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Capturer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ---------------------- | ---- | ---------------- | -| callback | AsyncCallback\ | 是 | 回调返回时间戳。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------------- | :--- | :------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'stateChange'。 | +| callback | [AudioState](#audiostate8) | 是 | 返回监听的状态。 | **示例:** ```js -audioRenderer.getAudioTime((err, timestamp) => { - console.info(`Current timestamp: ${timestamp}`); +audioCapturer.on('stateChange', (state) => { + if (state == 1) { + console.info('audio capturer state is: STATE_PREPARED'); + } + if (state == 2) { + console.info('audio capturer state is: STATE_RUNNING'); + } }); ``` -### getAudioTime8+ +## ToneType 9+ -getAudioTime(): Promise\ +枚举,播放器的音调类型。 -获取时间戳(从 1970 年 1 月 1 日开始)。使用Promise方式异步返回结果。 +**系统接口:** 该接口为系统接口 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Tone -**返回值:** +| 名称 | 默认值 | 描述 | +| :------------------------------------------------ | :----- | :----------------------------| +| TONE_TYPE_DIAL_0 | 0 | 键0的DTMF音。 | +| TONE_TYPE_DIAL_1 | 1 | 键1的DTMF音。 | +| TONE_TYPE_DIAL_2 | 2 | 键2的DTMF音。 | +| TONE_TYPE_DIAL_3 | 3 | 键3的DTMF音。 | +| TONE_TYPE_DIAL_4 | 4 | 键4的DTMF音。 | +| TONE_TYPE_DIAL_5 | 5 | 键5的DTMF音。 | +| TONE_TYPE_DIAL_6 | 6 | 键6的DTMF音。 | +| TONE_TYPE_DIAL_7 | 7 | 键7的DTMF音。 | +| TONE_TYPE_DIAL_8 | 8 | 键8的DTMF音。 | +| TONE_TYPE_DIAL_9 | 9 | 键9的DTMF音。 | +| TONE_TYPE_DIAL_S | 10 | 键*的DTMF音。 | +| TONE_TYPE_DIAL_P | 11 | 键#的DTMF音。 | +| TONE_TYPE_DIAL_A | 12 | 键A的DTMF音。 | +| TONE_TYPE_DIAL_B | 13 | 键B的DTMF音。 | +| TONE_TYPE_DIAL_C | 14 | 键C的DTMF音。 | +| TONE_TYPE_DIAL_D | 15 | 键D的DTMF音。 | +| TONE_TYPE_COMMON_SUPERVISORY_DIAL | 100 | 呼叫监管音调,拨号音。 | +| TONE_TYPE_COMMON_SUPERVISORY_BUSY | 101 | 呼叫监管音调,忙。 | +| TONE_TYPE_COMMON_SUPERVISORY_CONGESTION | 102 | 呼叫监管音调,拥塞。 | +| TONE_TYPE_COMMON_SUPERVISORY_RADIO_ACK | 103 | 呼叫监管音调,无线电 ACK。 | +| TONE_TYPE_COMMON_SUPERVISORY_RADIO_NOT_AVAILABLE | 104 | 呼叫监管音调,无线电不可用。 | +| TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING | 106 | 呼叫监管音调,呼叫等待。 | +| TONE_TYPE_COMMON_SUPERVISORY_RINGTONE | 107 | 呼叫监管音调,铃声。 | +| TONE_TYPE_COMMON_PROPRIETARY_BEEP | 200 | 专有声调,一般蜂鸣声。 | +| TONE_TYPE_COMMON_PROPRIETARY_ACK | 201 | 专有声调,ACK。 | +| TONE_TYPE_COMMON_PROPRIETARY_PROMPT | 203 | 专有声调,PROMPT。 | +| TONE_TYPE_COMMON_PROPRIETARY_DOUBLE_BEEP | 204 | 专有声调,双重蜂鸣声。 | -| 类型 | 描述 | -| ---------------- | ----------------------- | -| Promise\ | Promise回调返回时间戳。 | +## TonePlayer9+ -**示例:** +提供播放和管理DTMF(Dual Tone Multi Frequency,双音多频)音调的方法,包括各种系统监听音调、专有音调,如拨号音、通话回铃音等。 -```js -audioRenderer.getAudioTime().then((timestamp) => { - console.info(`Current timestamp: ${timestamp}`); -}).catch((err) => { - console.error(`ERROR: ${err}`); -}); -``` +**系统接口:** 该接口为系统接口 -### getBufferSize8+ +### load9+ -getBufferSize(callback: AsyncCallback\): void +load(type: ToneType, callback: AsyncCallback<void>): void -获取音频渲染器的最小缓冲区大小。使用callback方式异步返回结果。 +加载DTMF音调配置。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Tone **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ---------------------- | ---- | -------------------- | -| callback | AsyncCallback\ | 是 | 回调返回缓冲区大小。 | +| 参数名 | 类型 | 必填 | 说明 | +| :--------------| :-------------------------- | :-----| :------------------------------ | +| type | ToneType(#tonetype9) | 是 | 配置的音调类型。 | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -let bufferSize = audioRenderer.getBufferSize(async(err, bufferSize) => { +tonePlayer.load(audio.ToneType.TONE_TYPE_DIAL_5, (err) => { if (err) { - console.error('getBufferSize error'); + console.error(`callback call load failed error: ${err.message}`); + return; + } else { + console.info('callback call load success'); } }); ``` -### getBufferSize8+ +### load9+ -getBufferSize(): Promise\ +load(type: ToneType): Promise<void> -获取音频渲染器的最小缓冲区大小。使用Promise方式异步返回结果。 +加载DTMF音调配置。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Tone + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| :------------- | :--------------------- | :--- | ---------------- | +| type | ToneType(#tonetype9) | 是 | 配置的音调类型。 | **返回值:** -| 类型 | 说明 | -| ---------------- | --------------------------- | -| Promise\ | promise回调返回缓冲区大小。 | +| 类型 | 说明 | +| :--------------| :-------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -let bufferSize; -audioRenderer.getBufferSize().then((data) => { - console.info(`AudioFrameworkRenderLog: getBufferSize: SUCCESS ${data}`); - bufferSize = data; -}).catch((err) => { - console.error(`AudioFrameworkRenderLog: getBufferSize: ERROR: ${err}`); +tonePlayer.load(audio.ToneType.TONE_TYPE_DIAL_1).then(() => { + console.info('promise call load '); +}).catch(() => { + console.error('promise call load fail'); }); ``` -### setRenderRate8+ +### start9+ -setRenderRate(rate: AudioRendererRate, callback: AsyncCallback\): void +start(callback: AsyncCallback<void>): void -设置音频渲染速率。使用callback方式异步返回结果。 +启动DTMF音调播放。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Tone **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------- | ---- | ------------------------ | -| rate | [AudioRendererRate](#audiorendererrate8) | 是 | 渲染的速率。 | -| callback | AsyncCallback\ | 是 | 用于返回执行结果的回调。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :----------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -audioRenderer.setRenderRate(audio.AudioRendererRate.RENDER_RATE_NORMAL, (err) => { +tonePlayer.start((err) => { if (err) { - console.error('Failed to set params'); + console.error(`callback call start failed error: ${err.message}`); + return; } else { - console.info('Callback invoked to indicate a successful render rate setting.'); + console.info('callback call start success'); } }); ``` -### setRenderRate8+ - -setRenderRate(rate: AudioRendererRate): Promise\ - -设置音频渲染速率。使用Promise方式异步返回结果。 +### start9+ -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +start(): Promise<void> -**参数:** +启动DTMF音调播放。使用Promise方式异步返回结果。 -| 参数名 | 类型 | 必填 | 说明 | -| ------ | ---------------------------------------- | ---- | ------------ | -| rate | [AudioRendererRate](#audiorendererrate8) | 是 | 渲染的速率。 | +**系统能力:** SystemCapability.Multimedia.Audio.Tone **返回值:** -| 类型 | 说明 | -| -------------- | ------------------------- | -| Promise\ | Promise用于返回执行结果。 | +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.setRenderRate(audio.AudioRendererRate.RENDER_RATE_NORMAL).then(() => { - console.info('setRenderRate SUCCESS'); -}).catch((err) => { - console.error(`ERROR: ${err}`); +tonePlayer.start().then(() => { + console.info('promise call start'); +}).catch(() => { + console.error('promise call start fail'); }); ``` -### getRenderRate8+ +### stop9+ -getRenderRate(callback: AsyncCallback\): void +stop(callback: AsyncCallback<void>): void -获取当前渲染速率。使用callback方式异步返回结果。 +停止当前正在播放的音调。使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Tone **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ------------------------------------------------------- | ---- | ------------------ | -| callback | AsyncCallback<[AudioRendererRate](#audiorendererrate8)> | 是 | 回调返回渲染速率。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :----------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -audioRenderer.getRenderRate((err, renderrate) => { - console.info(`getRenderRate: ${renderrate}`); +tonePlayer.stop((err) => { + if (err) { + console.error(`callback call stop error: ${err.message}`); + return; + } else { + console.error('callback call stop success '); + } }); ``` -### getRenderRate8+ +### stop9+ -getRenderRate(): Promise\ +stop(): Promise<void> -获取当前渲染速率。使用Promise方式异步返回结果。 +停止当前正在播放的音调。使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Tone **返回值:** -| 类型 | 说明 | -| ------------------------------------------------- | ------------------------- | -| Promise<[AudioRendererRate](#audiorendererrate8)> | Promise回调返回渲染速率。 | +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -audioRenderer.getRenderRate().then((renderRate) => { - console.info(`getRenderRate: ${renderRate}`); -}).catch((err) => { - console.error(`ERROR: ${err}`); +tonePlayer.stop().then(() => { + console.info('promise call stop finish'); +}).catch(() => { + console.error('promise call stop fail'); }); ``` -### setInterruptMode9+ - -setInterruptMode(mode: InterruptMode): Promise<void> -设置应用的焦点模型。使用Promise异步回调。 +### release9+ -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +release(callback: AsyncCallback<void>): void -**参数:** +释放与此TonePlay对象关联的资源。使用callback方式异步返回结果。 -| 参数名 | 类型 | 必填 | 说明 | -| ---------- | ---------------------------------- | ------ | ---------- | -| mode | [InterruptMode](#interruptmode9) | 是 | 焦点模型。 | +**系统能力:** SystemCapability.Multimedia.Audio.Tone -**返回值:** +**参数:** -| 类型 | 说明 | -| ------------------- | ----------------------------- | -| Promise<void> | 以Promise对象返回结果,设置成功时返回undefined,否则返回error。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :------------------- | :--- | :---------------------------- | +| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | **示例:** ```js -let mode = 0; -audioRenderer.setInterruptMode(mode).then(data=>{ - console.info('setInterruptMode Success!'); -}).catch((err) => { - console.error(`setInterruptMode Fail: ${err}`); +tonePlayer.release((err) => { + if (err) { + console.error(`callback call release failed error: ${err.message}`); + return; + } else { + console.info('callback call release success '); + } }); ``` -### setInterruptMode9+ -setInterruptMode(mode: InterruptMode, callback: AsyncCallback\): void +### release9+ -设置应用的焦点模型。使用Callback回调返回执行结果。 +release(): Promise<void> -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +释放与此TonePlay对象关联的资源。使用Promise方式异步返回结果。 -**参数:** +**系统能力:** SystemCapability.Multimedia.Audio.Tone -| 参数名 | 类型 | 必填 | 说明 | -| ------- | ----------------------------------- | ------ | -------------- | -|mode | [InterruptMode](#interruptmode9) | 是 | 焦点模型。| -|callback | AsyncCallback\ | 是 |回调返回执行结果。| +**返回值:** + +| 类型 | 说明 | +| :------------- | :---------------------------- | +| Promise | 使用Promise方式异步返回结果。 | **示例:** ```js -let mode = 1; -audioRenderer.setInterruptMode(mode, (err, data)=>{ - if(err){ - console.error(`setInterruptMode Fail: ${err}`); - } - console.info('setInterruptMode Success!'); +tonePlayer.release().then(() => { + console.info('promise call release'); +}).catch(() => { + console.error('promise call release fail'); }); ``` -### on('interrupt')9+ -on(type: 'interrupt', callback: Callback\): void - -监听音频中断事件。使用callback获取中断事件。 +## ActiveDeviceType(deprecated) -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +枚举,活跃设备类型。 -**参数:** +> **说明:** +> 从 API version 9 开始废弃,建议使用[CommunicationDeviceType](#communicationdevicetype9)替代。 -| 参数名 | 类型 | 必填 | 说明 | -| -------- | -------------------------------------------- | ---- | ------------------------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'interrupt'(中断事件被触发,音频播放被中断。) | -| callback | Callback<[InterruptEvent](#interruptevent9)> | 是 | 被监听的中断事件的回调。 | +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Device -**示例:** +| 名称 | 默认值 | 描述 | +| ------------- | ------ | ---------------------------------------------------- | +| SPEAKER | 2 | 扬声器。 | +| BLUETOOTH_SCO | 7 | 蓝牙设备SCO(Synchronous Connection Oriented)连接。 | -```js -let isPlay; -let started; -audioRenderer.on('interrupt', async(interruptEvent) => { - if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_FORCE) { - switch (interruptEvent.hintType) { - case audio.InterruptHint.INTERRUPT_HINT_PAUSE: - console.info('Force paused. Stop writing'); - isPlay = false; - break; - case audio.InterruptHint.INTERRUPT_HINT_STOP: - console.info('Force stopped. Stop writing'); - isPlay = false; - break; - } - } else if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_SHARE) { - switch (interruptEvent.hintType) { - case audio.InterruptHint.INTERRUPT_HINT_RESUME: - console.info('Resume force paused renderer or ignore'); - await audioRenderer.start().then(async function () { - console.info('AudioInterruptMusic: renderInstant started :SUCCESS '); - started = true; - }).catch((err) => { - console.error(`AudioInterruptMusic: renderInstant start :ERROR : ${err}`); - started = false; - }); - if (started) { - isPlay = true; - console.info(`AudioInterruptMusic Renderer started : isPlay : ${isPlay}`); - } else { - console.error('AudioInterruptMusic Renderer start failed'); - } - break; - case audio.InterruptHint.INTERRUPT_HINT_PAUSE: - console.info('Choose to pause or ignore'); - if (isPlay == true) { - isPlay == false; - console.info('AudioInterruptMusic: Media PAUSE : TRUE'); - } else { - isPlay = true; - console.info('AudioInterruptMusic: Media PLAY : TRUE'); - } - break; - } - } -}); -``` +## InterruptActionType(deprecated) -### on('markReach')8+ +枚举,中断事件返回类型。 -on(type: "markReach", frame: number, callback: Callback<number>): void +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃。 -订阅到达标记的事件。 当渲染的帧数达到 frame 参数的值时,回调被调用。 +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +| 名称 | 默认值 | 描述 | +| -------------- | ------ | ------------------ | +| TYPE_ACTIVATED | 0 | 表示触发焦点事件。 | +| TYPE_INTERRUPT | 1 | 表示音频打断事件。 | -**参数:** +## AudioInterrupt(deprecated) -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :----------------------- | :--- | :---------------------------------------- | -| type | string | 是 | 事件回调类型,支持的事件为:'markReach'。 | -| frame | number | 是 | 触发事件的帧数。 该值必须大于 0。 | -| callback | Callback\ | 是 | 触发事件时调用的回调。 | +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃。 -**示例:** +音频监听事件传入的参数。 -```js -audioRenderer.on('markReach', 1000, (position) => { - if (position == 1000) { - console.info('ON Triggered successfully'); - } -}); -``` +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer +| 名称 | 类型 | 必填 | 说明 | +| --------------- | --------------------------- | ---- | ------------------------------------------------------------ | +| streamUsage | [StreamUsage](#streamusage) | 是 | 音频流使用类型。 | +| contentType | [ContentType](#contenttype) | 是 | 音频打断媒体类型。 | +| pauseWhenDucked | boolean | 是 | 音频打断时是否可以暂停音频播放(true表示音频播放可以在音频打断期间暂停,false表示相反)。 | -### off('markReach') 8+ +## InterruptAction(deprecated) -off(type: 'markReach'): void +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃。 -取消订阅标记事件。 +音频打断/获取焦点事件的回调方法。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Renderer -**参数:** +| 名称 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | +| actionType | [InterruptActionType](#interruptactiontype) | 是 | 事件返回类型。TYPE_ACTIVATED为焦点触发事件,TYPE_INTERRUPT为音频打断事件。 | +| type | [InterruptType](#interrupttype) | 否 | 打断事件类型。 | +| hint | [InterruptHint](#interrupthint) | 否 | 打断事件提示。 | +| activated | boolean | 否 | 获得/释放焦点。true表示焦点获取/释放成功,false表示焦点获得/释放失败。 | -| 参数名 | 类型 | 必填 | 说明 | -| :----- | :----- | :--- | :------------------------------------------------ | -| type | string | 是 | 要取消订阅事件的类型。支持的事件为:'markReach'。 | +### setVolume(deprecated) -**示例:** +setVolume(volumeType: AudioVolumeType, volume: number, callback: AsyncCallback<void>): void -```js -audioRenderer.off('markReach'); -``` +设置指定流的音量,使用callback方式异步返回结果。 -### on('periodReach') 8+ +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setVolume](#setvolume9)替代。 -on(type: "periodReach", frame: number, callback: Callback<number>): void +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -订阅到达标记的事件。 当渲染的帧数达到 frame 参数的值时,回调被循环调用。 +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :----------------------- | :--- | :------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'periodReach'。 | -| frame | number | 是 | 触发事件的帧数。 该值必须大于 0。 | -| callback | Callback\ | 是 | 触发事件时调用的回调。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | +| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | **示例:** ```js -audioRenderer.on('periodReach', 1000, (position) => { - if (position == 1000) { - console.info('ON Triggered successfully'); +audioManager.setVolume(audio.AudioVolumeType.MEDIA, 10, (err) => { + if (err) { + console.error(`Failed to set the volume. ${err}`); + return; } + console.info('Callback invoked to indicate a successful volume setting.'); }); ``` -### off('periodReach') 8+ +### setVolume(deprecated) -off(type: 'periodReach'): void +setVolume(volumeType: AudioVolumeType, volume: number): Promise<void> -取消订阅标记事件。 +设置指定流的音量,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setVolume](#setvolume9)替代。 + +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :----- | :----- | :--- | :-------------------------------------------------- | -| type | string | 是 | 要取消订阅事件的类型。支持的事件为:'periodReach'。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | -------------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| volume | number | 是 | 音量等级,可设置范围通过getMinVolume和getMaxVolume获取。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | Promise回调表示成功还是失败。 | **示例:** ```js -audioRenderer.off('periodReach') +audioManager.setVolume(audio.AudioVolumeType.MEDIA, 10).then(() => { + console.info('Promise returned to indicate a successful volume setting.'); +}); ``` -### on('stateChange') 8+ +### getVolume(deprecated) -on(type: 'stateChange', callback: Callback): void +getVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -订阅监听状态变化。 +获取指定流的音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Renderer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getVolume](#getvolume9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------------- | :--- | :------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'stateChange'。 | -| callback | [AudioState](#audiostate8) | 是 | 返回监听的状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回音量大小。 | **示例:** ```js -audioRenderer.on('stateChange', (state) => { - if (state == 1) { - console.info('audio renderer state is: STATE_PREPARED'); - } - if (state == 2) { - console.info('audio renderer state is: STATE_RUNNING'); +audioManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { + if (err) { + console.error(`Failed to obtain the volume. ${err}`); + return; } + console.info('Callback invoked to indicate that the volume is obtained.'); }); ``` -## AudioCapturer8+ +### getVolume(deprecated) -提供音频采集的相关接口。在调用AudioCapturer的接口前,需要先通过[createAudioCapturer](#audiocreateaudiocapturer8)创建实例。 +getVolume(volumeType: AudioVolumeType): Promise<number> -### 属性 +获取指定流的音量,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getVolume](#getvolume9)替代。 -| 名称 | 类型 | 可读 | 可写 | 说明 | -| :---- | :------------------------- | :--- | :--- | :--------------- | -| state8+ | [AudioState](#audiostate8) | 是 | 否 | 音频采集器状态。 | +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | + +**返回值:** + +| 类型 | 说明 | +| --------------------- | ------------------------- | +| Promise<number> | Promise回调返回音量大小。 | **示例:** ```js -let state = audioCapturer.state; +audioManager.getVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the volume is obtained ${value} .`); +}); ``` -### getCapturerInfo8+ +### getMinVolume(deprecated) -getCapturerInfo(callback: AsyncCallback): void +getMinVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -获取采集器信息。使用callback方式异步返回结果。 +获取指定流的最小音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getMinVolume](#getminvolume9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :-------------------------------- | :--- | :----------------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回采集器信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回最小音量。 | **示例:** ```js -audioCapturer.getCapturerInfo((err, capturerInfo) => { +audioManager.getMinVolume(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error('Failed to get capture info'); - } else { - console.info('Capturer getCapturerInfo:'); - console.info(`Capturer source: ${capturerInfo.source}`); - console.info(`Capturer flags: ${capturerInfo.capturerFlags}`); + console.error(`Failed to obtain the minimum volume. ${err}`); + return; } + console.info(`Callback invoked to indicate that the minimum volume is obtained. ${value}`); }); ``` +### getMinVolume(deprecated) -### getCapturerInfo8+ +getMinVolume(volumeType: AudioVolumeType): Promise<number> -getCapturerInfo(): Promise +获取指定流的最小音量,使用Promise方式异步返回结果。 -获取采集器信息。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getMinVolume](#getminvolume9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| :------------------------------------------------ | :---------------------------------- | -| Promise<[AudioCapturerInfo](#audiocapturerinfo)\> | 使用Promise方式异步返回采集器信息。 | +| 类型 | 说明 | +| --------------------- | ------------------------- | +| Promise<number> | Promise回调返回最小音量。 | **示例:** ```js -audioCapturer.getCapturerInfo().then((audioParamsGet) => { - if (audioParamsGet != undefined) { - console.info('AudioFrameworkRecLog: Capturer CapturerInfo:'); - console.info(`AudioFrameworkRecLog: Capturer SourceType: ${audioParamsGet.source}`); - console.info(`AudioFrameworkRecLog: Capturer capturerFlags: ${audioParamsGet.capturerFlags}`); - } else { - console.info(`AudioFrameworkRecLog: audioParamsGet is : ${audioParamsGet}`); - console.info('AudioFrameworkRecLog: audioParams getCapturerInfo are incorrect'); - } -}).catch((err) => { - console.error(`AudioFrameworkRecLog: CapturerInfo :ERROR: ${err}`); +audioManager.getMinVolume(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promised returned to indicate that the minimum volume is obtained. ${value}`); }); ``` -### getStreamInfo8+ +### getMaxVolume(deprecated) -getStreamInfo(callback: AsyncCallback): void +getMaxVolume(volumeType: AudioVolumeType, callback: AsyncCallback<number>): void -获取采集器流信息。使用callback方式异步返回结果。 +获取指定流的最大音量,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getMaxVolume](#getmaxvolume9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------------------------------------- | :--- | :------------------------------- | -| callback | AsyncCallback<[AudioStreamInfo](#audiostreaminfo8)\> | 是 | 使用callback方式异步返回流信息。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ---------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<number> | 是 | 回调返回最大音量大小。 | **示例:** ```js -audioCapturer.getStreamInfo((err, streamInfo) => { +audioManager.getMaxVolume(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error('Failed to get stream info'); - } else { - console.info('Capturer GetStreamInfo:'); - console.info(`Capturer sampling rate: ${streamInfo.samplingRate}`); - console.info(`Capturer channel: ${streamInfo.channels}`); - console.info(`Capturer format: ${streamInfo.sampleFormat}`); - console.info(`Capturer encoding type: ${streamInfo.encodingType}`); + console.error(`Failed to obtain the maximum volume. ${err}`); + return; } + console.info(`Callback invoked to indicate that the maximum volume is obtained. ${value}`); }); ``` -### getStreamInfo8+ +### getMaxVolume(deprecated) -getStreamInfo(): Promise +getMaxVolume(volumeType: AudioVolumeType): Promise<number> -获取采集器流信息。使用Promise方式异步返回结果。 +获取指定流的最大音量,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getMaxVolume](#getmaxvolume9)替代。 -**返回值:** +**系统能力:** SystemCapability.Multimedia.Audio.Volume -| 类型 | 说明 | -| :--------------------------------------------- | :------------------------------ | -| Promise<[AudioStreamInfo](#audiostreaminfo8)\> | 使用Promise方式异步返回流信息。 | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | + +**返回值:** + +| 类型 | 说明 | +| --------------------- | ----------------------------- | +| Promise<number> | Promise回调返回最大音量大小。 | **示例:** ```js -audioCapturer.getStreamInfo().then((audioParamsGet) => { - console.info('getStreamInfo:'); - console.info(`sampleFormat: ${audioParamsGet.sampleFormat}`); - console.info(`samplingRate: ${audioParamsGet.samplingRate}`); - console.info(`channels: ${audioParamsGet.channels}`); - console.info(`encodingType: ${audioParamsGet.encodingType}`); -}).catch((err) => { - console.error(`getStreamInfo :ERROR: ${err}`); +audioManager.getMaxVolume(audio.AudioVolumeType.MEDIA).then((data) => { + console.info('Promised returned to indicate that the maximum volume is obtained.'); }); ``` -### start8+ +### mute(deprecated) -start(callback: AsyncCallback): void +mute(volumeType: AudioVolumeType, mute: boolean, callback: AsyncCallback<void>): void -启动音频采集器。使用callback方式异步返回结果。 +设置指定音量流静音,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[mute](#mute9)替代。 + +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :----------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | +| callback | AsyncCallback<void> | 是 | 回调表示成功还是失败。 | **示例:** ```js -audioCapturer.start((err) => { +audioManager.mute(audio.AudioVolumeType.MEDIA, true, (err) => { if (err) { - console.error('Capturer start failed.'); - } else { - console.info('Capturer start success.'); + console.error(`Failed to mute the stream. ${err}`); + return; } + console.info('Callback invoked to indicate that the stream is muted.'); }); ``` +### mute(deprecated) -### start8+ +mute(volumeType: AudioVolumeType, mute: boolean): Promise<void> -start(): Promise +设置指定音量流静音,使用Promise方式异步返回结果。 -启动音频采集器。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[mute](#mute9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅设置铃声(即volumeType为AudioVolumeType.RINGTONE)在静音和非静音状态切换时需要该权限。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| mute | boolean | 是 | 静音状态,true为静音,false为非静音。 | **返回值:** -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +| 类型 | 说明 | +| ------------------- | ----------------------------- | +| Promise<void> | Promise回调表示成功还是失败。 | **示例:** + ```js -audioCapturer.start().then(() => { - console.info('AudioFrameworkRecLog: ---------START---------'); - console.info('AudioFrameworkRecLog: Capturer started: SUCCESS'); - console.info(`AudioFrameworkRecLog: AudioCapturer: STATE: ${audioCapturer.state}`); - console.info('AudioFrameworkRecLog: Capturer started: SUCCESS'); - if ((audioCapturer.state == audio.AudioState.STATE_RUNNING)) { - console.info('AudioFrameworkRecLog: AudioCapturer is in Running State'); - } -}).catch((err) => { - console.info(`AudioFrameworkRecLog: Capturer start :ERROR : ${err}`); +audioManager.mute(audio.AudioVolumeType.MEDIA, true).then(() => { + console.info('Promise returned to indicate that the stream is muted.'); }); ``` -### stop8+ +### isMute(deprecated) -stop(callback: AsyncCallback): void +isMute(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void -停止采集。使用callback方式异步返回结果。 +获取指定音量流是否被静音,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[isMute](#ismute9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :----------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ----------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回流静音状态,true为静音,false为非静音。 | **示例:** ```js -audioCapturer.stop((err) => { +audioManager.isMute(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error('Capturer stop failed'); - } else { - console.info('Capturer stopped.'); + console.error(`Failed to obtain the mute status. ${err}`); + return; } + console.info(`Callback invoked to indicate that the mute status of the stream is obtained. ${value}`); }); ``` +### isMute(deprecated) -### stop8+ +isMute(volumeType: AudioVolumeType): Promise<boolean> -stop(): Promise +获取指定音量流是否被静音,使用Promise方式异步返回结果。 -停止采集。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[isMute](#ismute9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +| 类型 | 说明 | +| ---------------------- | ------------------------------------------------------ | +| Promise<boolean> | Promise回调返回流静音状态,true为静音,false为非静音。 | **示例:** ```js -audioCapturer.stop().then(() => { - console.info('AudioFrameworkRecLog: ---------STOP RECORD---------'); - console.info('AudioFrameworkRecLog: Capturer stopped: SUCCESS'); - if ((audioCapturer.state == audio.AudioState.STATE_STOPPED)){ - console.info('AudioFrameworkRecLog: State is Stopped:'); - } -}).catch((err) => { - console.info(`AudioFrameworkRecLog: Capturer stop: ERROR: ${err}`); +audioManager.isMute(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the mute status of the stream is obtained ${value}.`); }); ``` -### release8+ +### isActive(deprecated) -release(callback: AsyncCallback): void +isActive(volumeType: AudioVolumeType, callback: AsyncCallback<boolean>): void -释放采集器。使用callback方式异步返回结果。 +获取指定音量流是否为活跃状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioStreamManager中的[isActive](#isactive9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :---------------------------------- | -| callback | AsyncCallback | 是 | Callback used to return the result. | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------------------------------------------- | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回流的活跃状态,true为活跃,false为不活跃。 | **示例:** ```js -audioCapturer.release((err) => { +audioManager.isActive(audio.AudioVolumeType.MEDIA, (err, value) => { if (err) { - console.error('capturer release failed'); - } else { - console.info('capturer released.'); + console.error(`Failed to obtain the active status of the stream. ${err}`); + return; } + console.info(`Callback invoked to indicate that the active status of the stream is obtained ${value}.`); }); ``` +### isActive(deprecated) -### release8+ +isActive(volumeType: AudioVolumeType): Promise<boolean> -release(): Promise +获取指定音量流是否为活跃状态,使用Promise方式异步返回结果。 -释放采集器。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioStreamManager中的[isActive](#isactive9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Volume + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ----------------------------------- | ---- | ------------ | +| volumeType | [AudioVolumeType](#audiovolumetype) | 是 | 音量流类型。 | **返回值:** -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +| 类型 | 说明 | +| ---------------------- | -------------------------------------------------------- | +| Promise<boolean> | Promise回调返回流的活跃状态,true为活跃,false为不活跃。 | **示例:** ```js -let stateFlag; -audioCapturer.release().then(() => { - console.info('AudioFrameworkRecLog: ---------RELEASE RECORD---------'); - console.info('AudioFrameworkRecLog: Capturer release : SUCCESS'); - console.info(`AudioFrameworkRecLog: AudioCapturer : STATE : ${audioCapturer.state}`); - console.info(`AudioFrameworkRecLog: stateFlag : ${stateFlag}`); -}).catch((err) => { - console.info(`AudioFrameworkRecLog: Capturer stop: ERROR: ${err}`); +audioManager.isActive(audio.AudioVolumeType.MEDIA).then((value) => { + console.info(`Promise returned to indicate that the active status of the stream is obtained ${value}.`); }); ``` +### setRingerMode(deprecated) -### read8+ +setRingerMode(mode: AudioRingMode, callback: AsyncCallback<void>): void -read(size: number, isBlockingRead: boolean, callback: AsyncCallback): void +设置铃声模式,使用callback方式异步返回结果。 -读入缓冲区。使用callback方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setRingerMode](#setringermode9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY + +仅在静音和非静音状态切换时需要该权限。 + +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------------- | :-------------------------- | :--- | :------------------------------- | -| size | number | 是 | 读入的字节数。 | -| isBlockingRead | boolean | 是 | 是否阻塞读操作。 | -| callback | AsyncCallback | 是 | 使用callback方式异步返回缓冲区。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------- | ---- | ------------------------ | +| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** ```js -let bufferSize; -audioCapturer.getBufferSize().then((data) => { - console.info(`AudioFrameworkRecLog: getBufferSize: SUCCESS ${data}`); - bufferSize = data; - }).catch((err) => { - console.error(`AudioFrameworkRecLog: getBufferSize: ERROR: ${err}`); - }); -audioCapturer.read(bufferSize, true, async(err, buffer) => { - if (!err) { - console.info('Success in reading the buffer data'); +audioManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL, (err) => { + if (err) { + console.error(`Failed to set the ringer mode.​ ${err}`); + return; } + console.info('Callback invoked to indicate a successful setting of the ringer mode.'); }); ``` +### setRingerMode(deprecated) -### read8+ - -read(size: number, isBlockingRead: boolean): Promise - -读入缓冲区。使用Promise方式异步返回结果。 +setRingerMode(mode: AudioRingMode): Promise<void> -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +设置铃声模式,使用Promise方式异步返回结果。 -**参数:** +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setRingerMode](#setringermode9)替代。 -| 参数名 | 类型 | 必填 | 说明 | -| :------------- | :------ | :--- | :--------------- | -| size | number | 是 | 读入的字节数。 | -| isBlockingRead | boolean | 是 | 是否阻塞读操作。 | +**需要权限:** ohos.permission.ACCESS_NOTIFICATION_POLICY -**返回值:** +仅在静音和非静音状态切换时需要该权限。 -| 类型 | 说明 | -| :-------------------- | :----------------------------------------------------- | -| Promise | 如果操作成功,返回读取的缓冲区数据;否则返回错误代码。 | +**系统能力:** SystemCapability.Multimedia.Audio.Communication -**示例:** +**参数:** -```js -let bufferSize; -audioCapturer.getBufferSize().then((data) => { - console.info(`AudioFrameworkRecLog: getBufferSize: SUCCESS ${data}`); - bufferSize = data; - }).catch((err) => { - console.info(`AudioFrameworkRecLog: getBufferSize: ERROR ${err}`); - }); -console.info(`Buffer size: ${bufferSize}`); -audioCapturer.read(bufferSize, true).then((buffer) => { - console.info('buffer read successfully'); -}).catch((err) => { - console.info(`ERROR : ${err}`); +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------------------------------- | ---- | -------------- | +| mode | [AudioRingMode](#audioringmode) | 是 | 音频铃声模式。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | + +**示例:** + +```js +audioManager.setRingerMode(audio.AudioRingMode.RINGER_MODE_NORMAL).then(() => { + console.info('Promise returned to indicate a successful setting of the ringer mode.'); }); ``` +### getRingerMode(deprecated) -### getAudioTime8+ +getRingerMode(callback: AsyncCallback<AudioRingMode>): void -getAudioTime(callback: AsyncCallback): void +获取铃声模式,使用callback方式异步返回结果。 -获取时间戳(从1970年1月1日开始),单位为纳秒。使用callback方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getRingerMode](#getringermode9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Communication **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------- | :--- | :----------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------------------- | ---- | ------------------------ | +| callback | AsyncCallback<[AudioRingMode](#audioringmode)> | 是 | 回调返回系统的铃声模式。 | **示例:** ```js -audioCapturer.getAudioTime((err, timestamp) => { - console.info(`Current timestamp: ${timestamp}`); +audioManager.getRingerMode((err, value) => { + if (err) { + console.error(`Failed to obtain the ringer mode.​ ${err}`); + return; + } + console.info(`Callback invoked to indicate that the ringer mode is obtained ${value}.`); }); ``` +### getRingerMode(deprecated) -### getAudioTime8+ +getRingerMode(): Promise<AudioRingMode> -getAudioTime(): Promise +获取铃声模式,使用Promise方式异步返回结果。 -获取时间戳(从1970年1月1日开始),单位为纳秒。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[getRingerMode](#getringermode9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Communication **返回值:** -| 类型 | 说明 | -| :--------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +| 类型 | 说明 | +| ---------------------------------------------- | ------------------------------- | +| Promise<[AudioRingMode](#audioringmode)> | Promise回调返回系统的铃声模式。 | **示例:** ```js -audioCapturer.getAudioTime().then((audioTime) => { - console.info(`AudioFrameworkRecLog: AudioCapturer getAudioTime : Success ${audioTime}`); -}).catch((err) => { - console.info(`AudioFrameworkRecLog: AudioCapturer Created : ERROR : ${err}`); +audioManager.getRingerMode().then((value) => { + console.info(`Promise returned to indicate that the ringer mode is obtained ${value}.`); }); ``` +### getDevices(deprecated) -### getBufferSize8+ +getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void -getBufferSize(callback: AsyncCallback): void +获取音频设备列表,使用callback方式异步返回结果。 -获取采集器合理的最小缓冲区大小。使用callback方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[getDevices](#getdevices9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :--------------------- | :--- | :----------------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回缓冲区大小。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------------------------------ | ---- | -------------------- | +| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | +| callback | AsyncCallback<[AudioDeviceDescriptors](#audiodevicedescriptors)> | 是 | 回调,返回设备列表。 | **示例:** - ```js -audioCapturer.getBufferSize((err, bufferSize) => { - if (!err) { - console.info(`BufferSize : ${bufferSize}`); - audioCapturer.read(bufferSize, true).then((buffer) => { - console.info(`Buffer read is ${buffer}`); - }).catch((err) => { - console.error(`AudioFrameworkRecLog: AudioCapturer Created : ERROR : ${err}`); - }); +audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (err, value) => { + if (err) { + console.error(`Failed to obtain the device list. ${err}`); + return; } + console.info('Callback invoked to indicate that the device list is obtained.'); }); ``` +### getDevices(deprecated) -### getBufferSize8+ +getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors> -getBufferSize(): Promise +获取音频设备列表,使用Promise方式异步返回结果。 -获取采集器合理的最小缓冲区大小。使用Promise方式异步返回结果。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[getDevices](#getdevices9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Device + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------- | ---- | ---------------- | +| deviceFlag | [DeviceFlag](#deviceflag) | 是 | 设备类型的flag。 | **返回值:** -| 类型 | 说明 | -| :--------------- | :---------------------------------- | -| Promise | 使用Promise方式异步返回缓冲区大小。 | +| 类型 | 说明 | +| ------------------------------------------------------------ | ------------------------- | +| Promise<[AudioDeviceDescriptors](#audiodevicedescriptors)> | Promise回调返回设备列表。 | **示例:** ```js -let bufferSize; -audioCapturer.getBufferSize().then((data) => { - console.info(`AudioFrameworkRecLog: getBufferSize :SUCCESS ${data}`); - bufferSize = data; -}).catch((err) => { - console.info(`AudioFrameworkRecLog: getBufferSize :ERROR : ${err}`); +audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { + console.info('Promise returned to indicate that the device list is obtained.'); }); ``` +### setDeviceActive(deprecated) -### on('markReach')8+ +setDeviceActive(deviceType: ActiveDeviceType, active: boolean, callback: AsyncCallback<void>): void -on(type: "markReach", frame: number, callback: Callback<number>): void +设置设备激活状态,使用callback方式异步返回结果。 -订阅标记到达的事件。 当采集的帧数达到 frame 参数的值时,回调被触发。 +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[setCommunicationDevice](#setcommunicationdevice9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :---------------------- | :--- | :----------------------------------------- | -| type | string | 是 | 事件回调类型,支持的事件为:'markReach'。 | -| frame | number | 是 | 触发事件的帧数。 该值必须大于0。 | -| callback | Callback\ | 是 | 使用callback方式异步返回被触发事件的回调。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------- | ---- | ------------------------ | +| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | +| active | boolean | 是 | 设备激活状态。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** ```js -audioCapturer.on('markReach', 1000, (position) => { - if (position == 1000) { - console.info('ON Triggered successfully'); +audioManager.setDeviceActive(audio.ActiveDeviceType.SPEAKER, true, (err) => { + if (err) { + console.error(`Failed to set the active status of the device. ${err}`); + return; } + console.info('Callback invoked to indicate that the device is set to the active status.'); }); ``` -### off('markReach')8+ +### setDeviceActive(deprecated) -off(type: 'markReach'): void +setDeviceActive(deviceType: ActiveDeviceType, active: boolean): Promise<void> -取消订阅标记到达的事件。 +设置设备激活状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[setCommunicationDevice](#setcommunicationdevice9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :----- | :----- | :--- | :-------------------------------------------- | -| type | string | 是 | 取消事件回调类型,支持的事件为:'markReach'。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------- | ---- | ------------------ | +| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | +| active | boolean | 是 | 设备激活状态。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | **示例:** + ```js -audioCapturer.off('markReach'); +audioManager.setDeviceActive(audio.ActiveDeviceType.SPEAKER, true).then(() => { + console.info('Promise returned to indicate that the device is set to the active status.'); +}); ``` -### on('periodReach')8+ +### isDeviceActive(deprecated) -on(type: "periodReach", frame: number, callback: Callback<number>): void +isDeviceActive(deviceType: ActiveDeviceType, callback: AsyncCallback<boolean>): void -订阅到达标记的事件。 当采集的帧数达到 frame 参数的值时,回调被循环调用。 +获取指定设备的激活状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[isCommunicationDeviceActive](#iscommunicationdeviceactive9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :----------------------- | :--- | :------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'periodReach'。 | -| frame | number | 是 | 触发事件的帧数。 该值必须大于0。 | -| callback | Callback\ | 是 | 使用callback方式异步返回被触发事件的回调 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------- | ---- | ------------------------ | +| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | +| callback | AsyncCallback<boolean> | 是 | 回调返回设备的激活状态。 | **示例:** ```js -audioCapturer.on('periodReach', 1000, (position) => { - if (position == 1000) { - console.info('ON Triggered successfully'); +audioManager.isDeviceActive(audio.ActiveDeviceType.SPEAKER, (err, value) => { + if (err) { + console.error(`Failed to obtain the active status of the device. ${err}`); + return; } + console.info('Callback invoked to indicate that the active status of the device is obtained.'); }); ``` -### off('periodReach')8+ +### isDeviceActive(deprecated) -off(type: 'periodReach'): void +isDeviceActive(deviceType: ActiveDeviceType): Promise<boolean> -取消订阅标记到达的事件。 +获取指定设备的激活状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[isCommunicationDeviceActive](#iscommunicationdeviceactive9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :----- | :----- | :--- | :---------------------------------------------- | -| type | string | 是 | 取消事件回调类型,支持的事件为:'periodReach'。 | +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------------- | ---- | ------------------ | +| deviceType | [ActiveDeviceType](#activedevicetype) | 是 | 活跃音频设备类型。 | + +**返回值:** + +| Type | Description | +| ---------------------- | ------------------------------- | +| Promise<boolean> | Promise回调返回设备的激活状态。 | **示例:** ```js -audioCapturer.off('periodReach') +audioManager.isDeviceActive(audio.ActiveDeviceType.SPEAKER).then((value) => { + console.info(`Promise returned to indicate that the active status of the device is obtained ${value}.`); +}); ``` -### on('stateChange') 8+ +### setMicrophoneMute(deprecated) -on(type: 'stateChange', callback: Callback): void +setMicrophoneMute(mute: boolean, callback: AsyncCallback<void>): void -订阅监听状态变化。 +设置麦克风静音状态,使用callback方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Capturer +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setMicrophoneMute](#setmicrophonemute9)替代。 + +**需要权限:** ohos.permission.MICROPHONE + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------------- | :--- | :------------------------------------------ | -| type | string | 是 | 事件回调类型,支持的事件为:'stateChange'。 | -| callback | [AudioState](#audiostate8) | 是 | 返回监听的状态。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------- | ---- | --------------------------------------------- | +| mute | boolean | 是 | 待设置的静音状态,true为静音,false为非静音。 | +| callback | AsyncCallback<void> | 是 | 回调返回设置成功或失败。 | **示例:** ```js -audioCapturer.on('stateChange', (state) => { - if (state == 1) { - console.info('audio capturer state is: STATE_PREPARED'); - } - if (state == 2) { - console.info('audio capturer state is: STATE_RUNNING'); +audioManager.setMicrophoneMute(true, (err) => { + if (err) { + console.error(`Failed to mute the microphone. ${err}`); + return; } + console.info('Callback invoked to indicate that the microphone is muted.'); }); ``` -## ToneType 9+ +### setMicrophoneMute(deprecated) -枚举,播放器的音调类型。 +setMicrophoneMute(mute: boolean): Promise<void> + +设置麦克风静音状态,使用Promise方式异步返回结果。 + +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[setMicrophoneMute](#setmicrophonemute9)替代。 + +**需要权限:** ohos.permission.MICROPHONE + +**系统能力:** SystemCapability.Multimedia.Audio.Device + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------- | ---- | --------------------------------------------- | +| mute | boolean | 是 | 待设置的静音状态,true为静音,false为非静音。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------- | ------------------------------- | +| Promise<void> | Promise回调返回设置成功或失败。 | -**系统能力:** 以下各项对应的系统能力均为SystemCapability.Multimedia.Audio.Tone +**示例:** -| 名称 | 默认值 | 描述 | -| :------------------------------------------------ | :----- | :----------------------------| -| TONE_TYPE_DIAL_0 | 0 | 键0的DTMF音。 | -| TONE_TYPE_DIAL_1 | 1 | 键1的DTMF音。 | -| TONE_TYPE_DIAL_2 | 2 | 键2的DTMF音。 | -| TONE_TYPE_DIAL_3 | 3 | 键3的DTMF音。 | -| TONE_TYPE_DIAL_4 | 4 | 键4的DTMF音。 | -| TONE_TYPE_DIAL_5 | 5 | 键5的DTMF音。 | -| TONE_TYPE_DIAL_6 | 6 | 键6的DTMF音。 | -| TONE_TYPE_DIAL_7 | 7 | 键7的DTMF音。 | -| TONE_TYPE_DIAL_8 | 8 | 键8的DTMF音。 | -| TONE_TYPE_DIAL_9 | 9 | 键9的DTMF音。 | -| TONE_TYPE_DIAL_S | 10 | 键*的DTMF音。 | -| TONE_TYPE_DIAL_P | 11 | 键#的DTMF音。 | -| TONE_TYPE_DIAL_A | 12 | 键A的DTMF音。 | -| TONE_TYPE_DIAL_B | 13 | 键B的DTMF音。 | -| TONE_TYPE_DIAL_C | 14 | 键C的DTMF音。 | -| TONE_TYPE_DIAL_D | 15 | 键D的DTMF音。 | -| TONE_TYPE_COMMON_SUPERVISORY_DIAL | 100 | 呼叫监管音调,拨号音。 | -| TONE_TYPE_COMMON_SUPERVISORY_BUSY | 101 | 呼叫监管音调,忙。 | -| TONE_TYPE_COMMON_SUPERVISORY_CONGESTION | 102 | 呼叫监管音调,拥塞。 | -| TONE_TYPE_COMMON_SUPERVISORY_RADIO_ACK | 103 | 呼叫监管音调,无线电 ACK。 | -| TONE_TYPE_COMMON_SUPERVISORY_RADIO_NOT_AVAILABLE | 104 | 呼叫监管音调,无线电不可用。 | -| TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING | 106 | 呼叫监管音调,呼叫等待。 | -| TONE_TYPE_COMMON_SUPERVISORY_RINGTONE | 107 | 呼叫监管音调,铃声。 | -| TONE_TYPE_COMMON_PROPRIETARY_BEEP | 200 | 专有声调,一般蜂鸣声。 | -| TONE_TYPE_COMMON_PROPRIETARY_ACK | 201 | 专有声调,ACK。 | -| TONE_TYPE_COMMON_PROPRIETARY_PROMPT | 203 | 专有声调,PROMPT。 | -| TONE_TYPE_COMMON_PROPRIETARY_DOUBLE_BEEP | 204 | 专有声调,双重蜂鸣声。 | +```js +audioManager.setMicrophoneMute(true).then(() => { + console.info('Promise returned to indicate that the microphone is muted.'); +}); +``` -## TonePlayer9+ +### isMicrophoneMute(deprecated) -提供播放和管理DTMF(Dual Tone Multi Frequency,双音多频)音调的方法,包括各种系统监听音调、专有音调,如拨号音、通话回铃音等。 +isMicrophoneMute(callback: AsyncCallback<boolean>): void -### load9+ +获取麦克风静音状态,使用callback方式异步返回结果。 -load(type: ToneType, callback: AsyncCallback<void>): void +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[isMicrophoneMute](#ismicrophonemute9)替代。 -加载DTMF音调配置。使用callback方式异步返回结果。 +**需要权限:** ohos.permission.MICROPHONE -**系统能力:** SystemCapability.Multimedia.Audio.Tone +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :--------------| :-------------------------- | :-----| :------------------------------ | -| type | ToneType(#tonetype9) | 是 | 配置的音调类型。 | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | ------------------------------------------------------- | +| callback | AsyncCallback<boolean> | 是 | 回调返回系统麦克风静音状态,true为静音,false为非静音。 | **示例:** ```js -tonePlayer.load(audio.ToneType.TONE_TYPE_DIAL_5, (err) => { +audioManager.isMicrophoneMute((err, value) => { if (err) { - console.error(`callback call load failed error: ${err.message}`); + console.error(`Failed to obtain the mute status of the microphone. ${err}`); return; - } else { - console.info('callback call load success'); } + console.info(`Callback invoked to indicate that the mute status of the microphone is obtained ${value}.`); }); ``` -### load9+ +### isMicrophoneMute(deprecated) -load(type: ToneType): Promise<void> +isMicrophoneMute(): Promise<boolean> -加载DTMF音调配置。使用Promise方式异步返回结果。 +获取麦克风静音状态,使用Promise方式异步返回结果。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[isMicrophoneMute](#ismicrophonemute9)替代。 -**参数:** +**需要权限:** ohos.permission.MICROPHONE -| 参数名 | 类型 | 必填 | 说明 | -| :------------- | :--------------------- | :--- | ---------------- | -| type | ToneType(#tonetype9) | 是 | 配置的音调类型。 | +**系统能力:** SystemCapability.Multimedia.Audio.Device **返回值:** -| 类型 | 说明 | -| :--------------| :-------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +| 类型 | 说明 | +| ---------------------- | ------------------------------------------------------------ | +| Promise<boolean> | Promise回调返回系统麦克风静音状态,true为静音,false为非静音。 | **示例:** ```js -tonePlayer.load(audio.ToneType.TONE_TYPE_DIAL_1).then(() => { - console.info('promise call load '); -}).catch(() => { - console.error('promise call load fail'); +audioManager.isMicrophoneMute().then((value) => { + console.info(`Promise returned to indicate that the mute status of the microphone is obtained ${value}.`); }); ``` -### start9+ +### on('volumeChange')(deprecated) -start(callback: AsyncCallback<void>): void +on(type: 'volumeChange', callback: Callback\): void -启动DTMF音调播放。使用callback方式异步返回结果。 +> **说明:** +> 从 API version 8 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeManager中的[on](#on9)替代。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +监听系统音量变化事件。 + +**系统接口:** 该接口为系统接口 + +目前此订阅接口在单进程多AudioManager实例的使用场景下,仅最后一个实例的订阅生效,其他实例的订阅会被覆盖(即使最后一个实例没有进行订阅),因此推荐使用单一AudioManager实例进行开发。 + +**系统能力:** SystemCapability.Multimedia.Audio.Volume **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :----------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'volumeChange'(系统音量变化事件,检测到系统音量改变时,触发该事件)。 | +| callback | Callback<[VolumeEvent](#volumeevent8)> | 是 | 回调方法。 | **示例:** ```js -tonePlayer.start((err) => { - if (err) { - console.error(`callback call start failed error: ${err.message}`); - return; - } else { - console.info('callback call start success'); - } +audioManager.on('volumeChange', (volumeEvent) => { + console.info(`VolumeType of stream: ${volumeEvent.volumeType} `); + console.info(`Volume level: ${volumeEvent.volume} `); + console.info(`Whether to updateUI: ${volumeEvent.updateUi} `); }); ``` -### start9+ +### on('ringerModeChange')(deprecated) -start(): Promise<void> +on(type: 'ringerModeChange', callback: Callback\): void -启动DTMF音调播放。使用Promise方式异步返回结果。 +监听铃声模式变化事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 8 开始支持,从 API version 9 开始废弃,建议使用AudioVolumeGroupManager中的[on('ringerModeChange')](#onringermodechange9)替代。 -**返回值:** +**系统接口:** 该接口为系统接口 -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +**系统能力:** SystemCapability.Multimedia.Audio.Communication + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件回调类型,支持的事件为:'ringerModeChange'(铃声模式变化事件,检测到铃声模式改变时,触发该事件)。 | +| callback | Callback<[AudioRingMode](#audioringmode)> | 是 | 回调方法。 | **示例:** ```js -tonePlayer.start().then(() => { - console.info('promise call start'); -}).catch(() => { - console.error('promise call start fail'); +audioManager.on('ringerModeChange', (ringerMode) => { + console.info(`Updated ringermode: ${ringerMode}`); }); ``` -### stop9+ +### on('deviceChange')(deprecated) -stop(callback: AsyncCallback<void>): void +on(type: 'deviceChange', callback: Callback): void -停止当前正在播放的音调。使用callback方式异步返回结果。 +设备更改。音频设备连接状态变化。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[on](#on9)替代。 + +**系统能力:** SystemCapability.Multimedia.Audio.Device **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :----------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| :------- | :--------------------------------------------------- | :--- | :----------------------------------------- | +| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | +| callback | Callback<[DeviceChangeAction](#devicechangeaction)\> | 是 | 获取设备更新详情。 | **示例:** ```js -tonePlayer.stop((err) => { - if (err) { - console.error(`callback call stop error: ${err.message}`); - return; - } else { - console.error('callback call stop success '); - } +audioManager.on('deviceChange', (deviceChanged) => { + console.info(`device change type : ${deviceChanged.type} `); + console.info(`device descriptor size : ${deviceChanged.deviceDescriptors.length} `); + console.info(`device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceRole} `); + console.info(`device change descriptor : ${deviceChanged.deviceDescriptors[0].deviceType} `); }); ``` -### stop9+ +### off('deviceChange')(deprecated) -stop(): Promise<void> +off(type: 'deviceChange', callback?: Callback): void -停止当前正在播放的音调。使用Promise方式异步返回结果。 +取消订阅音频设备连接变化事件。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃,建议使用AudioRoutingManager中的[off](#off9)替代。 -**返回值:** +**系统能力:** SystemCapability.Multimedia.Audio.Device -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------------------------- | ---- | ------------------------------------------ | +| type | string | 是 | 订阅的事件的类型。支持事件:'deviceChange' | +| callback | Callback<[DeviceChangeAction](#devicechangeaction)> | 否 | 获取设备更新详情。 | **示例:** ```js -tonePlayer.stop().then(() => { - console.info('promise call stop finish'); -}).catch(() => { - console.error('promise call stop fail'); +audioManager.off('deviceChange', (deviceChanged) => { + console.info('Should be no callback.'); }); ``` -### release9+ +### on('interrupt')(deprecated) -release(callback: AsyncCallback<void>): void +on(type: 'interrupt', interrupt: AudioInterrupt, callback: Callback\): void -释放与此TonePlay对象关联的资源。使用callback方式异步返回结果。 +请求焦点并开始监听音频打断事件(当应用程序的音频被另一个播放事件中断,回调通知此应用程序)。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃。 + +**系统能力:** SystemCapability.Multimedia.Audio.Renderer **参数:** -| 参数名 | 类型 | 必填 | 说明 | -| :------- | :------------------- | :--- | :---------------------------- | -| callback | AsyncCallback | 是 | 使用callback方式异步返回结果。 | +| 参数名 | 类型 | 必填 | 说明 | +| --------- | --------------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 音频打断事件回调类型,支持的事件为:'interrupt'(多应用之间第二个应用会打断第一个应用,触发该事件)。 | +| interrupt | AudioInterrupt | 是 | 音频打断事件类型的参数。 | +| callback | Callback<[InterruptAction](#interruptaction)> | 是 | 音频打断事件回调方法。 | **示例:** ```js -tonePlayer.release((err) => { - if (err) { - console.error(`callback call release failed error: ${err.message}`); - return; - } else { - console.info('callback call release success '); +let interAudioInterrupt = { + streamUsage:2, + contentType:0, + pauseWhenDucked:true +}; +audioManager.on('interrupt', interAudioInterrupt, (InterruptAction) => { + if (InterruptAction.actionType === 0) { + console.info('An event to gain the audio focus starts.'); + console.info(`Focus gain event: ${InterruptAction} `); + } + if (InterruptAction.actionType === 1) { + console.info('An audio interruption event starts.'); + console.info(`Audio interruption event: ${InterruptAction} `); } }); ``` -### release9+ +### off('interrupt')(deprecated) -release(): Promise<void> +off(type: 'interrupt', interrupt: AudioInterrupt, callback?: Callback\): void -释放与此TonePlay对象关联的资源。使用Promise方式异步返回结果。 +取消监听音频打断事件(删除监听事件,取消打断)。 -**系统能力:** SystemCapability.Multimedia.Audio.Tone +> **说明:** +> 从 API version 7 开始支持,从 API version 9 开始废弃。 -**返回值:** +**系统能力:** SystemCapability.Multimedia.Audio.Renderer -| 类型 | 说明 | -| :------------- | :---------------------------- | -| Promise | 使用Promise方式异步返回结果。 | +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------- | --------------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 音频打断事件回调类型,支持的事件为:'interrupt'(多应用之间第二个应用会打断第一个应用,触发该事件)。 | +| interrupt | AudioInterrupt | 是 | 音频打断事件类型的参数。 | +| callback | Callback<[InterruptAction](#interruptaction)> | 否 | 音频打断事件回调方法。 | **示例:** ```js -tonePlayer.release().then(() => { - console.info('promise call release'); -}).catch(() => { - console.error('promise call release fail'); +let interAudioInterrupt = { + streamUsage:2, + contentType:0, + pauseWhenDucked:true +}; +audioManager.off('interrupt', interAudioInterrupt, (InterruptAction) => { + if (InterruptAction.actionType === 0) { + console.info('An event to release the audio focus starts.'); + console.info(`Focus release event: ${InterruptAction} `); + } }); ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-bundle-defaultAppManager.md b/zh-cn/application-dev/reference/apis/js-apis-bundle-defaultAppManager.md index 1508fd7c192fc20c0c38699176d3fe0b6c1206c3..202f1042a292d31e6882f77383e71cc1a936cd33 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-bundle-defaultAppManager.md +++ b/zh-cn/application-dev/reference/apis/js-apis-bundle-defaultAppManager.md @@ -9,7 +9,7 @@ ## 导入模块 ``` -import defaultAppMgr from '@ohos.bundle.defaultAppManager' +import defaultAppMgr from '@ohos.bundle.defaultAppManager'; ``` ## defaultAppMgr.ApplicationType diff --git a/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md b/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md index 80e40eb4bb410bf40425842e56f0e7a0bf9a8582..d8e5e1b251feb62851336d77d58c040d39b77b9c 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md +++ b/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md @@ -60,7 +60,7 @@ buffer数组的列表。 ## EncodingBlob -证书链数据,在证书链校验时,作为入参传入。 +带编码格式的证书二进制数组。 ### 属性 @@ -1029,7 +1029,7 @@ console.info("key hex:" + uint8ArrayToShowStr(encodedKey.data)); // 输出全 getEncoded() : DataBlob -以同步方法,获取二进制形式的密钥内容。 +以同步方法,获取二进制形式的密钥内容。公钥格式满足ASN.1语法、X.509规范、DER编码格式。 **系统能力:** SystemCapability.Security.CryptoFramework @@ -1065,7 +1065,7 @@ console.info("key encoded:" + Uint8ArrayToShowStr(encodedKey.data)); getEncoded() : DataBlob -以同步方法,获取二进制形式的密钥内容。 +以同步方法,获取二进制形式的密钥内容。私钥格式满足ASN.1语法,PKCS#8规范、DER编码方式。 **系统能力:** SystemCapability.Security.CryptoFramework @@ -1437,11 +1437,9 @@ keyGenPromise.then( keyPair => { **密钥转换说明** -1. RSA二进制密钥数据,按keysize(32位) ,nsize(keysize/8), esize(e实际长度),dsize(keysize/8),nval(大数n的二进制数据),eval(大数e的二进制数据),dval(大数d的二进制数据)拼接形成。 -2. RSA二进制密钥数据中,nsize和dsize为密钥位数/8,esize为具体的实际长度。 -3. RSA私钥数据需要包含keysize,nsize,esize,dsize,nval,eval,dval的全部数据,公钥材料中dsize设置为0,缺省dval的数据。 -4. RSA二进制密钥数据中,keysize、nsize、esize和dsize为32位二进制数据,数据的大小端格式请按设备CPU默认格式,密钥材料(nval、eval、dval)统一为大端格式。 -5. convertKey接口中,公钥和私钥二进制数据为可选项,可单独传入公钥或私钥的数据,生成对应只包含公钥或私钥的KeyPair对象。 +1. 非对称密钥(RSA、ECC)的公钥和私钥调用getEncoded()方法后,分别返回X.509格式和PKCS#8格式的二进制数据,此数据可用于跨应用传输或持久化存储。 +2. 当调用convertKey方法将外来二进制数据转换为算法库非对称密钥对象时,公钥应满足ASN.1语法、X.509规范、DER编码格式,私钥应满足ASN.1语法、PKCS#8规范、DER编码格式。 +3. convertKey方法中,公钥和密钥二进制数据非必选项,可单独传入公钥或私钥的数据,生成对应只包含公钥或私钥的KeyPair对象。 ## cryptoFramework.createCipher diff --git a/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md b/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md index 38b19761bb45edb344fac038c4dd78e11a075d82..80e01c8b59697f412eb6f10f1a8b0f844fae0b2f 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md +++ b/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @@ -77,10 +77,12 @@ createFileAccessHelper(context: Context, wants: Array<Want>) : FileAccessH let fileAccesssHelper = null; // wantInfo 从getFileAccessAbilityInfo()获取 // 创建只连接媒体库服务的helper对象 - let wantInfo = { - "bundleName": "com.ohos.medialibrary.medialibrarydata", - "abilityName": "FileExtensionAbility", - } + let wantInfos = [ + { + "bundleName": "com.ohos.medialibrary.medialibrarydata", + "abilityName": "FileExtensionAbility", + }, + ] try { fileAccesssHelper = fileAccess.createFileAccessHelper(this.context, wantInfos); if (!fileAccesssHelper) @@ -211,7 +213,7 @@ listFile(filter?: Filter) : FileIterator let fileIterator = rootInfo.listFile(); // 含过滤器实现的listFile // let fileIterator = rootInfo.listFile(filter); - if (fileIterator) { + if (!fileIterator) { console.error("listFile interface returns an undefined object"); return; } @@ -261,7 +263,7 @@ scanFile(filter?: Filter) : FileIterator let fileIterator = rootInfo.scanFile(); // 含过滤器实现的scanFile // let fileIterator = rootInfo.scanFile(filter); - if (fileIterator) { + if (!fileIterator) { console.error("scanFile interface returns undefined object"); return; } @@ -311,7 +313,7 @@ listFile(filter?: Filter) : FileIterator let fileIterator = fileInfoDir.listFile(); // 含过滤器实现的listFile // let fileIterator = rootInfo.listFile(filter); - if (fileIterator) { + if (!fileIterator) { console.error("listFile interface returns an undefined object"); return; } @@ -362,7 +364,7 @@ scanFile(filter?: Filter) : FileIterator; let fileIterator = fileInfoDir.scanFile(); // 含过滤器实现的scanFile // let fileIterator = rootInfo.scanFile(filter); - if (fileIterator) { + if (!fileIterator) { console.error("scanFile interface returns an undefined object"); return; } @@ -451,12 +453,12 @@ mkDir(parentUri: string, displayName: string) : Promise<string> let dirName = "dirTest" let dirUri = null; try { - dirUri = await fileAccessHelper.mkDir(sourceUri, displayName) + dirUri = await fileAccessHelper.mkDir(sourceUri, dirName) if (!dirUri) { console.error("mkDir return undefined object"); return; } - console.log("mkDir sucess, fileUri: " + JSON.stringify(fileUri)); + console.log("mkDir sucess, dirUri: " + JSON.stringify(dirUri)); } catch (error) { console.error("mkDir failed, error " + error); }; diff --git a/zh-cn/application-dev/reference/apis/js-apis-fileio.md b/zh-cn/application-dev/reference/apis/js-apis-fileio.md index 25d4499022f4a77670b49ac4f79ddae7d27316b1..9ba948beaccf86693e6d13fe257ab5554212659b 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-fileio.md +++ b/zh-cn/application-dev/reference/apis/js-apis-fileio.md @@ -68,7 +68,7 @@ stat(path: string): Promise<Stat> ```js let filePath = pathDir + "test.txt"; fileio.stat(filePath).then(function(stat){ - console.info("getFileInfo succeed:"+ JSON.stringify(stat)); + console.info("getFileInfo succeed, the size of file is " + stat.size); }).catch(function(err){ console.info("getFileInfo failed with error:"+ err); }); @@ -153,7 +153,7 @@ opendir(path: string): Promise<Dir> ```js let dirPath = pathDir + "/testDir"; fileio.opendir(dirPath).then(function(dir){ - console.info("opendir succeed:"+ JSON.stringify(dir)); + console.info("opendir succeed"); }).catch(function(err){ console.info("opendir failed with error:"+ err); }); @@ -1178,7 +1178,7 @@ fstat(fd: number): Promise<Stat> let filePath = pathDir + "/test.txt"; let fd = fileio.openSync(filePath); fileio.fstat(fd).then(function(stat){ - console.info("fstat succeed:"+ JSON.stringify(stat)); + console.info("fstat succeed, the size of file is "+ stat.size); }).catch(function(err){ console.info("fstat failed with error:"+ err); }); @@ -1525,7 +1525,7 @@ lstat(path: string): Promise<Stat> ```js let filePath = pathDir + "/test.txt"; fileio.lstat(filePath).then(function(stat){ - console.info("get link status succeed:"+ JSON.stringify(stat)); + console.info("get link status succeed, " + the size of file is + stat.size); }).catch(function(err){ console.info("get link status failed with error:"+ err); }); @@ -3166,7 +3166,7 @@ read(): Promise<Dirent> ```js dir.read().then(function (dirent){ - console.log("read succeed:"+JSON.stringify(dirent)); + console.log("read succeed, the name of dirent is " + dirent.name); }).catch(function(err){ console.info("read failed with error:"+ err); }); @@ -3193,7 +3193,7 @@ read(callback: AsyncCallback<Dirent>): void dir.read(function (err, dirent) { if (dirent) { // do something - console.log("read succeed:"+JSON.stringify(dirent)); + console.log("read succeed, the name of file is " + dirent.name); } }); ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md b/zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md index 2551e73891f1692e7589c807e52a2dc44cef6de9..96022038df5110f77024b83733eec4c9e126267e 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inputconsumer.md @@ -1,6 +1,6 @@ # 组合按键 -InputConsumer模块提供对按键事件的监听。 +组合按键订阅模块,用于处理组合按键的订阅。 > **说明:** > @@ -21,7 +21,7 @@ import inputConsumer from '@ohos.multimodalInput.inputConsumer'; on(type: "key", keyOptions: KeyOptions, callback: Callback<KeyOptions>): void -开始监听组合按键事件, 当满足条件的组合按键输入事件发生时,将keyOptions回调到入参callback表示的回调函数上。 +订阅组合按键,当满足条件的组合按键输入事件发生时,使用Callback异步方式上报组合按键数据。 **系统能力:** SystemCapability.MultimodalInput.Input.InputConsumer @@ -29,22 +29,20 @@ on(type: "key", keyOptions: KeyOptions, callback: Callback<KeyOptions>): v | 参数 | 类型 | 必填 | 说明 | | ---------- | -------------------------- | ---- | ---------------------------------------- | -| type | string | 是 | 监听输入事件类型,只支持“key”。 | -| keyOptions | [keyOptions](#keyoptions) | 是 | 组合键选项,用来指定组合键输入时应该符合的条件。 | -| callback | Callback<KeyOptions> | 是 | 回调函数。当满足条件的按键输入产生时,回调到此函数,以传入的KeyOptions为入参。 | +| type | string | 是 | 事件类型,目前只支持”key“。 | +| keyOptions | [keyOptions](#keyoptions) | 是 | 组合键选项。 | +| callback | Callback<KeyOptions> | 是 | 回调函数,当满足条件的组合按键输入事件发生时,异步上报组合按键数据。 | **示例:** ```js -let keyOptions = { preKeys: [], finalKey: 18, isFinalKeyDown: true, finalKeyDownDuration: 0 } -let callback = function (keyOptions) { - console.info("preKeys: " + keyOptions.preKeys, "finalKey: " + keyOptions.finalKey, - "isFinalKeyDown: " + keyOptions.isFinalKeyDown, "finalKeyDownDuration: " + keyOptions.finalKeyDownDuration) -} +let powerKeyCode = 18; try { - inputConsumer.on(inputConsumer.SubscribeType.KEY, keyOptions, callback); + inputConsumer.on("key", {preKeys: [], finalKey: powerKeyCode, isFinalKeyDown: true, finalKeyDownDuration: 0}, keyOptions => { + console.log(`keyOptions: ${JSON.stringify(keyOptions)}`); + }); } catch (error) { - console.info(`inputConsumer.on, error.code=${JSON.stringify(error.code)}, error.msg=${JSON.stringify(error.message)}`); + console.log(`Subscribe failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -53,7 +51,7 @@ try { off(type: "key", keyOptions: KeyOptions, callback?: Callback<KeyOptions>): void -停止监听组合按键事件。 +取消订阅组合按键。 **系统能力:** SystemCapability.MultimodalInput.Input.InputConsumer @@ -61,35 +59,49 @@ off(type: "key", keyOptions: KeyOptions, callback?: Callback<KeyOptions>): | 参数 | 类型 | 必填 | 说明 | | ---------- | -------------------------- | ---- | ------------------------------- | -| type | string | 是 | 监听输入事件类型,只支持“key”。 | -| keyOptions | [keyOptions](#keyoptions) | 是 | 开始监听时传入的keyOptions。 | -| callback | Callback<KeyOptions> | 是 | 开始监听时与KeyOption一同传入的回调函数 。 | +| type | string | 是 | 事件类型,当前只支持”key“。 | +| keyOptions | [keyOptions](#keyoptions) | 是 | 组合键选项。 | +| callback | Callback<KeyOptions> | 否 | 需要取消订阅的回调函数,若无此参数,则取消当前应用的组合键选项已订阅的所有回调函数。 | **示例:** ```js -let keyOptions = { preKeys: [], finalKey: 18, isFinalKeyDown: true, finalKeyDownDuration: 0 } +// 取消订阅单个回调函数 +let callback = function (keyOptions) { + console.log(`keyOptions: ${JSON.stringify(keyOptions)}`); +} +let keyOption = {preKeys: [], finalKey: powerKeyCode, isFinalKeyDown: true, finalKeyDownDuration: 0}; +try { + inputConsumer.on("key", keyOption, callback); + inputConsumer.off("key", keyOption, callback); +} catch (error) { + console.log(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`); +} +``` +```js +// 取消订阅所有回调函数 let callback = function (keyOptions) { - console.info("preKeys: " + keyOptions.preKeys, "finalKey: " + keyOptions.finalKey, - "isFinalKeyDown: " + keyOptions.isFinalKeyDown, "finalKeyDownDuration: " + keyOptions.finalKeyDownDuration) + console.log(`keyOptions: ${JSON.stringify(keyOptions)}`); } +let keyOption = {preKeys: [], finalKey: powerKeyCode, isFinalKeyDown: true, finalKeyDownDuration: 0}; try { - inputConsumer.off(inputConsumer.SubscribeType.KEY, keyOptions, callback); + inputConsumer.on("key", keyOption, callback); + inputConsumer.off("key", keyOption); } catch (error) { - console.info(`inputConsumer.off, error.code=${JSON.stringify(error.code)}, error.msg=${JSON.stringify(error.message)}`); + console.log(`Execute failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` ## KeyOptions -组合键输入事件发生时,组合键满足的选项。 +组合键选项。 **系统能力:** SystemCapability.MultimodalInput.Input.InputConsumer | 参数 | 类型 | 必填 | 说明 | | -------------------- | ------- | ---- | ------------------------ | -| preKeys | Array | 是 | 组合键前置按键集合,可为空,前置按键无顺序要求。 | -| finalKey | Number | 是 | 组合键最后按键,不能为空。 | -| isFinalKeyDown | boolean | 是 | 组合键最后按键是按下还是抬起,默认是按下。 | -| finalKeyDownDuration | Number | 是 | 组合键最后按键按下持续时长,默认无时长要求。 | +| preKeys | Array | 是 | 前置按键集合,数量范围[0, 4],前置按键无顺序要求。 | +| finalKey | Number | 是 | 最终按键,此项必填,最终按键触发上报回调函数。 | +| isFinalKeyDown | boolean | 是 | 最终按键状态。 | +| finalKeyDownDuration | Number | 是 | 最终按键保持按下持续时间,为0时立即触发回调函数,大于0时,当isFinalKeyDown为true,则最终按键按下超过此时长后触发回调函数,当isFinalKeyDown为false,则最终按键按下到抬起时间小于此时长时触发回调函数。 | diff --git a/zh-cn/application-dev/reference/apis/js-apis-inputdevice.md b/zh-cn/application-dev/reference/apis/js-apis-inputdevice.md index b255b0a2f4a3fc86fb06170ae182267c33d3c339..5ddc299f650e5fed2f429f7cbd1458c3d9f552f3 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-inputdevice.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inputdevice.md @@ -1,7 +1,7 @@ # 输入设备 -输入设备管理模块,用于监听输入设备连接、断开和变化,并查看输入设备相关信息。比如监听鼠标插拔,并获取鼠标的id、name和指针移动速度等信息。 +输入设备管理模块,用于监听输入设备连接和断开状态,查询输入设备相关信息。 > **说明**: @@ -20,15 +20,15 @@ import inputDevice from '@ohos.multimodalInput.inputDevice'; getDeviceList(callback: AsyncCallback<Array<number>>): void -获取所有输入设备的id列表,使用callback方式作为异步方法。 +获取所有输入设备的id列表,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------- | ---- | ---------- | -| callback | AsyncCallback<Array<number>> | 是 | 回调函数。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------- | ---- | ---------------------------------------- | +| callback | AsyncCallback<Array<number>> | 是 | 回调函数,异步返回所有输入设备的id列表。 | **示例**: @@ -36,15 +36,13 @@ getDeviceList(callback: AsyncCallback<Array<number>>): void try { inputDevice.getDeviceList((error, ids) => { if (error) { - console.log(`Failed to get device list. - error code=${JSON.stringify(err.code)} msg=${JSON.stringify(err.message)}`); + console.log(`Failed to get device id list, error: ${JSON.stringify(error, [`code`, `message`])}`); return; } - this.data = ids; - console.log("The device ID list is: " + ids); + console.log(`Device id list: ${JSON.stringify(ids)}`); }); } catch (error) { - console.info("getDeviceList " + error.code + " " + error.message); + console.log(`Failed to get device id list, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -52,25 +50,25 @@ try { getDeviceList(): Promise<Array<number>> -获取所有输入设备的id列表,使用Promise方式作为异步方法。 +获取所有输入设备的id列表,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice **返回值**: -| 参数 | 说明 | -| ---------------------------------- | ------------------------------- | -| Promise<Array<number>> | Promise实例,用于异步获取结果。 | +| 参数 | 说明 | +| ---------------------------------- | ------------------------------------------- | +| Promise<Array<number>> | Promise对象,异步返回所有输入设备的id列表。 | **示例**: ```js try { inputDevice.getDeviceList().then((ids) => { - console.log("The device ID list is: " + ids); + console.log(`Device id list: ${JSON.stringify(ids)}`); }); } catch (error) { - console.info("getDeviceList " + error.code + " " + error.message); + console.log(`Failed to get device id list, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -78,7 +76,7 @@ try { getDeviceInfo(deviceId: number, callback: AsyncCallback<InputDeviceData>): void -获取输入设备的描述信息,使用callback方式作为异步方法。 +获取指定输入设备的信息,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice @@ -86,24 +84,23 @@ getDeviceInfo(deviceId: number, callback: AsyncCallback<InputDeviceData>): | 参数 | 类型 | 必填 | 说明 | | -------- | -------------------------------------------------------- | ---- | --------------------------------------- | -| deviceId | number | 是 | 需要获取信息的设备id。 | -| callback | AsyncCallback<[InputDeviceData](#inputdevicedata)> | 是 | 回调函数,异步返回InputDeviceData对象。 | +| deviceId | number | 是 | 输入设备id。 | +| callback | AsyncCallback<[InputDeviceData](#inputdevicedata)> | 是 | 回调函数,异步返回输入设备信息。 | **示例**: ```js -// 示例获取设备id为1的设备name信息。 +// 获取输入设备id为1的设备信息。 try { - inputDevice.getDeviceInfo(1, (error, inputDevice) => { + inputDevice.getDeviceInfo(1, (error, deviceData) => { if (error) { - console.log(`Failed to get device information. - error code=${JSON.stringify(err.code)} msg=${JSON.stringify(err.message)}`); + console.log(`Failed to get device info, error: ${JSON.stringify(error, [`code`, `message`])}`); return; } - console.log("The device name is: " + inputDevice.name); + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); } catch (error) { - console.info("getDeviceInfo " + error.code + " " + error.message); + console.log(`Failed to get device info, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -111,7 +108,7 @@ try { getDeviceInfo(deviceId: number): Promise<InputDeviceData> -获取输入设备的描述信息,使用Promise方式作为异步方法。 +获取指定输入设备的信息,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice @@ -119,30 +116,30 @@ getDeviceInfo(deviceId: number): Promise<InputDeviceData> | 参数 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | ---------------------- | -| deviceId | number | 是 | 需要获取信息的设备id。 | +| deviceId | number | 是 | 输入设备id。 | **返回值**: | 参数 | 说明 | | -------------------------------------------------- | ------------------------------- | -| Promise<[InputDeviceData](#inputdevicedata)> | Promise实例,用于异步获取结果。 | +| Promise<[InputDeviceData](#inputdevicedata)> | Promise对象,异步返回输入设备信息。 | **示例**: ```js -// 示例获取设备id为1的设备name信息。 +// 获取输入设备id为1的设备信息。 try { - inputDevice.getDeviceInfo(id).then((inputDevice) => { - console.log("The device name is: " + inputDevice.name); + inputDevice.getDeviceInfo(1).then((deviceData) => { + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); } catch (error) { - console.info("getDeviceInfo " + error.code + " " + error.message); + console.log(`Failed to get device info, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` ## inputDevice.on9+ -on(type: “change”, listener: Callback<DeviceListener>): void +on(type: "change", listener: Callback<DeviceListener>): void 监听输入设备的热插拔事件。 @@ -153,7 +150,7 @@ on(type: “change”, listener: Callback<DeviceListener>): void | 参数 | 类型 | 必填 | 说明 | | -------- | ---------------------------------------- | ---- | ----------- | | type | string | 是 | 输入设备的事件类型。 | -| listener | Callback<[DeviceListener](#devicelistener9)> | 是 | 可上报的输入设备事件。 | +| listener | Callback<[DeviceListener](#devicelistener9)> | 是 | 回调函数,异步上报输入设备热插拔事件。 | **示例**: @@ -161,13 +158,13 @@ on(type: “change”, listener: Callback<DeviceListener>): void let isPhysicalKeyboardExist = true; try { inputDevice.on("change", (data) => { - console.log("type: " + data.type + ", deviceId: " + data.deviceId); - inputDevice.getKeyboardType(data.deviceId, (err, ret) => { - console.log("The keyboard type of the device is: " + ret); - if (ret == inputDevice.KeyboardType.ALPHABETIC_KEYBOARD && data.type == 'add') { + console.log(`Device event info: ${JSON.stringify(data)}`); + inputDevice.getKeyboardType(data.deviceId, (err, type) => { + console.log("The keyboard type is: " + type); + if (type == inputDevice.KeyboardType.ALPHABETIC_KEYBOARD && data.type == 'add') { // 监听物理键盘已连接。 isPhysicalKeyboardExist = true; - } else if (ret == inputDevice.KeyboardType.ALPHABETIC_KEYBOARD && data.type == 'remove') { + } else if (type == inputDevice.KeyboardType.ALPHABETIC_KEYBOARD && data.type == 'remove') { // 监听物理键盘已断开。 isPhysicalKeyboardExist = false; } @@ -175,13 +172,13 @@ try { }); // 根据isPhysicalKeyboardExist的值决定软键盘是否弹出。 } catch (error) { - console.info("oninputdevcie " + error.code + " " + error.message); + console.log(`Get device info failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` ## inputDevice.off9+ -off(type: “change”, listener?: Callback<DeviceListener>): void +off(type: "change", listener?: Callback<DeviceListener>): void 取消监听输入设备的热插拔事件。 @@ -192,42 +189,41 @@ off(type: “change”, listener?: Callback<DeviceListener>): void | 参数 | 类型 | 必填 | 说明 | | -------- | ---------------------------------------- | ---- | ----------- | | type | string | 是 | 输入设备的事件类型。 | -| listener | Callback<[DeviceListener](#devicelistener9)> | 否 | 可上报的输入设备事件。 | +| listener | Callback<[DeviceListener](#devicelistener9)> | 否 | 取消监听的回调函数。 | **示例**: ```js callback: function(data) { - console.log("type: " + data.type + ", deviceId: " + data.deviceId); + console.log(`Report device event info: ${JSON.stringify(data, [`type`, `deviceId`])}`); } try { inputDevice.on("change", this.callback); } catch (error) { - console.info("oninputdevcie " + error.code + " " + error.message) + console.log(`Listen device event failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } -// 单独取消listener的监听。 +// 取消指定的监听。 try { inputDevice.off("change", this.callback); } catch (error) { - console.info("offinputdevcie " + error.code + " " + error.message) + console.log(`Cancel listening device event failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } // 取消所有监听。 try { inputDevice.off("change"); } catch (error) { - console.info("offinputdevcie " + error.code + " " + error.message); + console.log(`Cancel all listening device event failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } -// 取消监听后,软键盘默认都弹出。 ``` ## inputDevice.getDeviceIds(deprecated) getDeviceIds(callback: AsyncCallback<Array<number>>): void -获取所有输入设备的id列表,使用callback方式作为异步方法。 +获取所有输入设备的id列表,使用AsyncCallback异步方式返回结果。 从API version 9 开始不再维护,建议使用[inputDevice.getDeviceList](#inputdevicegetdevicelist9)代替。 @@ -235,15 +231,19 @@ getDeviceIds(callback: AsyncCallback<Array<number>>): void **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------- | ---- | ----- | -| callback | AsyncCallback<Array<number>> | 是 | 回调函数。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------- | ---- | ---------------------------------------- | +| callback | AsyncCallback<Array<number>> | 是 | 回调函数,异步返回所有输入设备的id列表。 | **示例**: ```js -inputDevice.getDeviceIds((ids)=>{ - console.log("The device ID list is: " + ids); +inputDevice.getDeviceList((error, ids) => { + if (error) { + console.log(`Failed to get device id list, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Device id list: ${JSON.stringify(ids)}`); }); ``` @@ -251,7 +251,7 @@ inputDevice.getDeviceIds((ids)=>{ getDeviceIds(): Promise<Array<number>> -获取所有输入设备的id列表,使用Promise方式作为异步方法。 +获取所有输入设备的id列表,使用Promise异步方式返回结果。 从API version 9 开始不再维护,建议使用[inputDevice.getDeviceList](#inputdevicegetdevicelist9)代替。 @@ -259,15 +259,15 @@ getDeviceIds(): Promise<Array<number>> **返回值**: -| 参数 | 说明 | -| ---------------------------------- | ------------------- | -| Promise<Array<number>> | Promise实例,用于异步获取结果。 | +| 参数 | 说明 | +| ---------------------------------- | ------------------------------------------- | +| Promise<Array<number>> | Promise对象,异步返回所有输入设备的id列表。 | **示例**: ```js -inputDevice.getDeviceIds().then((ids)=>{ - console.log("The device ID list is: " + ids); +inputDevice.getDeviceList().then((ids) => { + console.log(`Device id list: ${JSON.stringify(ids)}`); }); ``` @@ -275,7 +275,7 @@ inputDevice.getDeviceIds().then((ids)=>{ getDevice(deviceId: number, callback: AsyncCallback<InputDeviceData>): void -获取输入设备的描述信息,使用callback方式作为异步方法。 +获取指定输入设备的信息,使用AsyncCallback异步方式返回结果。 从API version 9 开始不再维护,建议使用[inputDevice.getDeviceInfo](#inputdevicegetdeviceinfo9)代替。 @@ -283,17 +283,21 @@ getDevice(deviceId: number, callback: AsyncCallback<InputDeviceData>): voi **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------- | ---- | --------------------------- | -| deviceId | number | 是 | 需要获取信息的设备id。 | -| callback | AsyncCallback<[InputDeviceData](#inputdevicedata)> | 是 | 回调函数,异步返回InputDeviceData对象。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------------------------- | ---- | -------------------------------- | +| deviceId | number | 是 | 输入设备id。 | +| callback | AsyncCallback<[InputDeviceData](#inputdevicedata)> | 是 | 回调函数,异步返回输入设备信息。 | **示例**: ```js -// 示例获取设备id为1的设备name信息。 -inputDevice.getDevice(1, (inputDevice)=>{ - console.log("The device name is: " + inputDevice.name); +// 获取输入设备id为1的设备信息。 +inputDevice.getDeviceInfo(1, (error, deviceData) => { + if (error) { + console.log(`Failed to get device info, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); ``` @@ -301,7 +305,7 @@ inputDevice.getDevice(1, (inputDevice)=>{ getDevice(deviceId: number): Promise<InputDeviceData> -获取输入设备的描述信息,使用Promise方式作为异步方法。 +获取指定输入设备的信息,使用Promise异步方式返回结果。 从API version 9 开始不再维护,建议使用[inputDevice.getDeviceInfo](#inputdevicegetdeviceinfo9)代替。 @@ -309,22 +313,22 @@ getDevice(deviceId: number): Promise<InputDeviceData> **参数**: -| 参数 | 类型 | 必填 | 说明 | +| 参数 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | ------------ | -| deviceId | number | 是 | 需要获取信息的设备id。 | +| deviceId | number | 是 | 输入设备id。 | **返回值**: -| 参数 | 说明 | -| ---------------------------------------- | ------------------- | -| Promise<[InputDeviceData](#inputdevicedata)> | Promise实例,用于异步获取结果。 | +| 参数 | 说明 | +| -------------------------------------------------- | ----------------------------------- | +| Promise<[InputDeviceData](#inputdevicedata)> | Promise对象,异步返回输入设备信息。 | **示例**: ```js -// 示例获取设备id为1的设备name信息。 -inputDevice.getDevice(1).then((inputDevice)=>{ - console.log("The device name is: " + inputDevice.name); +// 获取输入设备id为1的设备信息。 +inputDevice.getDeviceInfo(1).then((deviceData) => { + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); ``` @@ -332,28 +336,28 @@ inputDevice.getDevice(1).then((inputDevice)=>{ supportKeys(deviceId: number, keys: Array<KeyCode>, callback: Callback<Array<boolean>>): void -获取输入设备支持的键码值,使用callback方式作为异步方法。 +获取输入设备是否支持指定的键码值,使用Callback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | ------------------------------------ | ---- | --------------------------------- | -| deviceId | number | 是 | 输入设备的唯一标识,同一个物理设备反复插拔,其设备id会发生变化。 | -| keys | Array<KeyCode> | 是 | 需要查询的键码值,最多支持5个按键查询。 | -| callback | Callback<Array<boolean>> | 是 | 回调函数,异步返回查询结果。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------ | ---- | ------------------------------------------------------ | +| deviceId | number | 是 | 输入设备id,同一个物理设备反复插拔,设备id会发生变化。 | +| keys | Array<KeyCode> | 是 | 需要查询的键码值,最多支持5个按键查询。 | +| callback | Callback<Array<boolean>> | 是 | 回调函数,异步返回查询结果。 | **示例**: ```js -// 示例查询id为1的设备对于17、22和2055按键的支持情况。 +// 查询id为1的输入设备对于17、22和2055按键的支持情况。 try { - inputDevice.supportKeys(1, [17, 22, 2055], (error, ret) => { - console.log("The query result is as follows: " + ret); + inputDevice.supportKeys(1, [17, 22, 2055], (error, supportResult) => { + console.log(`Query result: ${JSON.stringify(supportResult)}`); }); } catch (error) { - console.info("supportKeys " + error.code + " " + error.message); + console.log(`Query failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -361,33 +365,33 @@ try { supportKeys(deviceId: number, keys: Array<KeyCode>): Promise<Array<boolean>> -获取输入设备支持的键码值,使用Promise方式作为异步方法。 +获取输入设备是否支持指定的键码值,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | -------------------- | ---- | --------------------------------- | -| deviceId | number | 是 | 输入设备的唯一标识,同一个物理设备反复插拔,其设备id会发生变化。 | -| keys | Array<KeyCode> | 是 | 需要查询的键码值,最多支持5个按键查询。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ------------------------------------------------------ | +| deviceId | number | 是 | 输入设备id,同一个物理设备反复插拔,设备id会发生变化。 | +| keys | Array<KeyCode> | 是 | 需要查询的键码值,最多支持5个按键查询。 | **返回值**: -| 参数 | 说明 | -| ----------------------------------- | ------------------- | -| Promise<Array<boolean>> | Promise实例,用于异步获取结果。 | +| 参数 | 说明 | +| ----------------------------------- | ------------------------------- | +| Promise<Array<boolean>> | Promise对象,异步返回查询结果。 | **示例**: ```js -// 示例查询id为1的设备对于17、22和2055按键的支持情况。 +// 查询id为1的输入设备对于17、22和2055按键的支持情况。 try { - inputDevice.supportKeys(1, [17, 22, 2055]).then((ret) => { - console.log("The query result is as follows: " + ret); + inputDevice.supportKeys(1, [17, 22, 2055]).then((supportResult) => { + console.log(`Query result: ${JSON.stringify(supportResult)}`); }); } catch (error) { - console.info("supportKeys " + error.code + " " + error.message); + console.log(`Query failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -395,32 +399,31 @@ try { getKeyboardType(deviceId: number, callback: AsyncCallback<KeyboardType>): void -查询输入设备的键盘类型,使用callback方式作为异步方法。 +获取输入设备的键盘类型,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice **参数**: -| 参数 | 类型 | 必填 | 说明 | -| -------- | ---------------------------------------- | ---- | --------------------------------- | -| deviceId | number | 是 | 输入设备的唯一标识,同一个物理设备反复插拔,其设备id会发生变化。 | -| callback | AsyncCallback<[KeyboardType](#keyboardtype9)> | 是 | 回调函数,异步返回查询结果。 | +| 参数 | 类型 | 必填 | 说明 | +| -------- | --------------------------------------------------- | ---- | ------------------------------------------------------------ | +| deviceId | number | 是 | 输入设备的唯一标识,同一个物理设备反复插拔,设备id会发生变化。 | +| callback | AsyncCallback<[KeyboardType](#keyboardtype9)> | 是 | 回调函数,异步返回查询结果。 | **示例**: ```js -// 示例查询设备id为1的设备键盘类型。 +// 查询id为1的输入设备的键盘类型。 try { - inputDevice.getKeyboardType(1, (error, number) => { + inputDevice.getKeyboardType(1, (error, type) => { if (error) { - console.log(`Failed to get keyboardtype. - error code=${JSON.stringify(err.code)} msg=${JSON.stringify(err.message)}`); + console.log(`Failed to get keyboard type, error: ${JSON.stringify(error, [`code`, `message`])}`); return; } - console.log("The keyboard type of the device is: " + number); + console.log(`Keyboard type: ${JSON.stringify(type)}`); }); } catch (error) { - console.info("getKeyboardType " + error.code + " " + error.message); + console.log(`Failed to get keyboard type, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -428,39 +431,45 @@ try { getKeyboardType(deviceId: number): Promise<KeyboardType> -查询输入设备的键盘类型,使用Promise方式作为异步方法。 +获取输入设备的键盘类型,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice +**参数**: + +| 参数 | 类型 | 必填 | 说明 | +| -------- | ------ | ---- | ------------------------------------------------------------ | +| deviceId | number | 是 | 输入设备的唯一标识,同一个物理设备反复插拔,设备id会发生变化。 | + **返回值**: -| 参数 | 说明 | -| ---------------------------------------- | ------------------- | -| Promise<[KeyboardType](#keyboardtype9)> | Promise实例,用于异步获取结果。 | +| 参数 | 说明 | +| --------------------------------------------- | ------------------------------- | +| Promise<[KeyboardType](#keyboardtype9)> | Promise对象,异步返回查询结果。 | **示例**: ```js // 示例查询设备id为1的设备键盘类型。 try { - inputDevice.getKeyboardType(1).then((number) => { - console.log("The keyboard type of the device is: " + number); + inputDevice.getKeyboardType(1).then((type) => { + console.log(`Keyboard type: ${JSON.stringify(type)}`); }); } catch (error) { - console.info("getKeyboardType " + error.code + " " + error.message); + console.log(`Failed to get keyboard type, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` ## DeviceListener9+ -输入设备的描述信息。 +输入设备热插拔的描述信息。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice -| 名称 | 参数类型 | 说明 | -| -------- | --------------------------- | --------------------------------- | -| type | [ChangedType](#changedtype) | 表示输入设备插入或者移除。 | -| deviceId | number | 输入设备的唯一标识,同一个物理设备反复插拔,其设备id会发生变化。 | +| 名称 | 参数类型 | 说明 | +| -------- | --------------------------- | ------------------------------------------------------------ | +| type | [ChangedType](#changedtype) | 输入设备插入或者移除。 | +| deviceId | number | 输入设备的唯一标识,同一个物理设备反复插拔,设备id会发生变化。 | ## InputDeviceData @@ -468,18 +477,18 @@ try { **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice -| 名称 | 参数类型 | 说明 | -| -------------------- | -------------------------------------- | ---------------------------------------- | -| id | number | 输入设备的唯一标识,同一个物理设备反复插拔,其设备id会发生变化。 | -| name | string | 输入设备的名字。 | +| 名称 | 参数类型 | 说明 | +| -------------------- | -------------------------------------- | ------------------------------------------------------------ | +| id | number | 输入设备的唯一标识,同一个物理设备反复插拔,设备id会发生变化。 | +| name | string | 输入设备的名字。 | | sources | Array<[SourceType](#sourcetype)> | 输入设备支持的源类型。比如有的键盘上附带触摸板,则此设备有keyboard和touchpad两种输入源。 | -| axisRanges | Array<[axisRanges](#axisrange)> | 输入设备的轴信息。 | -| bus9+ | number | 输入设备的总线类型。 | -| product9+ | number | 输入设备的产品信息。 | -| vendor9+ | number | 输入设备的厂商信息。 | -| version9+ | number | 输入设备的版本信息。 | -| phys9+ | string | 输入设备的物理地址。 | -| uniq9+ | string | 输入设备的唯一标识。 | +| axisRanges | Array<[axisRanges](#axisrange)> | 输入设备的轴信息。 | +| bus9+ | number | 输入设备的总线类型。 | +| product9+ | number | 输入设备的产品信息。 | +| vendor9+ | number | 输入设备的厂商信息。 | +| version9+ | number | 输入设备的版本信息。 | +| phys9+ | string | 输入设备的物理地址。 | +| uniq9+ | string | 输入设备的唯一标识。 | ## AxisType9+ @@ -517,7 +526,7 @@ try { ## SourceType -定义这个轴的输入源类型。比如鼠标设备可上报x轴事件,则x轴的源就是鼠标。 +轴的输入源类型。比如鼠标设备可上报x轴事件,则x轴的输入源就是鼠标。 **系统能力**:SystemCapability.MultimodalInput.Input.InputDevice diff --git a/zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md b/zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md index 9654433e873c5803fb1d52def20ecd00e5efea07..80d1a26688e276daea5ed1572764368ef93fb8ba 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inputeventclient.md @@ -1,6 +1,6 @@ -# 注入按键 +# 按键注入 -InputEventClient模块提供了注入按键能力。 +按键注入模块,提供按键注入能力。 > **说明:** > @@ -21,7 +21,7 @@ import inputEventClient from '@ohos.multimodalInput.inputEventClient'; injectEvent({KeyEvent: KeyEvent}): void -注入按键,KeyEvent为注入按键的描述信息。 +按键注入,当前仅支持返回键(键值2)注入。 **系统能力:** SystemCapability.MultimodalInput.Input.InputSimulator @@ -29,41 +29,43 @@ injectEvent({KeyEvent: KeyEvent}): void | 参数 | 类型 | 必填 | 说明 | | -------- | --------------------- | ---- | --------- | -| KeyEvent | [KeyEvent](#keyevent) | 是 | 注入按键的描述信息 | +| KeyEvent | [KeyEvent](#keyevent) | 是 | 按键注入描述信息。 | **示例:** ```js try { - var keyEvent = { + let backKeyDown = { isPressed: true, keyCode: 2, keyDownDuration: 0, isIntercepted: false } - inputEventClient.injectKeyEvent({ KeyEvent: keyEvent }); - var keyEvent1 = { + inputEventClient.injectKeyEvent({ KeyEvent: backKeyDown }); + + let backKeyUp = { isPressed: false, keyCode: 2, keyDownDuration: 0, isIntercepted: false }; - inputEventClient.injectKeyEvent({ KeyEvent: keyEvent1 }); + inputEventClient.injectKeyEvent({ KeyEvent: backKeyUp }); } catch (error) { - console.info("injectKeyEvent " + error.code + " " + error.message); + console.log(`Failed to inject KeyEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` ## KeyEvent -注入按键的描述信息。 +按键注入描述信息。 **系统能力:** SystemCapability.MultimodalInput.Input.InputSimulator -| 参数 | 类型 | 必填 | 说明 | -| --------------- | ------- | ---- | --------- | -| isPressed | boolean | 是 | 按键是否按下 | -| keyCode | number | 是 | 按键键值 | -| keyDownDuration | number | 是 | 按键按下持续时间 | -| isIntercepted | boolean | 是 | 按键是否可以被拦截 | +| 参数 | 类型 | 必填 | 说明 | +| --------------- | ------- | ---- | -------------------------- | +| isPressed | boolean | 是 | 按键是否按下。 | +| keyCode | number | 是 | 按键键值,当前只支持back键。 | +| keyDownDuration | number | 是 | 按键按下持续时间。 | +| isIntercepted | boolean | 是 | 按键是否可以被拦截。 | + diff --git a/zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md b/zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md index 56743cb2b46490eb8ca89050e3e891e7b5cf064e..235bbab8b80bc9dd1ad89a0896e39cd9725dabfe 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inputmonitor.md @@ -37,11 +37,11 @@ on(type: "touch", receiver: TouchEventReceiver): void ```js try { inputMonitor.on("touch", (data)=> { - console.info(`monitorOnTouchEvent success ${JSON.stringify(data)}`); + console.log(`Monitor on TouchEvent success ${JSON.stringify(data)}`); return false; }); } catch (error) { - console.info("onMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor on TouchEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -66,11 +66,11 @@ on(type: "mouse", receiver: Callback<MouseEvent>): void ```js try { inputMonitor.on("mouse", (data)=> { - console.info(`monitorOnMouseEvent success ${JSON.stringify(data)}`); + console.log(`Monitor on MouseEvent success ${JSON.stringify(data)}`); return false; }); } catch (error) { - console.info("onMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor on MouseEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -95,25 +95,25 @@ off(type: "touch", receiver?: TouchEventReceiver): void **示例:** ```js -// 取消所有监听。 +// 取消监听全局触屏事件 try { inputMonitor.off("touch"); } catch (error) { - console.info("offMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor off TouchEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } // 单独取消receiver的监听。 callback:function(data) { - console.info(`call success ${JSON.stringify(data)}`); + console.log(`call success ${JSON.stringify(data)}`); }, try { inputMonitor.on("touch", this.callback); } catch (error) { - console.info("onTouchMonitor " + error.code + " " + error.message) -}, + console.log(`Failed to monitor on TouchEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); +}, try { inputMonitor.off("touch",this.callback); } catch (error) { - console.info("offTouchMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor off TouchEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -135,25 +135,25 @@ off(type: "mouse", receiver?: Callback<MouseEvent>): void **示例:** ```js -// 取消所有监听。 +// 取消监听全局鼠标事件 try { inputMonitor.off("mouse"); } catch (error) { - console.info("offMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor off MouseEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } // 单独取消receiver的监听。 callback:function(data) { - console.info(`call success ${JSON.stringify(data)}`); + console.log(`call success ${JSON.stringify(data)}`); }, try { inputMonitor.on("mouse", this.callback); } catch (error) { - console.info("onMouseMonitor " + error.code + " " + error.message) -}, + console.log(`Failed to monitor on MouseEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); +}, try { inputMonitor.off("mouse", this.callback); } catch (error) { - console.info("offMouseMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor off MouseEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -187,6 +187,6 @@ try { }); inputMonitor.off("touch"); } catch (error) { - console.info("offMonitor " + error.code + " " + error.message) + console.log(`Failed to monitor off TouchEvent, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-keycode.md b/zh-cn/application-dev/reference/apis/js-apis-keycode.md index 26f56165a23e232b68ac20f7d867a053a2631032..072408de7c4db11a84a00f3742f0104eaaf2f52f 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-keycode.md +++ b/zh-cn/application-dev/reference/apis/js-apis-keycode.md @@ -8,7 +8,7 @@ KeyCode模块提供了按键类设备的键值。 ## 导入模块 ```js -import {KeyCode} from '@ohos.multimodalInput.keyCode' +import {KeyCode} from '@ohos.multimodalInput.keyCode'; ``` ## KeyCode diff --git a/zh-cn/application-dev/reference/apis/js-apis-keyevent.md b/zh-cn/application-dev/reference/apis/js-apis-keyevent.md index 2dcf562d995aa43115528998f8fb14e625ab884d..45d91a8953f4e477a073562f8b7fa13e937ed306 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-keyevent.md +++ b/zh-cn/application-dev/reference/apis/js-apis-keyevent.md @@ -9,44 +9,44 @@ KeyEvent模块提供了设备可以上报的按键事件。 ## 导入模块 ```js -import {Action,Key,KeyEvent} from '@ohos.multimodalInput.keyEvent'; +import {Action, Key, KeyEvent} from '@ohos.multimodalInput.keyEvent'; ``` ## Action **系统能力**:SystemCapability.MultimodalInput.Input.Core -| 名称 | 参数类型 | 可读 | 可写 | 描述 | -| ------ | ------ | ---- | ---- | ---- | -| CANCEL | number | 是 | 否 | 取消 | -| DOWN | number | 是 | 否 | 按下按钮 | -| UP | number | 是 | 否 | 抬起按钮 | +| 名称 | 参数类型 | 可读 | 可写 | 描述 | +| ------ | -------- | ---- | ---- | -------- | +| CANCEL | number | 是 | 否 | 取消按钮 | +| DOWN | number | 是 | 否 | 按下按钮 | +| UP | number | 是 | 否 | 抬起按钮 | ## Key **系统能力**:SystemCapability.MultimodalInput.Input.Core -| 名称 | 参数类型 | 可读 | 可写 | 描述 | -| ----------- | ------- | ---- | ---- | ------ | -| code | KeyCode | 是 | 否 | 按键码 | -| pressedTime | number | 是 | 否 | 按下时间 | -| deviceId | number | 是 | 否 | 按键所属设备 | +| 名称 | 参数类型 | 可读 | 可写 | 描述 | +| ----------- | -------- | ---- | ---- | -------------- | +| code | KeyCode | 是 | 否 | 按键码 | +| pressedTime | number | 是 | 否 | 按下持续的时间 | +| deviceId | number | 是 | 否 | 按键所属设备 | ## KeyEvent **系统能力**:SystemCapability.MultimodalInput.Input.Core -| 名称 | 参数类型 | 可读 | 可写 | 描述 | -| ----------- | ------- | ---- | ---- | -------------------- | -| action | Action | 是 | 否 | 按键动作 | -| key | Key | 是 | 否 | 当前发生变化的按键 | -| unicodeChar | number | 是 | 否 | 按键对应的uniCode字符 | -| keys | Key[] | 是 | 否 | 当前处于按下状态的按键列表 | -| ctrlKey | boolean | 是 | 否 | 当前ctrlKey是否处于按下状态 | -| altKey | boolean | 是 | 否 | 当前altKey是否处于按下状态 | -| shiftKey | boolean | 是 | 否 | 当前shiftKey是否处于按下状态 | -| logoKey | boolean | 是 | 否 | 当前logoKey是否处于按下状态 | -| fnKey | boolean | 是 | 否 | 当前fnKey是否处于按下状态 | -| capsLock | boolean | 是 | 否 | 当前capsLock是否处于激活状态 | -| numLock | boolean | 是 | 否 | 当前numLock是否处于激活状态 | -| scrollLock | boolean | 是 | 否 | 当前scrollLock是否处于激活状态 | \ No newline at end of file +| 名称 | 参数类型 | 可读 | 可写 | 描述 | +| ----------- | -------- | ---- | ---- | ------------------------------ | +| action | Action | 是 | 否 | 按键动作 | +| key | Key | 是 | 否 | 当前发生变化的按键 | +| unicodeChar | number | 是 | 否 | 按键对应的uniCode字符 | +| keys | Key[] | 是 | 否 | 当前处于按下状态的按键列表 | +| ctrlKey | boolean | 是 | 否 | 当前ctrlKey是否处于按下状态 | +| altKey | boolean | 是 | 否 | 当前altKey是否处于按下状态 | +| shiftKey | boolean | 是 | 否 | 当前shiftKey是否处于按下状态 | +| logoKey | boolean | 是 | 否 | 当前logoKey是否处于按下状态 | +| fnKey | boolean | 是 | 否 | 当前fnKey是否处于按下状态 | +| capsLock | boolean | 是 | 否 | 当前capsLock是否处于激活状态 | +| numLock | boolean | 是 | 否 | 当前numLock是否处于激活状态 | +| scrollLock | boolean | 是 | 否 | 当前scrollLock是否处于激活状态 | diff --git a/zh-cn/application-dev/reference/apis/js-apis-mouseevent.md b/zh-cn/application-dev/reference/apis/js-apis-mouseevent.md index b47a5d9bd5dcfaaae274b736ec7cf3052eb22703..557a6a1a8554f9fa895bbba2680069370e0a6510 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-mouseevent.md +++ b/zh-cn/application-dev/reference/apis/js-apis-mouseevent.md @@ -15,15 +15,15 @@ import {Action,Button,Axis,AxisValue,MouseEvent} from '@ohos.multimodalInput.mou **系统能力**:SystemCapability.MultimodalInput.Input.Core -| 名称 | 参数类型 | 可读 | 可写 | 描述 | -| ----------- | ------ | ---- | ---- | ---------- | -| CANCEL | number | 是 | 否 | 取消 | -| MOVE | number | 是 | 否 | 鼠标移动 | -| BUTTON_DOWN | number | 是 | 否 | 鼠标按钮按下 | -| BUTTON_UP | number | 是 | 否 | 鼠标按钮抬起 | -| AXIS_BEGIN | number | 是 | 否 | 鼠标关联的轴事件开始 | -| AXIS_UPDATE | number | 是 | 否 | 鼠标关联的轴事件更新 | -| AXIS_END | number | 是 | 否 | 鼠标关联的轴事件结束 | +| 名称 | 参数类型 | 可读 | 可写 | 描述 | +| ----------- | -------- | ---- | ---- | -------------------- | +| CANCEL | number | 是 | 否 | 取消动作 | +| MOVE | number | 是 | 否 | 鼠标移动 | +| BUTTON_DOWN | number | 是 | 否 | 鼠标按钮按下 | +| BUTTON_UP | number | 是 | 否 | 鼠标按钮抬起 | +| AXIS_BEGIN | number | 是 | 否 | 鼠标关联的轴事件开始 | +| AXIS_UPDATE | number | 是 | 否 | 鼠标关联的轴事件更新 | +| AXIS_END | number | 是 | 否 | 鼠标关联的轴事件结束 | ## Button diff --git a/zh-cn/application-dev/reference/apis/js-apis-nfcTag.md b/zh-cn/application-dev/reference/apis/js-apis-nfcTag.md index 3cccd741b976c1b9122a871a11601e411fa18c55..71a0bee5b2b0e60b8ee2984768de9fa1c4891da5 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-nfcTag.md +++ b/zh-cn/application-dev/reference/apis/js-apis-nfcTag.md @@ -64,29 +64,57 @@ import tag from '@ohos.nfc.tag'; import tag from '@ohos.nfc.tag'; onCreate(want, launchParam) { - // add other code here + // add other code here... // want is initialized by nfc service, contains tag info for this found tag - var tagInfo = tag.getTagInfo(want); - if (tagInfo == undefined) { + var tagInfo; + try { + tag.getTagInfo(want); + } catch (error) { + console.log("tag.getTagInfo catched error: " + error); + } + if (tagInfo == null || tagInfo == undefined) { console.log("no TagInfo to be created, ignore it."); return; } + + // get the supported technologies for this found tag. var isNfcATag = false; + var isIsoDepTag = false; for (var i = 0; i < tagInfo.technology.length; i++) { if (tagInfo.technology[i] == tag.NFC_A) { isNfcATag = true; - break; } - // also check for technology: tag.NFC_B/NFC_F/NFC_V/ISO_DEP/NDEF/MIFARE_CLASSIC/MIFARE_ULTRALIGHT/NDEF_FORMATABLE + + if (tagInfo.technology[i] == tag.ISO_DEP) { + isIsoDepTag = true; + } + // also check for technology: tag.NFC_B/NFC_F/NFC_V/NDEF/MIFARE_CLASSIC/MIFARE_ULTRALIGHT/NDEF_FORMATABLE } + + // use NfcA APIs to access the found tag. if (isNfcATag) { - var nfcA = tag.getNfcATag(taginfo); + var nfcA; + try { + nfcA = tag.getNfcATag(taginfo); + } catch (error) { + console.log("tag.getNfcATag catched error: " + error); + } // other code to read or write this found tag. } - // use the same code to handle for "NfcA/NfcB/NfcF/NfcV/IsoDep/Ndef/MifareClassic/MifareUL/NdefFormatable", such as: - // var isoDep = tag.getIsoDepTag(taginfo); + // use getIsoDep APIs to access the found tag. + if (isIsoDepTag) { + var isoDep; + try { + isoDep = tag.getIsoDep(taginfo); + } catch (error) { + console.log("tag.getIsoDep catched error: " + error); + } + // other code to read or write this found tag. + } + + // use the same code to handle for "NfcA/NfcB/NfcF/NfcV/Ndef/MifareClassic/MifareUL/NdefFormatable". } ``` @@ -154,99 +182,135 @@ getNfcVTag(tagInfo: [TagInfo](#taginfo)): [NfcVTag](js-apis-nfctech.md#nfcvtag) | -------- | ---------------- | | [NfcVTag](js-apis-nfctech.md#nfcvtag) | NFC V类型Tag对象。 | -## tag.getIsoDepTag9+ +## tag.getIsoDep9+ -getIsoDepTag(tagInfo: [TagInfo](#taginfo)): [IsoDepTag](js-apis-nfctech.md#isoDepTag9 ) +getIsoDep(tagInfo: [TagInfo](#taginfo)): [IsoDepTag](js-apis-nfctech.md#isoDepTag9 ) -获取IsoDep类型Tag对象,通过该对象可访问Iso Dep技术类型的Tag。 - -**需要权限**:ohos.permission.NFC_TAG +获取IsoDep类型Tag对象,通过该对象可访问支持IsoDep技术类型的Tag。 **系统能力**:SystemCapability.Communication.NFC.Core -**返回值:** +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------- | ---- | ---------------------------------------- | +| taginfo | [TagInfo](#taginfo) | 是 | 包含Tag技术类型和相关参数,从tag.getTagInfo(want: Want)获取。 | +**返回值:** | **类型** | **说明** | | ---------- | ------------------| -| [IsoDepTag](js-apis-nfctech.md#isodeptag9) | Iso Dep类型Tag对象。 | - -## tag.getNdefTag9+ +| [IsoDepTag](js-apis-nfctech.md#isodeptag9) | IsoDep类型Tag对象,通过该对象访问IsoDep类型的相关接口。 | -getNdefTag(tagInfo: [TagInfo](#taginfo)): [NdefTag](js-apis-nfctech.md#ndeftag9) +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state of service is abnormal. | -获取Ndef类型Tag对象,通过该对象可访问Ndef技术类型的Tag。 +## tag.getNdef9+ +getNdef(tagInfo: [TagInfo](#taginfo)): [NdefTag](js-apis-nfctech.md#ndeftag9) -**需要权限**:ohos.permission.NFC_TAG +获取NDEF类型Tag对象,通过该对象可访问支持NDEF技术类型的Tag。 **系统能力**:SystemCapability.Communication.NFC.Core -**返回值:** +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------- | ---- | ---------------------------------------- | +| taginfo | [TagInfo](#taginfo) | 是 | 包含Tag技术类型和相关参数,从tag.getTagInfo(want: Want)获取。 | +**返回值:** | **类型** | **说明** | | ---------| -------------- | -| [NdefTag](js-apis-nfctech.md#ndeftag9) | Ndef类型Tag对象。| +| [NdefTag](js-apis-nfctech.md#ndeftag9) | NDEF类型Tag对象,通过该对象访问NDEF类型的相关接口。| -## tag.getMifareClassicTag9+ +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state of service is abnormal. | -getMifareClassicTag(tagInfo: [TagInfo](#taginfo)): [MifareClassicTag](js-apis-nfctech.md#mifareclassictag-9) +## tag.getMifareClassic9+ -获取Mifare Classic类型Tag对象,通过该对象访问Mifare Classic技术类型的Tag。 +getMifareClassic(tagInfo: [TagInfo](#taginfo)): [MifareClassicTag](js-apis-nfctech.md#mifareclassictag-9) -**需要权限**:ohos.permission.NFC_TAG +获取MIFARE Classic类型Tag对象,通过该对象访问支持MIFARE Classic技术类型的Tag。 **系统能力**:SystemCapability.Communication.NFC.Core -**返回值:** +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------- | ---- | ---------------------------------------- | +| taginfo | [TagInfo](#taginfo) | 是 | 包含Tag技术类型和相关参数,从tag.getTagInfo(want: Want)获取。 | +**返回值:** | **类型** | **说明** | | ----------------- | ------------------------| -| [MifareClassicTag](js-apis-nfctech.md#mifareclassictag-9) | Mifare Classic类型Tag对象。 | +| [MifareClassicTag](js-apis-nfctech.md#mifareclassictag-9) | MIFARE Classic类型Tag对象,通过该对象访问MIFARE Classic类型的相关接口。 | -## tag.getMifareUltralightTag9+ +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state of service is abnormal. | -getMifareUltralightTag(tagInfo: [TagInfo](#taginfo)): [MifareUltralightTag](js-apis-nfctech.md#mifareultralighttag9) +## tag.getMifareUltralight9+ -获取Mifare Ultralight类型Tag对象,通过该对象可访问Mifare Ultralight技术类型的Tag。 +getMifareUltralight(tagInfo: [TagInfo](#taginfo)): [MifareUltralightTag](js-apis-nfctech.md#mifareultralighttag9) -**需要权限**:ohos.permission.NFC_TAG +获取MIFARE Ultralight类型Tag对象,通过该对象可访问支持MIFARE Ultralight技术类型的Tag。 **系统能力**:SystemCapability.Communication.NFC.Core -**返回值:** +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------- | ---- | ---------------------------------------- | +| taginfo | [TagInfo](#taginfo) | 是 | 包含Tag技术类型和相关参数,从tag.getTagInfo(want: Want)获取。 | +**返回值:** | **类型** | **说明** | | -------------------- | ---------------------------| -| [MifareUltralightTag](js-apis-nfctech.md#mifareultralighttag9) | Mifare Ultralight类型Tag对象。 | +| [MifareUltralightTag](js-apis-nfctech.md#mifareultralighttag9) | MIFARE Ultralight类型Tag对象,通过该对象访问MIFARE Ultralight类型的相关接口。 | -## tag.getNdefFormatableTag9+ +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state of service is abnormal. | -getNdefFormatableTag(tagInfo: [TagInfo](#taginfo)): [NdefFormatableTag](js-apis-nfctech.md#ndefformatabletag9) +## tag.getNdefFormatable9+ -获取Ndef Formatable类型Tag对象,通过该对象可访问Ndef Formatable技术类型的Tag。 +getNdefFormatable(tagInfo: [TagInfo](#taginfo)): [NdefFormatableTag](js-apis-nfctech.md#ndefformatabletag9) -**需要权限**:ohos.permission.NFC_TAG +获取NDEF Formatable类型Tag对象,通过该对象可访问支持NDEF Formatable技术类型的Tag。 **系统能力**:SystemCapability.Communication.NFC.Core **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| [NdefFormatableTag](js-apis-nfctech.md#ndefformatabletag) | Ndef Formatable类型Tag对象。 | +| [NdefFormatableTag](js-apis-nfctech.md#ndefformatabletag) | NDEF Formatable类型Tag对象,通过该对象访问NDEF Formatable类型的相关接口。 | + +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state of service is abnormal. | ## tag.getTagInfo9+ -getTagInfo(want: Want): [TagInfo](#taginfo) +getTagInfo(want: [Want](js-apis-application-Want.md#Want)): [TagInfo](#taginfo) 从Want中获取TagInfo,Want是被NFC服务初始化,包含了TagInfo所需的属性值。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core -**返回值:** +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------- | ---- | ---------------------------------------- | +| want | [Want](js-apis-application-Want.md#Want) | 是 | 分发Ability时,在系统onCreate入口函数的参数中获取。 | +**返回值:** | **类型** | **说明** | | ------------------ | --------------------------| | [TagInfo](#taginfo) | TagInfo对象,用于获取不同技术类型的Tag对象。 | @@ -255,8 +319,6 @@ getTagInfo(want: Want): [TagInfo](#taginfo) NFC服务在读取到标签时给出的对象,通过改对象属性,应用知道该标签支持哪些技术类型,并使用匹配的技术类型来调用相关接口。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **类型** | **说明** | @@ -268,8 +330,6 @@ NFC服务在读取到标签时给出的对象,通过改对象属性,应用 ## NdefRecord9+ NDEF标签Record属性的定义,参考NDEF标签技术规范《NFCForum-TS-NDEF_1.0》的定义细节。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **类型** | **说明** | | -------- | -------- | -------- | @@ -281,8 +341,6 @@ NDEF标签Record属性的定义,参考NDEF标签技术规范《NFCForum-TS-NDE ## 技术类型定义 NFC Tag有多种不同的技术类型,定义常量描述不同的技术类型。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | @@ -292,15 +350,13 @@ NFC Tag有多种不同的技术类型,定义常量描述不同的技术类型 | NFC_F | 4 | NFC-F(JIS 6319-4)技术。| | NFC_V | 5 | NFC-V(ISO 15693)技术。| | NDEF | 6 | NDEF技术。| -| MIFARE_CLASSIC | 8 | Mifare Classic技术。| -| MIFARE_ULTRALIGHT | 9 | Mifare Utralight技术。| +| MIFARE_CLASSIC | 8 | MIFARE Classic技术。| +| MIFARE_ULTRALIGHT | 9 | MIFARE Utralight技术。| | NDEF_FORMATABLE9+ | 10 | 可以格式化的NDEF技术。| ## TnfType9+ NDEF Record的TNF(Type Name Field)类型值,参考NDEF标签技术规范《NFCForum-TS-NDEF_1.0》的定义细节。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | @@ -315,8 +371,6 @@ NDEF Record的TNF(Type Name Field)类型值,参考NDEF标签技术规范《NFC ## NDEF Record RTD类型定义 NDEF Record的RTD(Record Type Definition)类型值,参考NDEF标签技术规范《NFCForum-TS-NDEF_1.0》的定义细节。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | @@ -326,8 +380,6 @@ NDEF Record的RTD(Record Type Definition)类型值,参考NDEF标签技术规 ## NfcForumType9+ NFC Forum标准里面Tag类型的定义。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | @@ -335,25 +387,21 @@ NFC Forum标准里面Tag类型的定义。 | NFC_FORUM_TYPE_2 | 2 | NFC论坛类型2。 | | NFC_FORUM_TYPE_3 | 3 | NFC论坛类型3。 | | NFC_FORUM_TYPE_4 | 4 | NFC论坛类型4。 | -| MIFARE_CLASSIC | 101 | Mifare Classic类型。 | +| MIFARE_CLASSIC | 101 | MIFARE Classic类型。 | ## MifareClassicType9+ -MifareClassic标签类型的定义。 - -**需要权限**:ohos.permission.NFC_TAG +MIFARE Classic标签类型的定义。 **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | -| TYPE_UNKNOWN | -1 | 未知Mifare类型。 | -| TYPE_CLASSIC | 0 | Mifare Classic类型。| -| TYPE_PLUS | 1 | Mifare Plus类型。| -| TYPE_PRO | 2 | Mifare Pro类型。 | +| TYPE_UNKNOWN | 0 | 未知MIFARE类型。 | +| TYPE_CLASSIC | 1 | MIFARE Classic类型。| +| TYPE_PLUS | 2 | MIFARE Plus类型。| +| TYPE_PRO | 3 | MIFARE Pro类型。 | ## MifareClassicSize9+ -MifareClassic标签存储大小的定义。 - -**需要权限**:ohos.permission.NFC_TAG +MIFARE Classic标签存储大小的定义。 **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | @@ -363,15 +411,13 @@ MifareClassic标签存储大小的定义。 | MC_SIZE_2K | 2048 | 每个标签32个扇区,每个扇区4个块。 | | MC_SIZE_4K | 4096 | 每个标签40个扇区,每个扇区4个块。| -### MifareUltralightType9+ -MifareUltralight标签类型的定义。 - -**需要权限**:ohos.permission.NFC_TAG +## MifareUltralightType9+ +MIFARE Ultralight标签类型的定义。 **系统能力**:SystemCapability.Communication.NFC.Core | **参数名** | **常量值** | **说明** | | -------- | -------- | -------- | -| TYPE_UNKOWN | -1 | 未知的 Mifare 类型。 | -| TYPE_ULTRALIGHT | 1 | Mifare Ultralight类型。| -| TYPE_ULTRALIGHT_C | 2 | Mifare UltralightC 类型。 | +| TYPE_UNKOWN | 0 | 未知的 MIFARE 类型。 | +| TYPE_ULTRALIGHT | 1 | MIFARE Ultralight类型。| +| TYPE_ULTRALIGHT_C | 2 | MIFARE UltralightC 类型。 | \ No newline at end of file diff --git a/zh-cn/application-dev/reference/apis/js-apis-nfctech.md b/zh-cn/application-dev/reference/apis/js-apis-nfctech.md index 2ddd53f960a95e6d2b230017b8c34d17f1c8617f..f198cca93ffad384df83c41be315cc0a0c252b7c 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-nfctech.md +++ b/zh-cn/application-dev/reference/apis/js-apis-nfctech.md @@ -15,7 +15,7 @@ import tag from '@ohos.nfc.tag'; NfcATag 提供 NFC-A(ISO 14443-3A)技术的属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是NfcATag的独有接口。 @@ -40,8 +40,7 @@ getSak(): number ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcA' correctly. - +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcA' correctly. let sak = nfcA.getSak(); console.log("nfcA sak: " + sak); ``` @@ -67,7 +66,7 @@ getAtqa(): number[] ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcA' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcA' correctly. let atqa = nfcA.getAtqa(); console.log("nfcA atqa: " + atqa); ``` @@ -76,7 +75,7 @@ console.log("nfcA atqa: " + atqa); NfcBTag 提供对NFC-B(ISO 14443-3B)技术的属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类,提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类,提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是NfcBTag的独有接口。 @@ -101,7 +100,7 @@ getRespAppData(): number[] ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcB' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcB' correctly. let respAppData = nfcB.getRespAppData(); console.log("nfcB respAppData: " + respAppData); ``` @@ -127,7 +126,7 @@ getRespProtocol(): number[] ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcB' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcB' correctly. let respProtocol = nfcB.getRespProtocol(); console.log("nfcB respProtocol: " + respProtocol); ``` @@ -136,7 +135,7 @@ console.log("nfcB respProtocol: " + respProtocol); NfcFTag 提供对NFC-F(JIS 6319-4)技术的属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是NfcFTag的独有接口。 @@ -161,7 +160,7 @@ getSystemCode(): number[] ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcF' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcF' correctly. let systemCode = nfcF.getSystemCode(); console.log("nfcF systemCode: " + systemCode); ``` @@ -187,7 +186,7 @@ getPmm(): number[] ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcF' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcF' correctly. let pmm = nfcF.getPmm(); console.log("nfcF pmm: " + pmm); ``` @@ -196,7 +195,7 @@ console.log("nfcF pmm: " + pmm); NfcVTag 提供对NFC-V(ISO 15693)技术的属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是NfcVTag的独有接口。 @@ -221,7 +220,7 @@ getResponseFlags(): number ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcV' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcV' correctly. let responseFlags = nfcV.getResponseFlags(); console.log("nfcV responseFlags: " + responseFlags); ``` @@ -247,7 +246,7 @@ getDsfId(): number ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'nfcV' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'nfcV' correctly. let dsfId = nfcV.getDsfId(); console.log("nfcV dsfId: " + dsfId); ``` @@ -256,7 +255,7 @@ console.log("nfcV dsfId: " + dsfId); IsoDepTag 提供对ISO-DEP(ISO 14443-4)技术的属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是IsoDepTag的独有接口。 @@ -264,24 +263,20 @@ TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送 getHistoricalBytes(): number[] -获取标签的历史字节。 - -**需要权限**:ohos.permission.NFC_TAG +获取标签的历史字节,针对基于NfcA通信技术的IsoDep卡片。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| number[] | IsoDepTag 标签的历史字节,每个number十六进制表示,范围是0x00~0xFF。| +| number[] | IsoDepTag 标签的历史字节,每个number十六进制表示,范围是0x00~0xFF。如果该IsoDep类型Tag是基于NfcB技术的,则该返回值为空。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'isoDep' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'isoDep' correctly. let historicalBytes = isoDep.getHistoricalBytes(); console.log("isoDep historicalBytes: " + historicalBytes); ``` @@ -290,24 +285,20 @@ console.log("isoDep historicalBytes: " + historicalBytes); getHiLayerResponse(): number[] -获取标签的HiLayer响应字节。 - -**需要权限**:ohos.permission.NFC_TAG +获取标签的更高层响应字节,针对基于NfcB通信技术的IsoDep卡片。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| number[] | IsoDepTag 标签的HiLayer响应字节,每个number十六进制表示,范围是0x00~0xFF。| +| number[] | IsoDepTag 标签的更高层响应字节,每个number十六进制表示,范围是0x00~0xFF。如果该IsoDep类型Tag是基于NfcA技术的,则该返回值为空。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'isoDep' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'isoDep' correctly. let hiLayerResponse = isoDep.getHiLayerResponse(); console.log("isoDep hiLayerResponse: " + hiLayerResponse); ``` @@ -316,137 +307,368 @@ console.log("isoDep hiLayerResponse: " + hiLayerResponse); isExtendedApduSupported(): Promise<boolean> -检查是否支持扩展的APDU,使用promise方式作为异步方法。 +检查是否支持扩展的APDU,使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | Promise<boolean> | 检查结果,true: 支持, false: 不支持。| -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'isoDep' correctly. -isoDep.isExtendedApduSupported() - .then((data) => { - console.log("isoDep isExtendedApduSupported data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'isoDep' correctly. + +// connect the tag at first if not connected. +if (!isoDep.isTagConnected()) { + if (!isoDep.connectTag()) { + console.log("isoDep connectTag failed."); + return; + } +} + +try { + isoDep.isExtendedApduSupported().then((response) => { + console.log("isoDep isExtendedApduSupported Promise response: " + response); }).catch((err)=> { - console.log("isoDep isExtendedApduSupported err: " + err); + console.log("isoDep isExtendedApduSupported Promise err: " + err); }); +} catch (busiError) { + console.log("isoDep isExtendedApduSupported Promise busiError: " + busiError); +} + ``` ### IsoDepTag.isExtendedApduSupported9+ isExtendedApduSupported(callback: AsyncCallback\): void -检查是否支持扩展的APDU,使用callback方式作为异步方法。 +检查是否支持扩展的APDU,使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | | callback | AsyncCallback\ | 是 | 回调函数,true: 支持, false: 不支持。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | + ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'isoDep' correctly. -isoDep.isExtendedApduSupported((err, data)=> { - if (err) { - console.log("isoDep isExtendedApduSupported err: " + err); - } else { - console.log("isoDep isExtendedApduSupported data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'isoDep' correctly. + +// connect the tag at first if not connected. +if (!isoDep.isTagConnected()) { + if (!isoDep.connectTag()) { + console.log("isoDep connectTag failed."); + return; } -}); +} + +try { + isoDep.isExtendedApduSupported((err, response)=> { + if (err) { + console.log("isoDep isExtendedApduSupported AsyncCallback err: " + err); + } else { + console.log("isoDep isExtendedApduSupported AsyncCallback response: " + response); + } + }); +} catch (busiError) { + console.log("isoDep isExtendedApduSupported AsyncCallback busiError: " + busiError); +} ``` -## NdefTag9+ +## NdefMessage9+ -提供对已格式化为NDEF的NFC标签的数据和操作的访问,继承自TagSession。 +### NdefMessage.getNdefRecords9+ -TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +getNdefRecords(): [NdefRecord](js-apis-nfcTag.md#ndefrecord9)[] -以下是NdefTag的独有接口。 +获取NDEF消息中的所有记录。 -### NdefTag.createNdefMessage9+ +**系统能力**:SystemCapability.Communication.NFC -createNdefMessage(data: number[]): [NdefMessage](#ndefmessage9) +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| [NdefRecord](js-apis-nfcTag.md#ndefrecord9)[] | NDEF标签的Record列表,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | -使用原始字节创建ndef消息。 +**示例:** +```js +import tag from '@ohos.nfc.tag'; -**需要权限**:ohos.permission.NFC_TAG +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); -**系统能力**:SystemCapability.Communication.NFC +let ndefRecords = ndefMessage.getNdefRecords(); +console.log("ndef ndefRecords number: " + ndefRecords.length); +``` + +### NdefMessage.makeUriRecord9+ + +makeUriRecord(uri: string): [NdefRecord](js-apis-nfcTag.md#ndefrecord9); + +根据输入的URI,构建NDEF标签的Record数据对象。 +**系统能力**:SystemCapability.Communication.NFC **参数:** -| **参数名** | **类型** | **必填** | **说明** | -| -------- | -------- | -------- | -------- | -| data | number[] | 是 | 原始字节,每个number十六进制表示,范围是0x00~0xFF | +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| uri | string | 是 | 写入到NDEF Record里面的数据内容。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| [NdefMessage](#ndefmessage9) | NDEF标签的Message,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | +| [NdefRecord](js-apis-nfcTag.md#ndefrecord9) | NDEF标签的Record,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | **示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. Such as: +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); +try { + let uri = "https://gitee.com/openharmony"; // change it to be correct. + let ndefRecord = ndefMessage.makeUriRecord(uri); + if (ndefRecord != undefined) { + console.log("ndefMessage makeUriRecord rtdType: " + ndefRecord.rtdType); + console.log("ndefMessage makeUriRecord payload: " + ndefRecord.payload); + } else { + console.log("ndefMessage makeUriRecord ndefRecord: " + ndefRecord); + } +} catch (busiError) { + console.log("ndefMessage makeUriRecord catched busiError: " + busiError); +} +``` + +### NdefMessage.makeTextRecord9+ + +makeTextRecord(text: string, locale: string): [NdefRecord](js-apis-nfcTag.md#ndefrecord9); + +根据输入的文本数据和编码类型,构建NDEF标签的Record。 + +**系统能力**:SystemCapability.Communication.NFC +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| text | string | 是 | 写入到NDEF Record里面的文本数据内容。 | +| locale | string | 是 | 文本数据内容的编码方式。 | + +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| [NdefRecord](js-apis-nfcTag.md#ndefrecord9) | NDEF标签的Record,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | + +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let rawData = [0x00, 0xa4, 0x04, ......]; // change the raw data bytes tobe correct. -let ndefMessage = ndef.createNdefMessage(rawData); -console.log("ndef ndefMessage: " + ndefMessage); +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. Such as: +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); + +try { + let text = "Hello World"; // change it to be correct. + let locale = "utf8"; // change it to be correct. + let ndefRecord = ndefMessage.makeTextRecord(text, locale); + if (ndefRecord != undefined) { + console.log("ndefMessage makeTextRecord rtdType: " + ndefRecord.rtdType); + console.log("ndefMessage makeTextRecord payload: " + ndefRecord.payload); + } else { + console.log("ndefMessage makeTextRecord ndefRecord: " + ndefRecord); + } +} catch (busiError) { + console.log("ndefMessage makeTextRecord catched busiError: " + busiError); +} ``` -## NdefMessage9+ -### NdefMessage.getNdefRecords9+ +### NdefMessage.makeMimeRecord9+ -getNdefRecords(): [NdefRecord](js-apis-nfcTag.md#ndefrecord9)[ ] +makeMimeRecord(mimeType: string, mimeData: number[]): [NdefRecord](js-apis-nfcTag.md#ndefrecord9); -获取ndef消息的所有记录。 +根据输入的MIME数据和类型,构建NDEF标签的Record。 -**需要权限**:ohos.permission.NFC_TAG +**系统能力**:SystemCapability.Communication.NFC +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| mimeType | string | 是 | MIME数据的类型。 | +| mimeData | number[] | 是 | MIME数据内容。 | + +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| [NdefRecord](js-apis-nfcTag.md#ndefrecord9) | NDEF标签的Record,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | + +**示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. Such as: +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); + +try { + let mimeType = "media"; // change it to be correct. + let mimeData = [0x01, 0x02, 0x03, 0x04]; // change it to be correct. + let ndefRecord = ndefMessage.makeMimeRecord(mimeType, mimeData); + if (ndefRecord != undefined) { + console.log("ndefMessage makeMimeRecord rtdType: " + ndefRecord.rtdType); + console.log("ndefMessage makeMimeRecord payload: " + ndefRecord.payload); + } else { + console.log("ndefMessage makeMimeRecord ndefRecord: " + ndefRecord); + } +} catch (busiError) { + console.log("ndefMessage makeMimeRecord catched busiError: " + busiError); +} +``` +### NdefMessage.makeExternalRecord9+ + +makeExternalRecord(domainName: string, serviceName: string, externalData: number[]): [NdefRecord](js-apis-nfcTag.md#ndefrecord9); + +根据应用程序特定的外部数据,构建NDEF标签的Record。 **系统能力**:SystemCapability.Communication.NFC +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| domainName | string | 是 | 外部数据发布组织的域名,一般是应用程序的包名。 | +| serviceName | string | 是 | 外部数据的指定类型。 | +| externalData | number[] | 是 | 外部数据内容。 | **返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| [NdefRecord](js-apis-nfcTag.md#ndefrecord9) | NDEF标签的Record,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | + +**示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. Such as: +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); + +try { + let domainName = "ohos.nfc.application"; // change it to be correct. + let type = "nfc"; // change it to be correct. + let externalData = [0x01, 0x02, 0x03, 0x04]; // change it to be correct. + let ndefRecord = ndefMessage.makeExternalRecord(domainName, type, externalData); + if (ndefRecord != undefined) { + console.log("ndefMessage makeExternalRecord rtdType: " + ndefRecord.rtdType); + console.log("ndefMessage makeExternalRecord payload: " + ndefRecord.payload); + } else { + console.log("ndefMessage makeExternalRecord ndefRecord: " + ndefRecord); + } +} catch (busiError) { + console.log("ndefMessage makeExternalRecord catched busiError: " + busiError); +} +``` + +### NdefMessage.messageToBytes9+ + +messageToBytes(ndefMessage: [NdefMessage](#ndefmessage9)): number[]; + +把输入的NDEF消息数据对象,转换为字节格式的数据。 +**系统能力**:SystemCapability.Communication.NFC +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| ndefMessage | [NdefMessage](#ndefmessage9) | 是 | NDEF消息数据对象。 | + +**返回值:** | **类型** | **说明** | | ------------------ | --------------------------| -| [NdefRecord](js-apis-nfcTag.md#ndefrecord9)[ ] | NDEF标签的Record列表,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | +| number[] | NDEF消息数据对象,所转换成的字节格式的数据。每个number十六进制表示,范围是0x00~0xFF。 | **示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see NdefTag, obtains ndefMessage from ndefTag.createNdefMessage or ndefTag.getNdefMessage. Such as: +// var ndefMessage = ndefTag.createNdefMessage(...); +// var ndefMessage = ndefTag.getNdefMessage(); + +try { + // the parameter 'ndefMessage' can be different from the instance object. + let rawData = ndefMessage.messageToBytes(ndefMessage); + console.log("ndefMessage messageToBytes rawData: " + rawData); +} catch (busiError) { + console.log("ndefMessage messageToBytes catched busiError: " + busiError); +} +``` + +## NdefTag9+ + +提供对已格式化为NDEF的NFC标签的数据和操作的访问,继承自TagSession。 + +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 + +以下是NdefTag的独有接口。 + +### NdefTag.createNdefMessage9+ + +createNdefMessage(data: number[]): [NdefMessage](#ndefmessage9) + +使用原始字节数据创建NDEF标签的Message。该数据必须符合NDEF Record数据格式,如果不符合格式,则返回的NdeMessage数据对象,所包含的NDE Record列表会为空。 + +**系统能力**:SystemCapability.Communication.NFC + +**参数:** +| **参数名** | **类型** | **必填** | **说明** | +| -------- | -------- | -------- | -------- | +| data | number[] | 是 | 原始字节,每个number十六进制表示,范围是0x00~0xFF。 | +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| [NdefMessage](#ndefmessage9) | NDEF标签的Message,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | + +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefRecords = ndef.getNdefRecords(); -console.log("ndef ndefRecords number: " + ndefRecords.length); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +let rawData = [0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]; // change the raw data bytes to be correct. +let ndefMessage; +try { + ndefMessage = ndefTag.createNdefMessage(rawData); + console.log("ndef createNdefMessage, ndefMessage: " + ndefMessage); +} catch (busiError) { + console.log("ndef createNdefMessage busiError: " + busiError); +} ``` ### NdefTag.createNdefMessage9+ createNdefMessage(ndefRecords: NdefRecord[]): [NdefMessage](#ndefmessage9) -使用记录列表创建NDEF消息。 - -**需要权限**:ohos.permission.NFC_TAG +使用NDEF Records列表,创建NDEF Message。 **系统能力**:SystemCapability.Communication.NFC @@ -456,17 +678,15 @@ createNdefMessage(ndefRecords: NdefRecord[]): [NdefMessage](#ndefmessage9) | ndefRecords | [NdefRecord](js-apis-nfcTag.md#ndefrecord9)[] | 是 | NDEF标签的Record列表,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | [NdefMessage](#ndefmessage9) | NDEF标签的Message,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. let ndefRecords = [ // record format: tnf, rtdType, id, payload // 1st record: @@ -477,33 +697,34 @@ let ndefRecords = [ // other record if has one ... ]; -let ndefMessage = ndef.createNdefMessage(ndefRecords); -console.log("ndef ndefMessage: " + ndefMessage); +let ndefMessage; +try { + ndefMessage = ndefTag.createNdefMessage(ndefRecords); + console.log("ndef createNdefMessage ndefMessage: " + ndefMessage); +} catch (busiError) { + console.log("ndef createNdefMessage busiError: " + busiError); +} ``` ### NdefTag.getNdefTagType9+ getNdefTagType(): NfcForumType -获取Ndef标签的类型。 - -**需要权限**:ohos.permission.NFC_TAG +获取NDEF标签的类型。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | [NfcForumType](js-apis-nfcTag.md#nfcforumtype9) | NDEF标签类型,包括NFC FORUM TYPE 1/2/3/4等。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefTagType = ndef.getNdefTagType(); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +let ndefTagType = ndefTag.getNdefTagType(); console.log("ndef ndefTagType: " + ndefTagType); ``` @@ -513,217 +734,237 @@ getNdefMessage(): NdefMessage 获取发现NDEF标签时,从标签读取的Message。 -**需要权限**:ohos.permission.NFC_TAG - **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | [NdefMessage](#ndefmessage9) | NDEF标签的Message,详见NDEF技术规范《NFCForum-TS-NDEF_1.0》。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefMessage = ndef.getNdefMessage(); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +let ndefMessage = ndefTag.getNdefMessage(); console.log("ndef ndefMessage: " + ndefMessage); ``` ### NdefTag.isNdefWritable9+ -isNdefWritable(): Promise<boolean> - -检查NDEF标签是否可写,使用promise方式作为异步方法。 +isNdefWritable(): boolean; -**需要权限**:ohos.permission.NFC_TAG +检查NDEF标签是否可写。在调用写数据接口前,需要先判断是否支持写操作。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| Promise<boolean> | 检查结果,true: 可写, false: 不可写。| +| boolean | 检查结果,true: 可写, false: 不可写。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.isNdefWritable() - .then((data) => { - console.log("ndef isNdefWritable data: " + data); - }).catch((err)=> { - console.log("ndef isNdefWritable err: " + err); - }); -``` - -### NdefTag.isNdefWritable9+ - -isNdefWritable(callback: AsyncCallback<boolean>): void; - -检查ndef标签是否可写,使用callback方式作为异步方法。 - -**需要权限**:ohos.permission.NFC_TAG - -**系统能力**:SystemCapability.Communication.NFC - -**参数:** - -| 参数名 | 类型 | 必填 | 说明 | -| -------- | ----------------------- | ---- | -------------------------------------- | -| callback | AsyncCallback\ | 是 | 回调函数,NDEF标签可写,返回true。 | - -**示例:** - -```js -import tag from '@ohos.nfc.tag'; - -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.isNdefWritable((err, data)=> { - if (err) { - console.log("ndef isNdefWritable err: " + err); - } else { - console.log("ndef isNdefWritable data: " + data); - } -}); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +var isWritable = ndefTag.isNdefWritable(); +console.log("ndef isNdefWritable: " + isWritable); ``` ### NdefTag.readNdef9+ readNdef(): Promise\ -读取标签上的ndef消息,使用promise方式作为异步方法。 +读取标签上的NDEF消息,使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| Promise\<[NdefMessage](#ndefmessage9)> | 以Promise形式返回从NDEF标签中读取到的Message信息。| +| Promise\<[NdefMessage](#ndefmessage9)> | 以Promise形式返回从NDEF标签中读取到的Message数据对象。| -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.readNdef() - .then((data) => { - console.log("ndef readNdef data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. + +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; + } +} + +try { + ndefTag.readNdef().then((ndefmessage) => { + console.log("ndef readNdef Promise ndefmessage: " + ndefmessage); }).catch((err)=> { - console.log("ndef readNdef err: " + err); + console.log("ndef readNdef Promise err: " + err); }); +} catch (busiError) { + console.log("ndef readNdef Promise catched busiError: " + busiError); +} ``` ### NdefTag.readNdef9+ readNdef(callback: AsyncCallback\<[NdefMessage](#ndefmessage9)>): void -读取标签上的ndef消息,使用callback方式作为异步方法。 +读取标签上的NDEF消息,使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| callback | AsyncCallback\<[NdefMessage](#ndefmessage9)> | 是 | 回调函数。| +| callback | AsyncCallback\<[NdefMessage](#ndefmessage9)> | 是 | 回调函数,返回从NDEF标签中读取到的Message信息。| -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.readNdef((err, data)=> { - if (err) { - console.log("ndef readNdef err: " + err); - } else { - console.log("ndef readNdef data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. + +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; } -}); +} + +try { + ndefTag.readNdef((err, ndefmessage)=> { + if (err) { + console.log("ndef readNdef AsyncCallback err: " + err); + } else { + console.log("ndef readNdef AsyncCallback ndefmessage: " + ndefmessage); + } + }); +} catch (busiError) { + console.log("ndef readNdef AsyncCallback catched busiError: " + busiError); +} ``` ### NdefTag.writeNdef9+ -writeNdef(msg: NdefMessage): Promise\; +writeNdef(msg: NdefMessage): Promise\; -将ndef消息写入标签,使用promise方式作为异步方法。 +将NDEF Messsage数据对象写入标签,使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| msg | NdefMessage | 是 | Ndef消息。| - -**返回值:** +| msg | NdefMessage | 是 | NDEF Message数据对象。| -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 以Promise形式返回,写入执行后的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefMessage = ndef.createNdefMessage([0x01, 0x02, ...]); // change the raw data to be correct. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +// ndefMessage created from raw data, such as: +let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. +// or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) -ndef.writeNdef(ndefMessage) - .then((data) => { - console.log("ndef writeNdef data: " + data); +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; + } +} + +try { + ndefTag.writeNdef(ndefMessage).then(() => { + console.log("ndef writeNdef Promise success."); }).catch((err)=> { console.log("ndef writeNdef err: " + err); }); +} catch (busiError) { + console.log("ndef writeNdef Promise catch busiError: " + busiError); +} ``` ### NdefTag.writeNdef9+ -writeNdef(msg: NdefMessage, callback: AsyncCallback\): void +writeNdef(msg: NdefMessage, callback: AsyncCallback\): void -将ndef消息写入此标签,使用callback方式作为异步方法。 +将NDEF Message数据对象写入此标签,使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| msg | NdefMessage | 是 | Ndef消息 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| msg | NdefMessage | 是 | NDEF Message数据对象。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefMessage = ndef.createNdefMessage([0x01, 0x02, ...]); // change the raw data to be correct. -ndef.writeNdef(ndefMessage, (err, data)=> { - if (err) { - console.log("ndef writeNdef err: " + err); - } else { - console.log("ndef writeNdef data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +// ndefMessage created from raw data, such as: +let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. +// or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) + +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; } -}); +} + +try { + ndefTag.writeNdef(ndefMessage, (err)=> { + if (err) { + console.log("ndef writeNdef AsyncCallback err: " + err); + } else { + console.log("ndef writeNdef AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("ndef writeNdef AsyncCallback catch busiError: " + busiError); +} ``` ### NdefTag.canSetReadOnly9+ @@ -737,659 +978,874 @@ canSetReadOnly(): boolean **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | boolean| true: NDEF标签可设置为只读, false: NDEF标签不可设置为只读。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -var canSetReadOnly = ndef.canSetReadOnly(); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. +var canSetReadOnly = ndefTag.canSetReadOnly(); console.log("ndef canSetReadOnly: " + canSetReadOnly); ``` ### NdefTag.setReadOnly9+ -setReadOnly(): Promise\ +setReadOnly(): Promise\ -将Ndef标签设置为只读,使用promise方式作为异步方法。 +将NDEF标签设置为只读,使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise<number> | 0: 设置成功, 其它: 错误编码。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.setReadOnly() - .then((data) => { - console.log("ndef setReadOnly data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. + +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; + } +} + +try { + ndefTag.setReadOnly().then(() => { + console.log("ndef setReadOnly Promise success."); }).catch((err)=> { - console.log("ndef setReadOnly err: " + err); + console.log("ndef setReadOnly Promise err: " + err); }); +} catch (busiError) { + console.log("ndef setReadOnly Promise catch busiError: " + busiError); +} ``` ### NdefTag.setReadOnly9+ -setReadOnly(callback: AsyncCallback\): void +setReadOnly(callback: AsyncCallback\): void -将Ndef标签设置为只读,使用callback方式作为异步方法。 +将NDEF标签设置为只读,使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -ndef.setReadOnly((err, data)=> { - if (err) { - console.log("ndef setReadOnly err: " + err); - } else { - console.log("ndef setReadOnly data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. + +// connect the tag at first if not connected. +if (!ndefTag.isTagConnected()) { + if (!ndefTag.connectTag()) { + console.log("ndefTag connectTag failed."); + return; } -}); +} + +try { + ndefTag.setReadOnly((err)=> { + if (err) { + console.log("ndef setReadOnly AsyncCallback err: " + err); + } else { + console.log("ndef setReadOnly AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("ndef setReadOnly AsyncCallback catch busiError: " + busiError); +} ``` ### NdefTag.getNdefTagTypeString9+ getNdefTagTypeString(type: [NfcForumType](js-apis-nfcTag.md#nfcforumtype9)): string -将Nfc论坛类型转换为Nfc论坛中定义的字节数组。 - -**需要权限**:ohos.permission.NFC_TAG +将NFC论坛类型,转换为NFC论坛中定义的字符串描述。 **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | | type | [NfcForumType](js-apis-nfcTag.md#nfcforumtype9) | 是 | NDEF标签类型,包括NFC FORUM TYPE 1/2/3/4等。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | string | NFC论坛类型的字符串描述。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let ndefTypeString = ndef.getNdefTagTypeString(tag.NFC_FORUM_TYPE_1); -console.log("ndef ndefTypeString: " + ndefTypeString); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefTag' correctly. + +try { + let ndefTypeString = ndefTag.getNdefTagTypeString(tag.NFC_FORUM_TYPE_1); + console.log("ndef ndefTypeString: " + ndefTypeString); +} catch (busiError) { + console.log("ndef getNdefTagTypeString catch busiError: " + busiError); +} ``` ## MifareClassicTag9+ -MifareClassicTag提供对MIFARE经典属性和I/O操作的访问,继承自TagSession。 +MifareClassicTag提供对MIFARE Classic属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是MifareClassicTag的独有接口。 ### MifareClassicTag.authenticateSector9+ -authenticateSector(sectorIndex: number, key: number[], isKeyA: boolean): Promise\ +authenticateSector(sectorIndex: number, key: number[], isKeyA: boolean): Promise\ -使用密钥对扇区进行身份验证,只有身份验证成功的扇区可以进行操作。使用promise方式作为异步方法。 +使用密钥对扇区进行身份验证,只有身份验证成功的扇区可以进行操作。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| sectorIndex | number | 是 | 待验证的扇区索引 | -| key | number[]| 是 | 用于身份验证的密钥(6字节) | +| sectorIndex | number | 是 | 待验证的扇区索引,从0开始。 | +| key | number[]| 是 | 用于扇区验证的密钥(6字节)。 | | isKeyA | boolean | 是 | isKeyA标志。true 表示KeyA,false 表示KeyB。| -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 身份验证结果,成功返回true,失败返回false。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let sectorIndex = 1; // change it to be correct index. -let key = [0x04, 0x05, ....]; // change it to be correct key. -mifareClassic.authenticateSector(sectorIndex, key, true); - .then((data) => { - console.log("mifareClassic authenticateSector data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; + } +} + +try { + let sectorIndex = 1; // change it to be correct index. + let key = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06] // MUST be 6 bytes, change it to be correct key. + mifareClassic.authenticateSector(sectorIndex, key, true).then(() => { + console.log("mifareClassic authenticateSector Promise success."); }).catch((err)=> { - console.log("mifareClassic authenticateSector err: " + err); + console.log("mifareClassic authenticateSector Promise err: " + err); }); +} catch (busiError) { + console.log("mifareClassic authenticateSector Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.authenticateSector9+ -authenticateSector(sectorIndex: number, key: number[], isKeyA: boolean, callback: AsyncCallback\): void +authenticateSector(sectorIndex: number, key: number[], isKeyA: boolean, callback: AsyncCallback\): void -使用密钥对扇区进行身份验证,只有身份验证成功的扇区可以进行操作。使用callback方式作为异步方法。 +使用密钥对扇区进行身份验证,只有身份验证成功的扇区可以进行操作。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| sectorIndex | number | 是 | 待验证的扇区索引。 | -| key | number[]| 是 | 用于身份验证的密钥(6字节)。 | +| sectorIndex | number | 是 | 待验证的扇区索引,从0开始。 | +| key | number[]| 是 | 用于扇区验证的密钥(6字节)。 | | isKeyA | boolean | 是 | isKeyA标志。true 表示KeyA,false 表示KeyB。| -| callback | AsyncCallback\ | 是 | 回调函数。| +| callback | AsyncCallback\ | 是 | 回调函数。| -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let sectorIndex = 1; // change it to be correct index. -let key = [0x04, 0x05, ....]; // change it to be correct key. -mifareClassic.authenticateSector(sectorIndex, key, true, (err, data)=> { - if (err) { - console.log("mifareClassic authenticateSector err: " + err); - } else { - console.log("mifareClassic authenticateSector data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let sectorIndex = 1; // change it to be correct index. + let key = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06] // MUST be 6 bytes, change it to be correct key. + mifareClassic.authenticateSector(sectorIndex, key, true, (err)=> { + if (err) { + console.log("mifareClassic authenticateSector AsyncCallback err: " + err); + } else { + console.log("mifareClassic authenticateSector AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic authenticateSector AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.readSingleBlock9+ readSingleBlock(blockIndex: number): Promise\ -读取标签中一个块存储的内容,一个块大小为16字节。使用promise方式作为异步方法。 +读取标签中一个块存储的内容,一个块大小为16字节。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要读取的块索引。 | +| blockIndex | number | 是 | 要读取的块索引,从0开始。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | Promise\ | 读取的块数据。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.readSingleBlock(blockIndex, (err, data)=> { - if (err) { - console.log("mifareClassic readSingleBlock err: " + err); - } else { - console.log("mifareClassic readSingleBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.readSingleBlock(blockIndex).then((data) => { + console.log("mifareClassic readSingleBlock Promise data: " + data); + }).catch((err)=> { + console.log("mifareClassic readSingleBlock Promise err: " + err); + }); +} catch (busiError) { + console.log("mifareClassic readSingleBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.readSingleBlock9+ readSingleBlock(blockIndex: number, callback: AsyncCallback\): void -读取标签中一个块存储的内容,一个块大小为16字节。使用callback方式作为异步方法。 +读取标签中一个块存储的内容,一个块大小为16字节。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要读取的块索引 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| blockIndex | number | 是 | 要读取的块索引,从0开始。 | +| callback | AsyncCallback\ | 是 | 回调函数,返回读取到的数据。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.readSingleBlock(blockIndex, (err, data)=> { - if (err) { - console.log("mifareClassic readSingleBlock err: " + err); - } else { - console.log("mifareClassic readSingleBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.readSingleBlock(blockIndex, (err, data)=> { + if (err) { + console.log("mifareClassic readSingleBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic readSingleBlock AsyncCallback data: " + data); + } + }); +} catch (busiError) { + console.log("mifareClassic readSingleBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.writeSingleBlock9+ -writeSingleBlock(blockIndex: number, data: number[]): Promise\ +writeSingleBlock(blockIndex: number, data: number[]): Promise\ -向标签中一个块存储写入内容,一个块大小为16字节。使用promise方式作为异步方法。 +向标签中一个块存储写入内容,一个块大小为16字节。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要写入的块索引。 | -| data | number[] | 是 | 要写入的数据。 | +| blockIndex | number | 是 | 要写入的块索引,从0开始。 | +| data | number[] | 是 | 要写入的数据,大小必须是16个字节。 | -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行写入操作返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let rawData = [0x0a, 0x14, ...]; // change it to be correct data. -mifareClassic.writeSingleBlock(blockIndex, rawData, (err, data)=> { - if (err) { - console.log("mifareClassic writeSingleBlock err: " + err); - } else { - console.log("mifareClassic writeSingleBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let rawData = [0x01, 0x02, ..., 0x0F, 0x10]; // MUST be 16 bytes, change it to be correct data. + mifareClassic.writeSingleBlock(blockIndex, rawData).then(() => { + console.log("mifareClassic writeSingleBlock Promise success."); + }).catch((err)=> { + console.log("mifareClassic writeSingleBlock Promise err: " + err); + }); +} catch (busiError) { + console.log("mifareClassic writeSingleBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.writeSingleBlock9+ -writeSingleBlock(blockIndex: number, data: number[], callback: AsyncCallback\): void +writeSingleBlock(blockIndex: number, data: number[], callback: AsyncCallback\): void -向标签中一个块存储写入内容,一个块大小为16字节。使用callback方式作为异步方法。 +向标签中一个块存储写入内容,一个块大小为16字节。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要写入的块索引 | -| data | number[] | 是 | 要写入的数据 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| blockIndex | number | 是 | 要写入的块索引,从0开始。 | +| data | number[] | 是 | 要写入的数据,大小必须是16个字节。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let rawData = [0x0a, 0x14, ...]; // change it to be correct data. -mifareClassic.writeSingleBlock(blockIndex, rawData, (err, data)=> { - if (err) { - console.log("mifareClassic writeSingleBlock err: " + err); - } else { - console.log("mifareClassic writeSingleBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let rawData = [0x01, 0x02, ..., 0x15, 0x16]; // MUST be 16 bytes, change it to be correct data. + mifareClassic.writeSingleBlock(blockIndex, rawData, (err)=> { + if (err) { + console.log("mifareClassic writeSingleBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic writeSingleBlock AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic writeSingleBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.incrementBlock9+ -incrementBlock(blockIndex: number, value: number): Promise\ +incrementBlock(blockIndex: number, value: number): Promise\ -增加一块带值的区域块。使用promise方式作为异步方法。 +对指定块的内容,增加指定的数值。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要增加的块索引。 | -| value | number | 是 | 要增加的块数据,非负值。 | +| blockIndex | number | 是 | 要指定增加的块索引,从0开始。 | +| value | number | 是 | 要指定增加的数据,非负数。 | -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行新增操作返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let value = 0x20; // change it to be correct data. -mifareClassic.incrementBlock(blockIndex, value, (err, data)=> { - if (err) { - console.log("mifareClassic incrementBlock err: " + err); - } else { - console.log("mifareClassic incrementBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let value = 0x20; // change it to be correct data. + mifareClassic.incrementBlock(blockIndex, value).then(() => { + console.log("mifareClassic incrementBlock Promise success."); + }).catch((err)=> { + console.log("mifareClassic incrementBlock Promise err: " + err); + }); +} catch (busiError) { + console.log("mifareClassic incrementBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.incrementBlock9+ -incrementBlock(blockIndex: number, value: number, callback: AsyncCallback\): void +incrementBlock(blockIndex: number, value: number, callback: AsyncCallback\): void -增加一块带值的区域块。使用callback方式作为异步方法。 +对指定块的内容,增加指定的数值。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要增加的块索引。 | -| value | number | 是 | 要增加的块数据,非负值。 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| blockIndex | number | 是 | 要被运算的块索引,从0开始。 | +| value | number | 是 | 要增加的数值,非负数。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let value = 0x20; // change it to be correct data. -mifareClassic.incrementBlock(blockIndex, value, (err, data)=> { - if (err) { - console.log("mifareClassic incrementBlock err: " + err); - } else { - console.log("mifareClassic incrementBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let value = 0x20; // change it to be correct data. + mifareClassic.incrementBlock(blockIndex, value, (err)=> { + if (err) { + console.log("mifareClassic incrementBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic incrementBlock AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic incrementBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.decrementBlock9+ -decrementBlock(blockIndex: number, value: number): Promise\ +decrementBlock(blockIndex: number, value: number): Promise\ -递减一块带值的区域块。使用promise方式作为异步方法。 +对指定块的内容,减少指定的数值。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要递减的块索引。 | -| value | number | 是 | 要递减的块数据,非负值。 | +| blockIndex | number | 是 | 要被运算的块索引,从0开始。 | +| value | number | 是 | 要减少的数值,非负数。 | -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行递减操作返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let value = 0x20; // change it to be correct data. -mifareClassic.decrementBlock(blockIndex, value, (err, data)=> { - if (err) { - console.log("mifareClassic decrementBlock err: " + err); - } else { - console.log("mifareClassic decrementBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let value = 0x20; // change it to be correct data. + mifareClassic.decrementBlock(blockIndex, value).then(() => { + console.log("mifareClassic decrementBlock Promise success."); + }).catch((err)=> { + console.log("mifareClassic decrementBlock Promise err: " + err); + }); +} catch (busiError) { + console.log("mifareClassic decrementBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.decrementBlock9+ -decrementBlock(blockIndex: number, value: number, callback: AsyncCallback\): void +decrementBlock(blockIndex: number, value: number, callback: AsyncCallback\): void -递减一块带值的区域块。使用callback方式作为异步方法。 +对指定块的内容,减少指定的数值。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 要递减的块索引。 | -| value | number | 是 | 要递减的块数据,非负值。 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| blockIndex | number | 是 | 要被运算的块索引,从0开始。 | +| value | number | 是 | 要减少的数值,非负数。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let value = 0x20; // change it to be correct data. -mifareClassic.decrementBlock(blockIndex, value, (err, data)=> { - if (err) { - console.log("mifareClassic decrementBlock err: " + err); - } else { - console.log("mifareClassic decrementBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + let value = 0x20; // change it to be correct data. + mifareClassic.decrementBlock(blockIndex, value, (err)=> { + if (err) { + console.log("mifareClassic decrementBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic decrementBlock AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic decrementBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.transferToBlock9+ -transferToBlock(blockIndex: number): Promise\ +transferToBlock(blockIndex: number): Promise\ -将寄存器的值复制到块。使用promise方式作为异步方法。 +将临时寄存器的值转移到指定的块。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 复制的目的块索引。 | +| blockIndex | number | 是 | 被操作的块的索引,从0开始。 | -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行复制操作返回的错误代码。如果返回0,表示成功;否则返回错误码。| +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js - import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.transferToBlock(blockIndex, (err, data)=> { - if (err) { - console.log("mifareClassic transferToBlock err: " + err); - } else { - console.log("mifareClassic transferToBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.transferToBlock(blockIndex).then(() => { + console.log("mifareClassic transferToBlock Promise success."); + }).catch((err)=> { + console.log("mifareClassic transferToBlock Promise err: " + err); + }); +} catch (busiError) { + console.log("mifareClassic transferToBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.transferToBlock9+ -transferToBlock(blockIndex: number, callback: AsyncCallback\): void +transferToBlock(blockIndex: number, callback: AsyncCallback\): void -将寄存器的值复制到块。使用callback方式作为异步方法。 +将临时寄存器的值转移到指定的块。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 复制的目的块索引 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| blockIndex | number | 是 | 被操作的块的索引,从0开始。 | +| callback | AsyncCallback\ | 是 | 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.transferToBlock(blockIndex, (err, data)=> { - if (err) { - console.log("mifareClassic transferToBlock err: " + err); - } else { - console.log("mifareClassic transferToBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.transferToBlock(blockIndex, (err)=> { + if (err) { + console.log("mifareClassic transferToBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic transferToBlock AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic transferToBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.restoreFromBlock9+ -restoreFromBlock(blockIndex: number): Promise\ +restoreFromBlock(blockIndex: number): Promise\ -将块的值复制到寄存器。使用promise方式作为异步方法。 +将指定块的值复制到临时寄存器。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 复制的源块索引。| - -**返回值:** +| blockIndex | number | 是 | 被操作的块的索引,从0开始。| -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行复制操作返回的错误代码。如果返回0,表示成功;否则返回错误码。| +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js - import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.restoreFromBlock(blockIndex) - .then((data) => { - console.log("mifareClassic restoreFromBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; + } +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.restoreFromBlock(blockIndex).then(() => { + console.log("mifareClassic restoreFromBlock Promise success."); }).catch((err)=> { - console.log("mifareClassic isExtendrestoreFromBlockedApduSupported err: " + err); + console.log("mifareClassic restoreFromBlock Promise err: " + err); }); +} catch (busiError) { + console.log("mifareClassic restoreFromBlock Promise catch busiError: " + busiError); +} ``` ### MifareClassicTag.restoreFromBlock9+ -restoreFromBlock(blockIndex: number, callback: AsyncCallback\): void +restoreFromBlock(blockIndex: number, callback: AsyncCallback\): void -将块的值复制到寄存器。使用callback方式作为异步方法。 +将指定块的值复制到临时寄存器。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 复制的源块索引 | -| callback | AsyncCallback\ | 是 | 回调函数。| +| blockIndex | number | 是 | 被操作的块的索引,从0开始。 | +| callback | AsyncCallback\ | 是 | 回调函数。| -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -mifareClassic.restoreFromBlock(blockIndex, (err, data)=> { - if (err) { - console.log("mifareClassic restoreFromBlock err: " + err); - } else { - console.log("mifareClassic restoreFromBlock data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +// connect the tag at first if not connected. +if (!mifareClassic.isTagConnected()) { + if (!mifareClassic.connectTag()) { + console.log("mifareClassic connectTag failed."); + return; } -}); +} + +try { + let blockIndex = 1; // change it to be correct index. + mifareClassic.restoreFromBlock(blockIndex, (err)=> { + if (err) { + console.log("mifareClassic restoreFromBlock AsyncCallback err: " + err); + } else { + console.log("mifareClassic restoreFromBlock AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareClassic restoreFromBlock AsyncCallback catch busiError: " + busiError); +} ``` ### MifareClassicTag.getSectorCount9+ getSectorCount(): number -获取mifare classic标签中的扇区数。 - -**需要权限**:ohos.permission.NFC_TAG +获取MIFARE Classic标签中的扇区数。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| number | 扇区数量。| +| number | 标签中的扇区数量。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. let sectorCount = mifareClassic.getSectorCount(); console.log("mifareClassic sectorCount: " + sectorCount); ``` @@ -1398,56 +1854,53 @@ console.log("mifareClassic sectorCount: " + sectorCount); getBlockCountInSector(sectorIndex: number): number -获取扇区中的块数。 - -**需要权限**:ohos.permission.NFC_TAG +获取指定扇区中的块数。 **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| sectorIndex | number | 是 | 扇区序号。| +| sectorIndex | number | 是 | 扇区序号,从0开始。| **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | number | 该扇区内的块数量。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockCountInSector = mifareClassic.getBlockCountInSector(); -console.log("mifareClassic blockCountInSector: " + blockCountInSector); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +try { + let sectorIndex = 1; // change it to be correct index. + let blockCnt = mifareClassic.getBlockCountInSector(sectorIndex); + console.log("mifareClassic blockCnt: " + blockCnt); +} catch (busiError) { + console.log("mifareClassic getBlockCountInSector catch busiError: " + busiError); +} ``` ### MifareClassicTag.getType9+ getType(): [MifareClassicType](js-apis-nfcTag.md#mifareclassictype9) -获取MifareClassic标签的类型。 - -**需要权限**:ohos.permission.NFC_TAG +获取MIFARE Classic标签的类型。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | [MifareClassicType](js-apis-nfcTag.md#mifareclassictype9) | MifareClassic标签的类型。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. let getType = mifareClassic.getType(); console.log("mifareClassic getType: " + getType); ``` @@ -1456,24 +1909,20 @@ console.log("mifareClassic getType: " + getType); getTagSize(): number -获取标签的大小(字节),具体请参见[MifareClassicSize](js-apis-nfcTag.md#mifareclassicsize9)。 - -**需要权限**:ohos.permission.NFC_TAG +获取标签的存储空间大小,具体请参见[MifareClassicSize](js-apis-nfcTag.md#mifareclassicsize9)。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | number | 标签的大小,单位为字节,请参见[MifareClassicSize](js-apis-nfcTag.md#mifareclassicsize9)。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. let tagSize = mifareClassic.getTagSize(); console.log("mifareClassic tagSize: " + tagSize); ``` @@ -1482,24 +1931,20 @@ console.log("mifareClassic tagSize: " + tagSize); isEmulatedTag(): boolean -检查标签是否已模拟。 - -**需要权限**:ohos.permission.NFC_TAG +检查标签是不是被模拟的。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | boolean |检查结果,true: 是;false:否。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. let isEmulatedTag = mifareClassic.isEmulatedTag(); console.log("mifareClassic isEmulatedTag: " + isEmulatedTag); ``` @@ -1508,73 +1953,75 @@ console.log("mifareClassic isEmulatedTag: " + isEmulatedTag); getBlockIndex(sectorIndex: number): number -获取特定扇区的第一个块。 - -**需要权限**:ohos.permission.NFC_TAG +获取特定扇区的第一个块的序号。 **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| sectorIndex | number | 是 | 扇区序号。 | +| sectorIndex | number | 是 | 扇区序号,从0开始。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| number | 该扇区内的第一个块的序列号。 | +| number | 该扇区内的第一个块的序号,从0开始。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let sectorIndex = 1; // change it to be correct index. -let blockIndex = mifareClassic.getBlockIndex(sectorIndex); -console.log("mifareClassic blockIndex: " + blockIndex); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +try { + let sectorIndex = 1; // change it to be correct index. + let blockIndex = mifareClassic.getBlockIndex(sectorIndex); + console.log("mifareClassic blockIndex: " + blockIndex); +} catch (busiError) { + console.log("mifareClassic getBlockIndex catch busiError: " + busiError); +} ``` ### MifareClassicTag.getSectorIndex9+ getSectorIndex(blockIndex: number): number -获取扇区索引,该扇区包含特定块。 +获取包含指定块号的扇区序号。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| blockIndex | number | 是 | 块序号。 | +| blockIndex | number | 是 | 块序号,从0开始。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| number | 扇区序号。 | +| number | 扇区序号,从0开始。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareClassic' correctly. -let blockIndex = 1; // change it to be correct index. -let sectorIndex = mifareClassic.getSectorIndex(blockIndex); -console.log("mifareClassic sectorIndex: " + sectorIndex); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareClassic' correctly. + +try { + let blockIndex = 1; // change it to be correct index. + let sectorIndex = mifareClassic.getSectorIndex(blockIndex); + console.log("mifareClassic sectorIndex: " + sectorIndex); +} catch (busiError) { + console.log("mifareClassic getSectorIndex catch busiError: " + busiError); +} ``` ## MifareUltralightTag9+ -MifareUltralightTag 提供对MIFARE超轻属性和I/O操作的访问,继承自TagSession。 +MifareUltralightTag 提供对MIFARE Ultralight属性和I/O操作的访问,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是MifareUltralightTag的独有接口。 @@ -1582,7 +2029,7 @@ TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送 readMultiplePages(pageIndex: number): Promise\ -阅读4页,共16字节。页面大小为4字节。使用promise方式作为异步方法。 +读取标签的4页数据,共16字节的数据。每个页面数据大小为4字节。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG @@ -1592,298 +2039,383 @@ readMultiplePages(pageIndex: number): Promise\ | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | ------------------------------ | -| pageIndex | number | 是 | 要读取页面的索引。 | +| pageIndex | number | 是 | 要读取页面的索引,从0开始。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| Promise\ | 读取的4页的数据。 | +| Promise\ | 读取的4页的数据,共16字节。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareUltralight' correctly. -let pageIndex = 1; // change it to be correct index. -mifareUltralight.readMultiplePages(pageIndex) - .then((data) => { - console.log("mifareUltralight readMultiplePages data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareUltralight' correctly. + +// connect the tag at first if not connected. +if (!mifareUltralight.isTagConnected()) { + if (!mifareUltralight.connectTag()) { + console.log("mifareUltralight connectTag failed."); + return; + } +} + +try { + let pageIndex = 1; // change it to be correct index. + mifareUltralight.readMultiplePages(pageIndex).then((data) => { + console.log("mifareUltralight readMultiplePages Promise data = " + data); }).catch((err)=> { - console.log("mifareUltralight readMultiplePages err: " + err); + console.log("mifareUltralight readMultiplePages Promise err: " + err); }); +} catch (busiError) { + console.log("mifareUltralight readMultiplePages Promise catch busiError: " + busiError); +} ``` ### MifareUltralightTag.readMultiplePages9+ readMultiplePages(pageIndex: number, callback: AsyncCallback\): void -阅读4页,共16字节。页面大小为4字节。使用callback方式作为异步方法。 +读取标签的4页数据,共16字节的数据。每个页面数据大小为4字节。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| pageIndex | number | 是 | 要读取页面的索引 | -| callback | AsyncCallback\ | 是 | 回调函数。 | +| pageIndex | number | 是 | 要读取页面的索引,从0开始。 | +| callback | AsyncCallback\ | 是 | 回调函数,返回读取到的数据,共16字节。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareUltralight' correctly. -let pageIndex = 1; // change it to be correct index. -mifareUltralight.readMultiplePages(pageIndex, (err, data)=> { - if (err) { - console.log("mifareUltralight readMultiplePages err: " + err); - } else { - console.log("mifareUltralight readMultiplePages data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareUltralight' correctly. + +// connect the tag at first if not connected. +if (!mifareUltralight.isTagConnected()) { + if (!mifareUltralight.connectTag()) { + console.log("mifareUltralight connectTag failed."); + return; } -}); +} + +try { + let pageIndex = 1; // change it to be correct index. + mifareUltralight.readMultiplePages(pageIndex, (err, data)=> { + if (err) { + console.log("mifareUltralight readMultiplePages AsyncCallback err: " + err); + } else { + console.log("mifareUltralight readMultiplePages AsyncCallback data: " + data); + } + }); +} catch (busiError) { + console.log("mifareUltralight readMultiplePages AsyncCallback catch busiError: " + busiError); +} ``` -### MifareUltralightTag.writeSinglePages9+ +### MifareUltralightTag.writeSinglePage9+ -writeSinglePages(pageIndex: number, data: number[]): Promise\ +writeSinglePage(pageIndex: number, data: number[]): Promise\ -写入一页数据,页面大小为4字节。使用promise方式作为异步方法。 +写入一页数据,数据大小为4字节。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| pageIndex | number | 是 | 要写入页面的索引。 | -| data | number[] | 是 | 要写入页面的数据内容。 | - -**返回值:** +| pageIndex | number | 是 | 要写入页面的索引,从0开始。 | +| data | number[] | 是 | 要写入页面的数据内容,必须是4个字节大小。 | -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行写入操作返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareUltralight' correctly. -let pageIndex = 1; // change it to be correct index. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -mifareUltralight.writeSinglePages(pageIndex, data) - .then((data) => { - console.log("mifareUltralight writeSinglePages data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareUltralight' correctly. + +// connect the tag at first if not connected. +if (!mifareUltralight.isTagConnected()) { + if (!mifareUltralight.connectTag()) { + console.log("mifareUltralight connectTag failed."); + return; + } +} + +try { + let pageIndex = 1; // change it to be correct index. + let rawData = [0x01, 0x02, 0x03, 0x04]; // MUST be 4 bytes, change it to be correct raw data. + mifareUltralight.writeSinglePage(pageIndex, rawData).then(() => { + console.log("mifareUltralight writeSinglePage Promise success."); }).catch((err)=> { - console.log("mifareUltralight writeSinglePages err: " + err); + console.log("mifareUltralight writeSinglePage Promise err: " + err); }); +} catch (busiError) { + console.log("mifareUltralight writeSinglePage Promise catch busiError: " + busiError); +} ``` -### MifareUltralightTag.writeSinglePages9+ +### MifareUltralightTag.writeSinglePage9+ -writeSinglePages(pageIndex: number, data: number[], callback: AsyncCallback\): void +writeSinglePage(pageIndex: number, data: number[], callback: AsyncCallback\): void -写入一页数据,页面大小为4字节。使用callback方式作为异步方法。 +写入一页数据,数据大小为4字节。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | ------------------------ | -| pageIndex | number | 是 | 要写入页面的索引。 | -| data | number[] | 是 | 要写入页面的数据内容。 | -| callback|AsyncCallback\ |是| 回调函数。 | +| pageIndex | number | 是 | 要写入页面的索引,从0开始。 | +| data | number[] | 是 | 要写入页面的数据内容,必须是4个字节大小。 | +| callback|AsyncCallback\ |是| 回调函数。 | -**示例:** +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | +**示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareUltralight' correctly. -let pageIndex = 1; // change it to be correct index. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -mifareUltralight.writeSinglePages(pageIndex, data, (err, data)=> { - if (err) { - console.log("mifareUltralight writeSinglePages err: " + err); - } else { - console.log("mifareUltralight writeSinglePages data: " + data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareUltralight' correctly. + +// connect the tag at first if not connected. +if (!mifareUltralight.isTagConnected()) { + if (!mifareUltralight.connectTag()) { + console.log("mifareUltralight connectTag failed."); + return; } -}); +} + +try { + let pageIndex = 1; // change it to be correct index. + let rawData = [0x01, 0x02, 0x03, 0x04]; // MUST be 4 bytes, change it to be correct raw data. + mifareUltralight.writeSinglePage(pageIndex, rawData, (err)=> { + if (err) { + console.log("mifareUltralight writeSinglePage AsyncCallback err: " + err); + } else { + console.log("mifareUltralight writeSinglePage AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("mifareUltralight writeSinglePage AsyncCallback catch busiError: " + busiError); +} ``` ### MifareUltralightTag.getType9+ getType(): MifareUltralightType -获取MifareUltralight标签的类型,以字节形式返回,具体请参见 [MifareUltralightType](js-apis-nfcTag.md#mifareultralighttype9)。 - -**需要权限**:ohos.permission.NFC_TAG +获取MIFARE Ultralight标签的类型,具体请参见 [MifareUltralightType](js-apis-nfcTag.md#mifareultralighttype9)。 **系统能力**:SystemCapability.Communication.NFC **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| MifareUltralightType | MifareUltralight标签的类型, 具体请参见 [MifareUltralightType](js-apis-nfcTag.md#mifareultralighttype9)。| +| MifareUltralightType | MIFARE Ultralight标签的类型,具体请参见 [MifareUltralightType](js-apis-nfcTag.md#mifareultralighttype9)。| **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'mifareUltralight' correctly. +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'mifareUltralight' correctly. let getType = mifareClassic.getType(); console.log("mifareUltralight getType: " + getType); ``` ## NdefFormatableTag9+ -NdefFormatableTag为NDEF formattable的标签提供格式化操作,继承自TagSession。 +NdefFormatableTag为NDEF Formattable的标签提供格式化操作,继承自TagSession。 -TagSession是所有Nfc tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 +TagSession是所有NFC Tag 技术类型的基类, 提供建立连接和发送数据等共同接口。具体请参见[TagSession](js-apis-tagSession.md)。 以下是NdefFormatableTag的独有接口。 ### NdefFormatableTag.format9+ -format(message: [NdefMessage](#ndefmessage9)): Promise\ +format(message: [NdefMessage](#ndefmessage9)): Promise\ -将标签格式化为NDEF标签,然后将NDEF消息写入NDEF标签。使用promise方式作为异步方法。 +将标签格式化为NDEF标签,将NDEF消息写入NDEF标签。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| message | [NdefMessage](#ndefmessage9) | 是 | 格式化成功时要写入的Ndef消息。可以为null,为null时仅格式化标签,不写入内容。 | +| message | [NdefMessage](#ndefmessage9) | 是 | 格式化成功时要写入的NDEF消息。可以为null,为null时仅格式化标签,不写入内容。 | -**返回值:** - -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行操作后返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -let ndefmessage = ndef.createNdefMessage(data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefFormatable' correctly. -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndefFormatable' correctly. -ndefFormatable.format(ndefmessage, (err, data)=> { - if (err) { - console.log("ndefFormatable format err: " + err); - } else { - console.log("ndefFormatable format data: " + data); +// connect the tag at first if not connected. +if (!ndefFormatable.isTagConnected()) { + if (!ndefFormatable.connectTag()) { + console.log("ndefFormatable connectTag failed."); + return; } -}); +} + +try { + // ndefMessage created from raw data, such as: + let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. + // or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) + + ndefFormatable.format(ndefMessage).then(() => { + console.log("ndefFormatable format Promise success."); + }).catch((err)=> { + console.log("ndefFormatable format Promise err: " + err); + }); +} catch (busiError) { + console.log("ndefFormatable format Promise catch busiError: " + busiError); +} ``` ### NdefFormatableTag.format9+ -format(message: [NdefMessage](#ndefmessage9), callback: AsyncCallback\): void +format(message: [NdefMessage](#ndefmessage9), callback: AsyncCallback\): void -将标签格式化为NDEF标签,然后将NDEF消息写入NDEF标签。使用callback方式作为异步方法。 +将标签格式化为NDEF标签,然后将NDEF消息写入NDEF标签。使用AsyncCallback方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | | message | [NdefMessage](#ndefmessage9) | 是 | 格式化成功时要写入的Ndef消息。可以为null,为null时仅格式化标签,不写入内容。 | **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| callback: AsyncCallback\ | 回调函数。 | +| callback: AsyncCallback\ | 回调函数。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -let ndefmessage = ndef.createNdefMessage(data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefFormatable' correctly. -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndefFormatable' correctly. -ndefFormatable.format(ndefmessage, (err, data)=> { - if (err) { - console.log("ndefFormatable format err: " + err); - } else { - console.log("ndefFormatable format data: " + data); +// connect the tag at first if not connected. +if (!ndefFormatable.isTagConnected()) { + if (!ndefFormatable.connectTag()) { + console.log("ndefFormatable connectTag failed."); + return; } -}); +} + +try { + // ndefMessage created from raw data, such as: + let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. + // or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) + + ndefFormatable.format(ndefMessage, (err)=> { + if (err) { + console.log("ndefFormatable format AsyncCallback err: " + err); + } else { + console.log("ndefFormatable format AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("ndefFormatable format AsyncCallback catch busiError: " + busiError); +} ``` ### NdefFormatableTag.formatReadOnly9+ -formatReadOnly(message: [NdefMessage](#ndefmessage9)): Promise\ +formatReadOnly(message: [NdefMessage](#ndefmessage9)): Promise\ -将标签格式化为NDEF标签,然后将NDEF消息写入NDEF标签,之后将标签设置为只读。使用promise方式作为异步方法。 +将标签格式化为NDEF标签,将NDEF消息写入NDEF标签,之后将标签设置为只读。使用Promise方式作为异步方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC **参数:** - | 参数名 | 类型 | 必填 | 说明 | | -------- | ----------------------- | ---- | -------------------------------------- | -| message | [NdefMessage](#ndefmessage9) | 是 | 格式化成功时要写入的Ndef消息。可以为null,为null时仅格式化标签,不写入内容。 | - -**返回值:** +| message | [NdefMessage](#ndefmessage9) | 是 | 格式化成功时要写入的NDEF消息。可以为null,为null时仅格式化标签,不写入内容。 | -| **类型** | **说明** | -| ------------------ | --------------------------| -| Promise\ | 执行操作后返回的错误代码。如果返回0,则表示成功。 | +**错误码:** +以下错误码的详细介绍请参见[NFC错误码](../errorcodes/errorcode-nfc.md)。 +| 错误码ID | 错误信息| +| ------- | -------| +| 3100201 | Tag running state is abnormal in service. | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -let ndefmessage = ndef.createNdefMessage(data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefFormatable' correctly. -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndefFormatable' correctly. -ndefFormatable.formatReadOnly(ndefmessage, (err, data)=> { - if (err) { - console.log("ndefFormatable formatReadOnly err: " + err); - } else { - console.log("ndefFormatable formatReadOnly data: " + data); +// connect the tag at first if not connected. +if (!ndefFormatable.isTagConnected()) { + if (!ndefFormatable.connectTag()) { + console.log("ndefFormatable connectTag failed."); + return; } -}); +} + +try { + // ndefMessage created from raw data, such as: + let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. + // or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) + + ndefFormatable.formatReadOnly(ndefMessage).then(() => { + console.log("ndefFormatable formatReadOnly Promise success."); + }).catch((err)=> { + console.log("ndefFormatable formatReadOnly Promise err: " + err); + }); +} catch (busiError) { + console.log("ndefFormatable formatReadOnly Promise catch busiError: " + busiError); +} ``` ### NdefFormatableTag.formatReadOnly9+ -formatReadOnly(message: [NdefMessage](#ndefmessage9), callback: AsyncCallback\): void +formatReadOnly(message: [NdefMessage](#ndefmessage9), callback: AsyncCallback\): void 将标签格式化为NDEF标签,然后将NDEF消息写入NDEF标签,之后将标签设置为只读。使用callback方式作为异步方法。 @@ -1892,33 +2424,43 @@ formatReadOnly(message: [NdefMessage](#ndefmessage9), callback: AsyncCallback\ | 回调函数。 | +| callback: AsyncCallback\ | 回调函数。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndef' correctly. -let data = [0x01, 0x02, ...]; // change it to be correct raw data. -let ndefmessage = ndef.createNdefMessage(data); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', obtains the 'ndefFormatable' correctly. -// see 'tag.TagInfo' at 'js-apis-nfcTag', has obtained the 'ndefFormatable' correctly. -ndefFormatable.formatReadOnly(ndefmessage, (err, data)=> { - if (err) { - console.log("ndefFormatable formatReadOnly err: " + err); - } else { - console.log("ndefFormatable formatReadOnly data: " + data); +// connect the tag at first if not connected. +if (!ndefFormatable.isTagConnected()) { + if (!ndefFormatable.connectTag()) { + console.log("ndefFormatable connectTag failed."); + return; } -}); +} + +try { + // ndefMessage created from raw data, such as: + let ndefMessage = ndefTag.createNdefMessage([0xD1, 0x01, 0x03, 0x54, 0x4E, 0x46, 0x43]); // change the raw data to be correct. + // or ndefMessage created from ndefTag.createNdefMessage(ndefRecords: NdefRecord[]) + + ndefFormatable.formatReadOnly(ndefMessage, (err)=> { + if (err) { + console.log("ndefFormatable formatReadOnly AsyncCallback err: " + err); + } else { + console.log("ndefFormatable formatReadOnly AsyncCallback success."); + } + }); +} catch (busiError) { + console.log("ndefFormatable formatReadOnly AsyncCallback catch busiError: " + busiError); +} ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-pointer.md b/zh-cn/application-dev/reference/apis/js-apis-pointer.md index 6a9c09f1a21e7d18e21643085d2023eabd21ef85..44cfe78aeed2ed070e4e8a09f40f9ae23de26377 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-pointer.md +++ b/zh-cn/application-dev/reference/apis/js-apis-pointer.md @@ -1,6 +1,6 @@ # 鼠标指针 -鼠标指针管理模块,用于提供鼠标指针相关属性接口。 +鼠标指针管理模块,用于查询和设置鼠标指针相关属性。 > **说明**: > @@ -12,11 +12,11 @@ import pointer from '@ohos.multimodalInput.pointer'; ``` -## pointer.setPointerVisibele9+ +## pointer.setPointerVisible9+ setPointerVisible(visible: boolean, callback: AsyncCallback<void>): void -设置鼠标指针显示或者隐藏,使用callback异步回调。 +设置鼠标指针显示或者隐藏,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -24,18 +24,22 @@ setPointerVisible(visible: boolean, callback: AsyncCallback<void>): void | 参数 | 类型 | 必填 | 说明 | | -------- | ------------------------- | ---- | ---------------------------------------- | -| visible | boolean | 是 | 鼠标指针显示或者隐藏状态,true: 鼠标指针显示; false: 鼠标指针隐藏。 | -| callback | AsyncCallback<void> | 是 | 回调函数。当设置鼠标显示或隐藏成功,err为undefined,否则为错误对象。 | +| visible | boolean | 是 | 鼠标指针是否显示。 | +| callback | AsyncCallback<void> | 是 | 回调函数。 | **示例**: ```js try { - pointer.setPointerVisible(true, (err, data) => { + pointer.setPointerVisible(true, (error) => { + if (error) { + console.log(`Set pointer visible failed, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } console.log(`Set pointer visible success`); }); -} catch (err) { - console.log(`Set pointer visible failed. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); +} catch (error) { + console.log(`Set pointer visible failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -43,7 +47,7 @@ try { setPointerVisible(visible: boolean): Promise<void> -设置鼠标指针显示或者隐藏,使用Promise方式作为异步方法。 +设置鼠标指针显示或者隐藏,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -51,23 +55,23 @@ setPointerVisible(visible: boolean): Promise<void> | 参数 | 类型 | 必填 | 说明 | | ------- | ------- | ---- | ---------------------------------------- | -| visible | boolean | 是 | 鼠标指针显示或者隐藏状态,true: 鼠标指针显示; false: 鼠标指针隐藏。 | +| visible | boolean | 是 | 鼠标指针是否显示。 | **返回值**: | 参数 | 说明 | | ------------------- | ------------------- | -| Promise<void> | Promise实例,用于异步获取结果。 | +| Promise<void> | Promise对象。 | **示例**: ```js try { - pointer.setPointerVisible(false).then(data => { - console.log(`Set mouse pointer visible success`); + pointer.setPointerVisible(false).then(() => { + console.log(`Set pointer visible success`); }); -} catch { - console.log(`Set mouse pointer visible failed err=${JSON.stringify(data)}, msg=${JSON.stringify(message)}`); +} catch (error) { + console.log(`Set pointer visible failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -75,7 +79,7 @@ try { isPointerVisible(callback: AsyncCallback<boolean>): void -获取鼠标指针显示或隐藏状态,使用callback异步回调。 +获取鼠标指针显示或隐藏状态,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -83,17 +87,21 @@ isPointerVisible(callback: AsyncCallback<boolean>): void | 参数 | 类型 | 必填 | 说明 | | -------- | ---------------------------- | ---- | -------------- | -| callback | AsyncCallback<boolean> | 是 | 回调函数,异步返回查询结果。 | +| callback | AsyncCallback<boolean> | 是 | 回调函数,异步返回鼠标指针显示或隐藏状态。 | **示例**: ```js try { - pointer.isPointerVisible(visible, (err, data) => { - console.log(`The mouse pointer visible attributes is ` + visible); + pointer.isPointerVisible((error, visible) => { + if (error) { + console.log(`Get pointer visible failed, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Get pointer visible success, visible: ${JSON.stringify(visible)}`); }); -} catch (err) { - console.log(`The mouse pointer visible attributes is failed. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); +} catch (error) { + console.log(`Get pointer visible failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -101,7 +109,7 @@ try { isPointerVisible(): Promise<boolean> -获取鼠标指针显示或隐藏状态,使用Promise方式作为异步方法。 +获取鼠标指针显示或隐藏状态,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -109,25 +117,21 @@ isPointerVisible(): Promise<boolean> | 参数 | 说明 | | ---------------------- | ------------------- | -| Promise<boolean> | Promise实例,用于异步获取结果。 | +| Promise<boolean> | Promise对象,异步返回鼠标指针显示或隐藏状态。 | **示例**: ```js -try { - pointer.isPointerVisible().then((data) => { - console.log(`The mouse pointer visible attributes is success. data=${JSON.stringify(data)}`); - }); -} catch (err) { - ponsole.info(`The mouse pointer visible attributes is failed. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); -} +pointer.isPointerVisible().then((visible) => { + console.log(`Get pointer visible success, visible: ${JSON.stringify(visible)}`); +}); ``` ## pointer.setPointerSpeed9+ setPointerSpeed(speed: number, callback: AsyncCallback<void>): void -设置鼠标移动速度,使用callback异步回调。 +设置鼠标移动速度,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -135,18 +139,22 @@ setPointerSpeed(speed: number, callback: AsyncCallback<void>): void | 参数 | 类型 | 必填 | 说明 | | -------- | ------------------------- | ---- | ------------------------------------- | -| speed | number | 是 | 鼠标移动速度设置挡位值1-11,最大值:11,最小值:1,标准值:5。 | -| callback | AysncCallback<void> | 是 | 回调函数。当设置鼠标速度成功,err为undefined,否则为错误对象。 | +| speed | number | 是 | 鼠标移动速度,范围1-11,默认为5。 | +| callback | AysncCallback<void> | 是 | 回调函数。 | **示例**: ```js try { - pointer.setPointerSpeed(5, (err, data) => { + pointer.setPointerSpeed(5, (error) => { + if (error) { + console.log(`Set pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } console.log(`Set pointer speed success`); }); } catch (err) { - console.log(`Set pointer speed failed. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + console.log(`Set pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -154,7 +162,7 @@ try { setPointerSpeed(speed: number): Promise<void> -设置鼠标移动速度,使用Promise异步回调。 +设置鼠标移动速度,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -162,23 +170,23 @@ setPointerSpeed(speed: number): Promise<void> | 参数 | 类型 | 必填 | 说明 | | ----- | ------ | ---- | ----------------------------------- | -| speed | number | 是 | 鼠标移动速度设置挡位值1-11,最大值:11,最小值:1,标准值:5。 | +| speed | number | 是 | 鼠标移动速度,范围1-11,默认为5。 | **返回值**: | 参数 | 说明 | | ------------------- | ---------------- | -| Promise<void> | 无返回结果的Promise对象。 | +| Promise<void> | Promise对象。 | **示例**: ```js try { - pointer.setPointerSpeed(5).then(data => { + pointer.setPointerSpeed(5).then(() => { console.log(`Set pointer speed success`); }); -} catch (err) { - console.log(`Set pointer speed failed err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); +} catch (error) { + console.log(`Set pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -186,7 +194,7 @@ try { getPointerSpeed(callback: AsyncCallback<number>): void -获取当前鼠标移动速度,使用callback异步回调。 +获取鼠标移动速度,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -194,17 +202,21 @@ getPointerSpeed(callback: AsyncCallback<number>): void | 参数 | 类型 | 必填 | 说明 | | -------- | --------------------------- | ---- | -------------- | -| callback | AsyncCallback<number> | 是 | 回调函数,异步返回查询结果。 | +| callback | AsyncCallback<number> | 是 | 回调函数,异步返回鼠标移动速度。 | **示例**: ```js try { - pointer.getPointerSpeed(speed, (err, data) => { - console.log(`The pointer speed is ` + speed); + pointer.getPointerSpeed(speed, (error, speed) => { + if (error) { + console.log(`Get pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Get pointer speed success, speed: ${JSON.stringify(speed)}`); }); } catch (err) { - console.log(`Failed to get the pointer speed. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + console.log(`Get pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -212,7 +224,7 @@ try { getPointerSpeed(): Promise<number> -获取当前鼠标移动速度,使用Promise异步回调。 +获取当前鼠标移动速度,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -220,17 +232,17 @@ getPointerSpeed(): Promise<number> | 参数 | 说明 | | --------------------- | ------------------- | -| Promise<number> | Promise实例,用于异步获取结果。 | +| Promise<number> | Promise实例,异步返回鼠标移动速度。 | **示例**: ```js try { - pointer.getPointerSpeed().then(data => { - console.log(`Get pointer speed success. data=${JSON.stringify(data)}`); + pointer.getPointerSpeed().then(speed => { + console.log(`Get pointer speed success, speed: ${JSON.stringify(speed)}`); }); -} catch (err) { - console.log(`Get pointer speed failed err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); +} catch (error) { + console.log(`Get pointer speed failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } ``` @@ -238,7 +250,7 @@ try { getPointerStyle(windowId: number, callback: AsyncCallback<PointerStyle>): void -获取鼠标样式类型,使用callback异步回调。 +获取鼠标样式类型,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -246,29 +258,27 @@ getPointerStyle(windowId: number, callback: AsyncCallback<PointerStyle>): | 参数 | 类型 | 必填 | 说明 | | -------- | ---------------------------------------- | ---- | -------------- | -| windowId | number | 是 | 输入设备的窗口id。 | -| callback | AsyncCallback<[PointerStyle](#pointerstyle9)> | 是 | 回调函数,异步返回查询结果。 | +| windowId | number | 是 | 窗口id。 | +| callback | AsyncCallback<[PointerStyle](#pointerstyle9)> | 是 | 回调函数,异步返回鼠标样式类型。 | **示例**: ```js -// 获取设备的鼠标样式。 import window from '@ohos.window'; -var windowClass = null; -window.getTopWindow((err, data) => { - windowClass = data; - windowClass.getProperties((err, data) => { - var windowId = data.id; + +window.getTopWindow((error, win) => { + win.getProperties((error, properties) => { + var windowId = properties.id; if (windowId < 0) { console.log(`Invalid windowId`); return; } try { - pointer.getPointerStyle(windowId, (err, ret) => { - console.log(`The mouse pointer style is: ` + ret); + pointer.getPointerStyle(windowId, (error, style) => { + console.log(`Get pointer style success, style: ${JSON.stringify(style)}`); }); - } catch (err) { - console.log(`Failed to get the pointer style. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + } catch (error) { + console.log(`Get pointer style failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } }); }); @@ -278,7 +288,7 @@ window.getTopWindow((err, data) => { getPointerStyle(windowId: number): Promise<PointerStyle> -获取鼠标样式类型,使用Promise方式作为异步方法。 +获取鼠标样式类型,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -286,28 +296,26 @@ getPointerStyle(windowId: number): Promise<PointerStyle> | 参数 | 说明 | | ---------------------------------------- | ------------------- | -| Promise<[PointerStyle](#pointerstyle9)> | Promise实例,用于异步获取结果。 | +| Promise<[PointerStyle](#pointerstyle9)> | Promise实例,异步返回鼠标样式类型。 | **示例**: ```js -// 获取设备的鼠标样式。 import window from '@ohos.window'; -var windowClass = null; -window.getTopWindow((err, data) => { - windowClass = data; - windowClass.getProperties((err, data) => { - var windowId = data.id; + +window.getTopWindow((error, win) => { + win.getProperties((error, properties) => { + var windowId = properties.id; if (windowId < 0) { console.log(`Invalid windowId`); return; } try { - pointer.getPointerStyle(windowId).then((ret) => { - console.log(`The mouse pointer style is: ` + ret); + pointer.getPointerStyle(windowId).then((style) => { + console.log(`Get pointer style success, style: ${JSON.stringify(style)}`); }); - } catch (err) { - console.log(`Get pointer style failed err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + } catch (error) { + console.log(`Get pointer style failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } }); }); @@ -317,7 +325,7 @@ window.getTopWindow((err, data) => { setPointerStyle(windowId: number, pointerStyle: PointerStyle, callback: AsyncCallback<void>): void -设置鼠标的样式类型,使用callback异步回调。 +设置鼠标样式类型,使用AsyncCallback异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -325,30 +333,28 @@ setPointerStyle(windowId: number, pointerStyle: PointerStyle, callback: AsyncCal | 参数 | 类型 | 必填 | 说明 | | ------------ | ------------------------------ | ---- | ----------------------------------- | -| windowId | number | 是 | 输入设备的窗口id。 | +| windowId | number | 是 | 窗口id。 | | pointerStyle | [PointerStyle](#pointerstyle9) | 是 | 鼠标样式id。 | -| callback | AysncCallback<void> | 是 | 回调函数。当设置样式成功,err为undefined,否则为错误对象。 | +| callback | AysncCallback<void> | 是 | 回调函数。 | **示例**: ```js -// 设置设备的鼠标样式。 import window from '@ohos.window'; -var windowClass = null; -window.getTopWindow((err, data) => { - windowClass = data; - windowClass.getProperties((err, data) => { - var windowId = data.id; + +window.getTopWindow((error, win) => { + win.getProperties((error, properties) => { + var windowId = properties.id; if (windowId < 0) { console.log(`Invalid windowId`); return; } try { - pointer.setPointerStyle(windowId, pointer.PointerStyle.CROSS, (err) => { - console.log(`Successfully set mouse pointer style`); + pointer.setPointerStyle(windowId, pointer.PointerStyle.CROSS, error => { + console.log(`Set pointer style success`); }); - } catch (err) { - console.log(`Failed to set the pointer style. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + } catch (error) { + console.log(`Set pointer style failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } }); }); @@ -357,7 +363,7 @@ window.getTopWindow((err, data) => { setPointerStyle(windowId: number, pointerStyle: PointerStyle): Promise<void> -设置鼠标的样式类型,使用Promise方式作为异步方法。 +设置鼠标样式类型,使用Promise异步方式返回结果。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -365,37 +371,35 @@ setPointerStyle(windowId: number, pointerStyle: PointerStyle): Promise<void&g | 参数 | 类型 | 必填 | 说明 | | ------------------- | ------------------------------ | ---- | ---------------- | -| windowId | number | 是 | 输入设备的窗口id。 | +| windowId | number | 是 | 窗口id。 | | pointerStyle | [PointerStyle](#pointerstyle9) | 是 | 鼠标样式id。 | -| Promise<void> | void | 是 | 无返回结果的Promise对象。 | +| Promise<void> | void | 是 | Promise对象。 | **示例**: ```js -// 设置设备的鼠标样式。 import window from '@ohos.window'; -var windowClass = null; -window.getTopWindow((err, data) => { - windowClass = data; - windowClass.getProperties((err, data) => { - var windowId = data.id; + +window.getTopWindow((error, win) => { + win.getProperties((error, properties) => { + var windowId = properties.id; if (windowId < 0) { console.log(`Invalid windowId`); return; } try { pointer.setPointerStyle(windowId, pointer.PointerStyle.CROSS).then(() => { - console.log(`Successfully set mouse pointer style`); + console.log(`Set pointer style success`); }); - } catch (err) { - console.log(`Failed to set the pointer style. err=${JSON.stringify(err)}, msg=${JSON.stringify(message)}`); + } catch (error) { + console.log(`Set pointer style failed, error: ${JSON.stringify(error, [`code`, `message`])}`); } }); }); ``` ## PointerStyle9+ -定义鼠标样式类型。 +鼠标样式类型。 **系统能力**:SystemCapability.MultimodalInput.Input.Pointer @@ -439,6 +443,4 @@ window.getTopWindow((err, data) => { | MIDDLE_BTN_NORTH_WEST | 35 | 向西北滚动 | | MIDDLE_BTN_SOUTH_EAST | 36 | 向东南滚动 | | MIDDLE_BTN_SOUTH_WEST | 37 | 向西南滚动 | -| MIDDLE_BTN_NORTH_SOUTH_WEST_EAST | 38 | 四向锥形移动 | - - +| MIDDLE_BTN_NORTH_SOUTH_WEST_EAST | 38 | 四向锥形移动 | \ No newline at end of file diff --git a/zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md b/zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md index f931e52919a385cacbdd346d27b647868d1b8844..ed34599c56076fe9e3477ccb66c528da3191219e 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md +++ b/zh-cn/application-dev/reference/apis/js-apis-processrunninginfo.md @@ -1,19 +1,21 @@ # ProcessRunningInfo(deprecated) -ProcessRunningInfo模块提供对进程运行信息进行设置和查询的能力。 +本模块提供对进程运行信息进行设置和查询的能力。 > **说明:** -> - 本模块接口从API Version 9 开始废弃,建议使用[ProcessRunningInformation9+](js-apis-processrunninginformation.md)替代。 +> - 本模块接口从API version 9 开始废弃,建议使用[ProcessRunningInformation9+](js-apis-processrunninginformation.md)替代。 > - 本模块首批接口从API version 8 开始支持。 ## 使用说明 -通过appManager来获取。 +通过appManager中[getProcessRunningInfos](js-apis-appmanager.md#appmanagergetprocessrunninginfosdeprecated)方法来获取。 ```js import appManager from '@ohos.application.appManager'; -appManager.getProcessRunningInfos((error,data) => { - console.log("getProcessRunningInfos error: " + error.code + " data: " + JSON.stringify(data)); +app.getProcessRunningInfos().then((data) => { + console.log('success:' + JSON.stringify(data)); +}).catch((error) => { + console.log('failed:' + JSON.stringify(error)); }); ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-router.md b/zh-cn/application-dev/reference/apis/js-apis-router.md index 510bac63015e8793b7b34199403cea444db4f6fe..f13771a442e172f3e02488017033fb8876859590 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-router.md +++ b/zh-cn/application-dev/reference/apis/js-apis-router.md @@ -604,7 +604,7 @@ router.getParams(); | 名称 | 描述 | | -------- | ---------------------------------------- | -| Standard | 标准模式。 | +| Standard | 标准模式。
目标页面会被添加到页面路由栈顶,无论栈中是否存在相同url的页面。 | | Single | 单实例模式。
如果目标页面的url在页面栈中已经存在同url页面,离栈顶最近的页面会被移动到栈顶,移动后的页面为新建页。
如目标页面的url在页面栈中不存在同url页面,按标准模式跳转。 | ## 完整示例 diff --git a/zh-cn/application-dev/reference/apis/js-apis-rpc.md b/zh-cn/application-dev/reference/apis/js-apis-rpc.md index 4ca8bd896c8e0bb40346a6b62d7fa98caf2128de..61a2f32b4c1f8a3f71447572ae5307137d13ab3b 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-rpc.md +++ b/zh-cn/application-dev/reference/apis/js-apis-rpc.md @@ -3307,7 +3307,7 @@ readInterfaceToken(): string ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let interfaceToken = data.readInterfaceToken(); console.log("RpcServer: interfaceToken is " + interfaceToken); return true; @@ -3438,7 +3438,7 @@ getWritableBytes(): number ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let getWritableBytes = data.getWritableBytes(); console.log("RpcServer: getWritableBytes is " + getWritableBytes); return true; @@ -7130,7 +7130,7 @@ static getCallingPid(): number ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callerPid = rpc.IPCSkeleton.getCallingPid(); console.log("RpcServer: getCallingPid result: " + callerPid); return true; @@ -7157,7 +7157,7 @@ static getCallingUid(): number ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callerUid = rpc.IPCSkeleton.getCallingUid(); console.log("RpcServer: getCallingUid result: " + callerUid); return true; @@ -7185,7 +7185,7 @@ static getCallingTokenId(): number; ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callerTokenId = rpc.IPCSkeleton.getCallingTokenId(); console.log("RpcServer: getCallingTokenId result: " + callerTokenId); return true; @@ -7212,7 +7212,7 @@ static getCallingDeviceID(): string ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callerDeviceID = rpc.IPCSkeleton.getCallingDeviceID(); console.log("RpcServer: callerDeviceID is: " + callerDeviceID); return true; @@ -7239,7 +7239,7 @@ static getLocalDeviceID(): string ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let localDeviceID = rpc.IPCSkeleton.getLocalDeviceID(); console.log("RpcServer: localDeviceID is: " + localDeviceID); return true; @@ -7266,7 +7266,7 @@ static isLocalCalling(): boolean ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let isLocalCalling = rpc.IPCSkeleton.isLocalCalling(); console.log("RpcServer: isLocalCalling is: " + isLocalCalling); return true; @@ -7385,7 +7385,7 @@ static resetCallingIdentity(): string ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callingIdentity = rpc.IPCSkeleton.resetCallingIdentity(); console.log("RpcServer: callingIdentity is: " + callingIdentity); return true; @@ -7412,7 +7412,7 @@ static restoreCallingIdentity(identity : string): void ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callingIdentity = null; try { callingIdentity = rpc.IPCSkeleton.resetCallingIdentity(); @@ -7452,7 +7452,7 @@ static setCallingIdentity(identity : string): boolean ``` class Stub extends rpc.RemoteObject { - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { let callingIdentity = null; try { callingIdentity = rpc.IPCSkeleton.resetCallingIdentity(); @@ -7818,7 +7818,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ### onRemoteRequest8+(deprecated) ->从API version 9 开始不再维护,建议使用[onRemoteRequestEx](#onremoterequestex9)类替代。 +>从API version 9 开始不再维护,建议使用[onRemoteMessageRequest](#onremotemessagerequest9)类替代。 onRemoteRequest(code : number, data : MessageParcel, reply: MessageParcel, options : MessageOption): boolean @@ -7874,14 +7874,14 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里处理 } ``` -### onRemoteRequestEx9+ +### onRemoteMessageRequest9+ -onRemoteRequestEx(code : number, data : MessageSequence, reply: MessageSequence, options : MessageOption): boolean | Promise\ +onRemoteMessageRequest(code : number, data : MessageSequence, reply: MessageSequence, options : MessageOption): boolean | Promise\ > **说明:** > ->* 开发者应优先选择重载onRemoteRequestEx方法,其中可以自由实现同步和异步的消息处理。 ->* 开发者同时重载onRemoteRequest和onRemoteRequestEx方法时,仅onRemoteRequestEx方法生效。 +>* 开发者应优先选择重载onRemoteMessageRequest方法,其中可以自由实现同步和异步的消息处理。 +>* 开发者同时重载onRemoteRequest和onRemoteMessageRequest方法时,仅onRemoteMessageRequest方法生效。 sendMessageRequest请求的响应处理函数,服务端在该函数里同步或异步地处理请求,回复结果。 @@ -7900,10 +7900,10 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 | 类型 | 说明 | | ----------------- | ---------------------------------------------------------------------------------------------- | - | boolean | 若在onRemoteRequestEx中同步地处理请求,则返回一个布尔值:操作成功,则返回true;否则返回false。 | - | Promise\ | 若在onRemoteRequestEx中异步地处理请求,则返回一个Promise对象。 | + | boolean | 若在onRemoteMessageRequest中同步地处理请求,则返回一个布尔值:操作成功,则返回true;否则返回false。 | + | Promise\ | 若在onRemoteMessageRequest中异步地处理请求,则返回一个Promise对象。 | -**重载onRemoteRequestEx方法同步处理请求示例:** +**重载onRemoteMessageRequest方法同步处理请求示例:** ```ets class MyDeathRecipient { @@ -7920,9 +7920,9 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 isObjectDead(): boolean { return false; } - onRemoteRequestEx(code, data, reply, option) { + onRemoteMessageRequest(code, data, reply, option) { if (code === 1) { - console.log("RpcServer: sync onRemoteRequestEx is called"); + console.log("RpcServer: sync onRemoteMessageRequest is called"); return true; } else { console.log("RpcServer: unknown code: " + code); @@ -7932,7 +7932,7 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 } ``` - **重载onRemoteRequestEx方法异步处理请求示例:** + **重载onRemoteMessageRequest方法异步处理请求示例:** ```ets class MyDeathRecipient { @@ -7949,9 +7949,9 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 isObjectDead(): boolean { return false; } - async onRemoteRequestEx(code, data, reply, option) { + async onRemoteMessageRequest(code, data, reply, option) { if (code === 1) { - console.log("RpcServer: async onRemoteRequestEx is called"); + console.log("RpcServer: async onRemoteMessageRequest is called"); } else { console.log("RpcServer: unknown code: " + code); return false; @@ -7964,7 +7964,7 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 } ``` -**同时重载onRemoteRequestEx和onRemoteRequest方法同步处理请求示例:** +**同时重载onRemoteMessageRequest和onRemoteRequest方法同步处理请求示例:** ```ets class MyDeathRecipient { @@ -7983,17 +7983,17 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 } onRemoteRequest(code, data, reply, option) { if (code === 1) { - console.log("RpcServer: sync onRemoteRequestEx is called"); + console.log("RpcServer: sync onRemoteMessageRequest is called"); return true; } else { console.log("RpcServer: unknown code: " + code); return false; } } - // 同时调用仅会执行onRemoteRequestEx - onRemoteRequestEx(code, data, reply, option) { + // 同时调用仅会执行onRemoteMessageRequest + onRemoteMessageRequest(code, data, reply, option) { if (code === 1) { - console.log("RpcServer: async onRemoteRequestEx is called"); + console.log("RpcServer: async onRemoteMessageRequest is called"); } else { console.log("RpcServer: unknown code: " + code); return false; @@ -8004,7 +8004,7 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 } ``` - **同时重载onRemoteRequestEx和onRemoteRequest方法异步处理请求示例:** + **同时重载onRemoteMessageRequest和onRemoteRequest方法异步处理请求示例:** ```ets class MyDeathRecipient { @@ -8030,10 +8030,10 @@ sendMessageRequest请求的响应处理函数,服务端在该函数里同步 return false; } } - // 同时调用仅会执行onRemoteRequestEx - async onRemoteRequestEx(code, data, reply, option) { + // 同时调用仅会执行onRemoteMessageRequest + async onRemoteMessageRequest(code, data, reply, option) { if (code === 1) { - console.log("RpcServer: async onRemoteRequestEx is called"); + console.log("RpcServer: async onRemoteMessageRequest is called"); } else { console.log("RpcServer: unknown code: " + code); return false; diff --git a/zh-cn/application-dev/reference/apis/js-apis-tagSession.md b/zh-cn/application-dev/reference/apis/js-apis-tagSession.md old mode 100755 new mode 100644 index 0e8c280b1ba2e0eda322df2e2fcb95bba4a6d105..7196bcf24b46dc61da69642ef1178a1cfb897c13 --- a/zh-cn/application-dev/reference/apis/js-apis-tagSession.md +++ b/zh-cn/application-dev/reference/apis/js-apis-tagSession.md @@ -13,64 +13,82 @@ import tag from '@ohos.nfc.tag'; ## tagSession -tagSession是所有[Nfc tag 技术类型](js-apis-nfctech.md)的基类, 提供建立连接和发送数据等共同接口。 +tagSession是所有[NFC Tag技术类型](js-apis-nfctech.md)的基类, 提供建立连接和发送数据等共同接口。 -需要通过其子类来访问以下接口。在下面的示例中 统一用 getXXTag表示获取子类实例的方法。 +需要通过其子类来访问以下接口。在下面的示例中 统一用 getXXX()表示获取子类实例的方法。 具体使用时,请根据实际采用的Nfc tag技术,选择对应的方法,具体请参见[nfcTag](js-apis-nfcTag.md)文档。 -### tagSession.connectTag - -connectTag(): boolean; +### tagSession.getTagInfo -和标签建立连接; +getTagInfo(): tag.TagInfo -在从标签读取数据或将数据写入标签之前,必须调用此方法。 +获取该Tag被分发时,NFC服务所提供的Tag数据对象。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC.Core **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| boolean | 连接建立成功返回 true,失败返回false。 | +| TagInfo | NFC服务所提供的Tag数据对象。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// tagInfo is an Object given by nfc service when tag is dispatched. -let isNfcConnected = tag.getXXXTag(taginfo).connectTag(); -console.log("isNfcConnected:" +isNfcConnected); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +let tagInfo = tag.getXXX(tagInfo).getTagInfo(); +console.log("tag tagInfo: " + tagInfo); ``` -### tagSession.reset() +### tagSession.connectTag -reset(): void +connectTag(): boolean; -重置与标签的连接,并恢复将数据写入标签的默认超时时间。 +和标签建立连接。在从标签读取数据或将数据写入标签之前,必须调用此方法。 **需要权限**:ohos.permission.NFC_TAG **系统能力**:SystemCapability.Communication.NFC.Core **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| -| boolean | 方法执行成功返回 true,失败返回false。 | +| boolean | 连接建立成功返回true,失败返回false。 | **示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +let connectStatus = tag.getXXX(tagInfo).connectTag(); +console.log("connectStatus: " + connectStatus); +``` + +### tagSession.reset() + +reset(): void + +重置与标签的连接。 + +**需要权限**:ohos.permission.NFC_TAG + +**系统能力**:SystemCapability.Communication.NFC.Core +**示例:** ```js import tag from '@ohos.nfc.tag'; -// tagInfo is an Object given by nfc service when tag is dispatched. -let reset = tag.getXXXTag(taginfo).reset(); -console.log("reset:" +reset); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +tag.getXXX(tagInfo).reset(); ``` ### tagSession.isTagConnected @@ -84,19 +102,19 @@ isTagConnected(): boolean **系统能力**:SystemCapability.Communication.NFC.Core **返回值:** - | **类型** | **说明** | | ------------------ | --------------------------| | boolean | 已建立连接返回 true,未建立连接返回false。 | **示例:** - ```js import tag from '@ohos.nfc.tag'; -// tagInfo is an Object given by nfc service when tag is dispatched. -let isTagConnected = tag.getXXXTag(taginfo).isTagConnected(); -console.log("isTagConnected:" +isTagConnected); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +let isTagConnected = tag.getXXX(tagInfo).isTagConnected(); +console.log("isTagConnected: " + isTagConnected); ``` ### tagSession.getMaxSendLength @@ -110,17 +128,160 @@ getMaxSendLength(): number **系统能力**:SystemCapability.Communication.NFC.Core **返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| number | 可以发送到标签的最大数据长度,非负数。 | + +**示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... +let maxSendLen = tag.getXXX(tagInfo).getMaxSendLength(); +console.log("tag maxSendLen: " + maxSendLen); +``` + +### tagSession.getSendDataTimeout + +getSendDataTimeout(): number + +查询发送数据到Tag的等待超时时间,单位是毫秒。 + +**需要权限**:ohos.permission.NFC_TAG + +**系统能力**:SystemCapability.Communication.NFC.Core + +**返回值:** | **类型** | **说明** | | ------------------ | --------------------------| -| number | 可以发送到标签的最大数据长度。 | +| number | 发送数据到Tag的等待超时时间,单位是毫秒,非负数。 | **示例:** +```js +import tag from '@ohos.nfc.tag'; +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +let sendDataTimeout = tag.getXXX(tagInfo).getSendDataTimeout(); +console.log("tag sendDataTimeout: " + sendDataTimeout); +``` + +### tagSession.setSendDataTimeout + +setSendDataTimeout(timeout: number): boolean + +查询发送数据到Tag的等待超时时间,单位是毫秒。 + +**需要权限**:ohos.permission.NFC_TAG + +**系统能力**:SystemCapability.Communication.NFC.Core + +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| timeout | number | 是 | 超时时间,单位毫秒,非负值。 | + +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| boolean | 设置超时时间成功返回true,设置失败返回false。 | + +**示例:** + +```js +import tag from '@ohos.nfc.tag'; + +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +let timeoutMs = 700; // change it to be correct. +let setStatus = tag.getXXX(tagInfo).setSendDataTimeout(timeoutMs); +console.log("tag setSendDataTimeout setStatus: " + setStatus); +``` + +### tagSession.sendData + +sendData(data: number[]): Promise + +发送指令到Tag上,使用Promise方式作为异步方法。 + +**需要权限**:ohos.permission.NFC_TAG + +**系统能力**:SystemCapability.Communication.NFC + +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| data | number[] | 是 | 要发送的指令。每个number十六进制表示,范围是0x00~0xFF。 | + +**返回值:** +| **类型** | **说明** | +| ------------------ | --------------------------| +| Promise | 对端Tag对指令的响应数据。每个number十六进制表示,范围是0x00~0xFF。| + +**示例:** +```js +import tag from '@ohos.nfc.tag'; + +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +// connect the tag at first if not connected. +if (!tag.getXXX(tagInfo).isTagConnected()) { + if (!tag.getXXX(tagInfo).connectTag()) { + console.log("tagSession connectTag failed."); + return; + } +} + +let cmdData = [0x01, 0x02, ...]; // change the raw data to be correct. +tag.getXXX(tagInfo).sendData(cmdData).then((response) => { + console.log("tagSession sendData Promise response: " + response); +}).catch((err)=> { + console.log("tagSession sendData Promise err: " + err); +}); +``` + +### tagSession.sendData + +sendData(data: number[], callback: AsyncCallback): void + +发送指令到Tag上,使用AsyncCallback方式作为异步方法。 + +**需要权限**:ohos.permission.NFC_TAG + +**系统能力**:SystemCapability.Communication.NFC + +**参数:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | -------------------------------------- | +| data | number[] | 是 | 要发送的指令。每个number十六进制表示,范围是0x00~0xFF。 | +| callback | AsyncCallback | 是 | 回调函数,返回响应数据。每个number十六进制表示,范围是0x00~0xFF。 | + +**示例:** ```js import tag from '@ohos.nfc.tag'; -// tagInfo is an Object given by nfc service when tag is dispatched. -let mazSendLen = tag.getXXXTag(taginfo).getMaxSendLength(); -console.log("mazSendLen:" +mazSendLen); +// see 'tag.TagInfo' at 'js-apis-nfcTag.md', tagInfo is an Object given by nfc service when tag is dispatched. +// the folowing getXXX, can be one of getIsoDep, getNdef, getMifareClassic, ... + +// connect the tag at first if not connected. +if (!tag.getXXX(tagInfo).isTagConnected()) { + if (!tag.getXXX(tagInfo).connectTag()) { + console.log("tagSession connectTag failed."); + return; + } +} + +let cmdData = [0x01, 0x02, ...]; // change the raw data to be correct. +tag.getXXX(tagInfo).sendData(cmdData, (err, response)=> { + if (err) { + console.log("tagSession sendData AsyncCallback err: " + err); + } else { + console.log("tagSession sendData AsyncCallback response: " + response); + } +}); ``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-webview.md b/zh-cn/application-dev/reference/apis/js-apis-webview.md index eddd6ee8674b491267c08b292dadcbbd1044cd9e..ddd17eeb6f5f8e044d0a7082df0fe8336c386a94 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-webview.md +++ b/zh-cn/application-dev/reference/apis/js-apis-webview.md @@ -28,8 +28,7 @@ close(): void 关闭该消息端口。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -61,8 +60,7 @@ postMessageEvent(message: string): void 发送消息。完整示例代码参考[postMessage](#postmessage) -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -114,8 +112,7 @@ onMessageEvent(callback: (result: string) => void): void 注册回调函数,接收HTML5侧发送过来的消息。完整示例代码参考[postMessage](#postmessage) -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -178,8 +175,7 @@ loadUrl(url: string | Resource, headers?: Array\): void 加载指定的URL。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -231,8 +227,7 @@ loadData(data: string, mimeType: string, encoding: string, baseUrl?: string, his 加载指定的数据。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -289,8 +284,7 @@ accessForward(): boolean 当前页面是否可前进,即当前页面是否有前进历史记录。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -340,8 +334,7 @@ forward(): void 按照历史栈,前进一个页面。一般结合accessForward一起使用。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -384,8 +377,7 @@ accessBackward(): boolean 当前页面是否可后退,即当前页面是否有返回历史记录。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -435,8 +427,7 @@ backward(): void 按照历史栈,后退一个页面。一般结合accessBackward一起使用。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -479,8 +470,7 @@ onActive(): void 调用此接口通知Web组件进入前台激活状态。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -523,8 +513,7 @@ onInactive(): void 调用此接口通知Web组件进入未激活状态。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -566,8 +555,7 @@ refresh(): void 调用此接口通知Web组件刷新网页。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -610,8 +598,7 @@ accessStep(step: number): boolean 当前页面是否可前进或者后退给定的step步。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -668,8 +655,7 @@ clearHistory(): void 删除所有前进后退记录。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -712,8 +698,7 @@ getHitTest(): HitTestTypeV9 获取当前被点击区域的元素类型。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -763,8 +748,7 @@ registerJavaScriptProxy(object: object, name: string, methodList: Array\ 注入JavaScript对象到window对象中,并在window对象中调用该对象的方法。注册后,须调用[refresh](#refresh)接口生效。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -824,8 +808,7 @@ runJavaScript(script: string, callback : AsyncCallback\): void 异步执行JavaScript脚本,并通过回调方式返回脚本执行的结果。runJavaScript需要在loadUrl完成后,比如onPageEnd中调用。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -888,8 +871,7 @@ runJavaScript(script: string): Promise\ 异步执行JavaScript脚本,并通过Promise方式返回脚本执行的结果。runJavaScript需要在loadUrl完成后,比如onPageEnd中调用。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -953,8 +935,7 @@ deleteJavaScriptRegister(name: string): void 删除通过registerJavaScriptProxy注册到window上的指定name的应用侧JavaScript对象。删除后立即生效,无须调用[refresh](#refresh)接口。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1005,8 +986,7 @@ zoom(factor: number): void 调整当前网页的缩放比例。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1022,7 +1002,6 @@ SystemCapability.Web.Webview.Core | -------- | ------------------------------------------------------------ | | 17100001 | Init error. The WebviewController must be associated with a Web compoent. | | 17100004 | Cannot delete JavaScriptProxy. | -| 17100009 | Cannot zoom in or zoom out. | **示例:** @@ -1058,8 +1037,7 @@ searchAllAsync(searchString: string): void 异步查找网页中所有匹配关键字'searchString'的内容并高亮,结果通过[onSearchResultReceive](../arkui-ts/ts-basic-components-web.md#onsearchresultreceive9)异步返回。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1113,8 +1091,7 @@ clearMatches(): void 清除所有通过[searchAllAsync](#searchallasync)匹配到的高亮字符查找结果。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -1157,8 +1134,7 @@ searchNext(forward: boolean): void 滚动到下一个匹配的查找结果并高亮。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1207,8 +1183,7 @@ clearSslCache(): void 清除Web组件记录的SSL证书错误事件对应的用户操作行为。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -1251,8 +1226,7 @@ clearClientAuthenticationCache(): void 清除Web组件记录的客户端证书请求事件对应的用户操作行为。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码:** @@ -1295,8 +1269,7 @@ struct WebComponent { 创建Web消息端口。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1347,8 +1320,7 @@ postMessage(name: string, ports: Array\, uri: string): void 发送Web消息端口到HTML5。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1472,8 +1444,7 @@ requestFocus(): void 使当前web页面获取焦点。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -1516,8 +1487,7 @@ zoomIn(): void 调用此接口将当前网页进行放大,比例为20%。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -1527,7 +1497,6 @@ SystemCapability.Web.Webview.Core | -------- | ------------------------------------------------------------ | | 17100001 | Init error. The WebviewController must be associated with a Web component. | | 17100004 | Function not enable. | -| 17100009 | Cannot zoom in or zoom out. | **示例:** @@ -1562,8 +1531,7 @@ zoomOut(): void 调用此接口将当前网页进行缩小,比例为20%。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -1573,7 +1541,6 @@ SystemCapability.Web.Webview.Core | -------- | ------------------------------------------------------------ | | 17100001 | Init error. The WebviewController must be associated with a Web component. | | 17100004 | Function not enable. | -| 17100009 | Cannot zoom in or zoom out. | **示例:** @@ -1608,8 +1575,7 @@ getHitTestValue(): HitTestValue 获取当前被点击区域的元素信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1660,8 +1626,7 @@ getWebId(): number 获取当前Web组件的索引值,用于多个Web组件的管理。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1711,8 +1676,7 @@ getUserAgent(): string 获取当前默认用户代理。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1762,8 +1726,7 @@ getTitle(): string 获取文件选择器标题。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1813,8 +1776,7 @@ getPageHeight(): number 获取当前网页的页面高度。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -1864,8 +1826,7 @@ storeWebArchive(baseName: string, autoName: boolean, callback: AsyncCallback\ 以Promise方式异步保存当前页面。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -1991,8 +1951,7 @@ getUrl(): string 获取当前页面的url地址。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2042,8 +2001,7 @@ stop(): void 停止页面加载。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **错误码**: @@ -2086,8 +2044,7 @@ backOrForward(step: number): void 按照历史栈,前进或者后退指定步长的页面,当历史栈中不存在对应步长的页面时,不会进行页面跳转。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2102,7 +2059,6 @@ SystemCapability.Web.Webview.Core | 错误码ID | 错误信息 | | -------- | ------------------------------------------------------------ | | 17100001 | Init error. The WebviewController must be associated with a Web component. | -| 17100007 | Invalid back or forward operation. | **示例:** @@ -2142,8 +2098,7 @@ static getCookie(url: string): string 获取指定url对应cookie的值。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2198,8 +2153,7 @@ static setCookie(url: string, value: string): void 为指定url设置单个cookie的值。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2250,8 +2204,7 @@ static saveCookieAsync(callback: AsyncCallback\): void 将当前存在内存中的cookie异步保存到磁盘中。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2297,8 +2250,7 @@ static saveCookieAsync(): Promise\ 将当前存在内存中的cookie以Promise方法异步保存到磁盘中。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2345,8 +2297,7 @@ static putAcceptCookieEnabled(accept: boolean): void 设置WebCookieManager实例是否拥有发送和接收cookie的权限。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2387,8 +2338,7 @@ static isCookieAllowed(): boolean 获取WebCookieManager实例是否拥有发送和接收cookie的权限。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2426,8 +2376,7 @@ static putAcceptThirdPartyCookieEnabled(accept: boolean): void 设置WebCookieManager实例是否拥有发送和接收第三方cookie的权限。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2468,8 +2417,7 @@ static isThirdPartyCookieAllowed(): boolean 获取WebCookieManager实例是否拥有发送和接收第三方cookie的权限。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2507,8 +2455,7 @@ static existCookie(): boolean 获取是否存在cookie。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2546,8 +2493,7 @@ static deleteEntireCookie(): void 清除所有cookie。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -2578,8 +2524,7 @@ static deleteSessionCookie(): void 清除所有会话cookie。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -2614,8 +2559,7 @@ static deleteOrigin(origin : string): void 清除指定源所使用的存储。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2667,8 +2611,7 @@ static getOrigins(callback: AsyncCallback\>) : void 以回调方式异步获取当前使用Web SQL数据库的所有源的信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2729,8 +2672,7 @@ static getOrigins() : Promise\> 以Promise方式异步获取当前使用Web SQL数据库的所有源的信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -2791,8 +2733,7 @@ static getOriginQuota(origin : string, callback : AsyncCallback\) : void 使用callback回调异步获取指定源的Web SQL数据库的存储配额,配额以字节为单位。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2851,8 +2792,7 @@ static getOriginQuota(origin : string) : Promise\ 以Promise方式异步获取指定源的Web SQL数据库的存储配额,配额以字节为单位。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2916,8 +2856,7 @@ static getOriginUsage(origin : string, callback : AsyncCallback\) : void 以回调方式异步获取指定源的Web SQL数据库的存储量,存储量以字节为单位。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -2976,8 +2915,7 @@ static getOriginUsage(origin : string) : Promise\ 以Promise方式异步获取指定源的Web SQL数据库的存储量,存储量以字节为单位。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3041,8 +2979,7 @@ static deleteAllData(): void 清除Web SQL数据库当前使用的所有存储。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -3082,8 +3019,7 @@ static getHttpAuthCredentials(host: string, realm: string): Array\ 检索给定主机和域的HTTP身份验证凭据,该方法为同步方法。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3138,8 +3074,7 @@ static saveHttpAuthCredentials(host: string, realm: string, username: string, pa 保存给定主机和域的HTTP身份验证凭据,该方法为同步方法。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3185,8 +3120,7 @@ static existHttpAuthCredentials(): boolean 判断是否存在任何已保存的HTTP身份验证凭据,该方法为同步方法。存在返回true,不存在返回false。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -3227,8 +3161,7 @@ static deleteHttpAuthCredentials(): void 清除所有已保存的HTTP身份验证凭据,该方法为同步方法。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -3267,8 +3200,7 @@ static allowGeolocation(origin: string): void 允许指定来源使用地理位置接口。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3317,8 +3249,7 @@ static deleteGeolocation(origin: string): void 清除指定来源的地理位置权限状态。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3368,8 +3299,7 @@ static getAccessibleGeolocation(origin: string, callback: AsyncCallback\ 以Promise方式异步获取指定源的地理位置权限状态。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3488,8 +3417,7 @@ static getStoredGeolocation(callback: AsyncCallback\>): void 以回调方式异步获取已存储地理位置权限状态的所有源信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **参数:** @@ -3537,8 +3465,7 @@ static getStoredGeolocation(): Promise\> 以Promise方式异步获取已存储地理位置权限状态的所有源信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **返回值:** @@ -3585,8 +3512,7 @@ static deleteAllGeolocation(): void 清除所有来源的地理位置权限状态。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core **示例:** @@ -3615,9 +3541,10 @@ struct WebComponent { } ``` ## HeaderV9 - Web组件返回的请求/响应头对象。 +**系统能力:** SystemCapability.Web.Webview.Core + | 名称 | 类型 | 说明 | | ----------- | ------ | :------------------- | | headerKey | string | 请求/响应头的key。 | @@ -3625,6 +3552,8 @@ Web组件返回的请求/响应头对象。 ## HitTestTypeV9 +**系统能力:** SystemCapability.Web.Webview.Core + | 名称 | 描述 | | ------------- | ----------------------------------------- | | EditText | 可编辑的区域。 | @@ -3640,6 +3569,8 @@ Web组件返回的请求/响应头对象。 提供点击区域的元素信息。示例代码参考getHitTestValue。 +**系统能力:** SystemCapability.Web.Webview.Core + | 名称 | 类型 | 说明 | | ----- | ------------- | :----------------------------------------------------------- | | type | [HitTestTypeV9](#hittesttypev9) | 当前被点击区域的元素类型。 | @@ -3649,8 +3580,7 @@ Web组件返回的请求/响应头对象。 提供Web SQL数据库的使用信息。 -**系统能力:** -SystemCapability.Web.Webview.Core +**系统能力:** SystemCapability.Web.Webview.Core | 名称 | 类型 | 必填 | 说明 | | ------ | ------ | :--- | -------------------- | diff --git a/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_0000001177265268.png b/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_0000001177265268.png deleted file mode 100644 index 2ed837e111c3ac1ba1eafb5b28da581ef4de5d22..0000000000000000000000000000000000000000 Binary files a/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_0000001177265268.png and /dev/null differ diff --git a/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_000000117726526811.png b/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_000000117726526811.png new file mode 100644 index 0000000000000000000000000000000000000000..d9d9a17fe607c8acc99d3a7e26c6b4316e0b7f5b Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-js/figures/zh-cn_image_000000117726526811.png differ diff --git a/zh-cn/application-dev/reference/arkui-js/js-components-container-badge.md b/zh-cn/application-dev/reference/arkui-js/js-components-container-badge.md index 4548a4b060b3d45f19b93524e7e6509e495b7bc1..6540036839c1a5e73a0b38dbd9bb42ae6c62dbb6 100644 --- a/zh-cn/application-dev/reference/arkui-js/js-components-container-badge.md +++ b/zh-cn/application-dev/reference/arkui-js/js-components-container-badge.md @@ -23,14 +23,14 @@ 除支持[通用属性](js-components-common-attributes.md)外,还支持如下属性: -| 名称 | 类型 | 默认值 | 必填 | 描述 | -| ------------------ | ----------- | -------- | ---- | ---------------------------------------- | -| placement | string | rightTop | 否 | 事件提醒的数字标记或者圆点标记的位置,可选值为:
- right:位于组件右边框。
- rightTop:位于组件边框右上角。
- left:位于组件左边框。 | -| count | number | 0 | 否 | 设置提醒的消息数,默认为0。当设置相应的提醒消息数大于0时,消息提醒会变成数字标记类型,未设置消息数或者消息数不大于0时,消息提醒将采用圆点标记。
当数字设置大于maxcount时,将使用maxcount显示。count属性最大支持整数值为2147483647。 | -| visible | boolean | false | 否 | 是否显示消息提醒,当收到新信息提醒时可以设置该属性为true,显示相应的消息提醒,如果需要使用数字标记类型,同时需要设置相应的count属性。 | -| maxcount | number | 99 | 否 | 最大消息数限制,当收到新信息提醒大于该限制时,标识数字会进行省略,仅显示maxcount+。
maxcount属性支持的最大整数值为2147483647。 | -| config | BadgeConfig | - | 否 | 设置新事件标记相关配置属性。 | -| label6+ | string | - | 否 | 设置新事件提醒的文本值。
使用该属性时,count和maxcount属性不生效。 | +| 名称 | 类型 | 默认值 | 必填 | 描述 | +| ------------------ | ----------- | -------- | ---- | ------------------------------------------------------------ | +| placement | string | rightTop | 否 | 事件提醒的数字标记或者圆点标记的位置,可选值为:
- right:位于组件右边框。
- rightTop:位于组件边框右上角。
- left:位于组件左边框。 | +| count | number | 0 | 否 | 设置提醒的消息数,默认为0,为0时不显示。当设置相应的提醒消息数大于0时,消息提醒会变成数字标记类型。
当数字设置大于maxcount时,将使用maxcount显示。count属性最大支持整数值为2147483647。 | +| visible | boolean | false | 否 | 是否显示消息提醒,当收到新信息提醒时可以设置该属性为true,显示相应的消息提醒,如果需要使用数字标记类型,同时需要设置相应的count属性。 | +| maxcount | number | 99 | 否 | 最大消息数限制,当收到新信息提醒大于该限制时,标识数字会进行省略,仅显示maxcount+。
maxcount属性支持的最大整数值为2147483647。 | +| config | BadgeConfig | - | 否 | 设置新事件标记相关配置属性。 | +| label6+ | string | - | 否 | 设置新事件提醒的文本值。
使用该属性时,count和maxcount属性不生效。 | **表1** BadgeConfig @@ -107,4 +107,4 @@ export default { } ``` -![zh-cn_image_0000001177265268](figures/zh-cn_image_0000001177265268.png) +![zh-cn_image_000000117726526811](figures/zh-cn_image_000000117726526811.png) diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/alphabet.gif b/zh-cn/application-dev/reference/arkui-ts/figures/alphabet.gif new file mode 100644 index 0000000000000000000000000000000000000000..a868febbcb800d9d0df0d3bfcaf57c64e570eb8a Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/alphabet.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/animateTo.gif b/zh-cn/application-dev/reference/arkui-ts/figures/animateTo.gif new file mode 100644 index 0000000000000000000000000000000000000000..8755e2bc014f3843f8798acae725eeb0fee11f54 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/animateTo.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/animation.PNG b/zh-cn/application-dev/reference/arkui-ts/figures/animation.PNG new file mode 100644 index 0000000000000000000000000000000000000000..92f92e0001a90840d03ebd00e0b0ef736c2a94c8 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/animation.PNG differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/animation.gif b/zh-cn/application-dev/reference/arkui-ts/figures/animation.gif new file mode 100644 index 0000000000000000000000000000000000000000..6cfbc07fc5122be3ecd69e6b33b6f00c0f676a0f Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/animation.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/animation1.PNG b/zh-cn/application-dev/reference/arkui-ts/figures/animation1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..98cc1fa8c0537071549fa8185fa14f7ad103e7f8 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/animation1.PNG differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.gif b/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd8d0f1a9f9a786de94abf348130c526ecb09641 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.png b/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.png deleted file mode 100644 index 22285e0910e3c447036d2144194a2e4301c2df6f..0000000000000000000000000000000000000000 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/borderImage.png and /dev/null differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/button.gif b/zh-cn/application-dev/reference/arkui-ts/figures/button.gif new file mode 100644 index 0000000000000000000000000000000000000000..04ab6ed97635118a7ffd3fb9d6be666f2ac40691 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/button.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/clipAndMask.PNG b/zh-cn/application-dev/reference/arkui-ts/figures/clipAndMask.PNG new file mode 100644 index 0000000000000000000000000000000000000000..6f522bf5a01241f67ad8c493a04f3d9d71aa9be5 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/clipAndMask.PNG differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/datePicker.gif b/zh-cn/application-dev/reference/arkui-ts/figures/datePicker.gif new file mode 100644 index 0000000000000000000000000000000000000000..b00b7fad991682b2cd81b0afdd149a3b7f73dc49 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/datePicker.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/flex.PNG b/zh-cn/application-dev/reference/arkui-ts/figures/flex.PNG new file mode 100644 index 0000000000000000000000000000000000000000..ccfb5020729aa765d259afd74fc93822c5752f4d Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/flex.PNG differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/imageAnimator.gif b/zh-cn/application-dev/reference/arkui-ts/figures/imageAnimator.gif new file mode 100644 index 0000000000000000000000000000000000000000..9686185c04ef6c0a764fa7fcb91b8270d503f79d Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/imageAnimator.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/list1.gif b/zh-cn/application-dev/reference/arkui-ts/figures/list1.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b8a734b8fbafb33d47a774d772ec81da8197740 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/list1.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/shared.gif b/zh-cn/application-dev/reference/arkui-ts/figures/shared.gif new file mode 100644 index 0000000000000000000000000000000000000000..d43a6a38d9516945efc3ed80f4f1592c94645952 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/shared.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/swiper.gif b/zh-cn/application-dev/reference/arkui-ts/figures/swiper.gif new file mode 100644 index 0000000000000000000000000000000000000000..692ac1398e1c98217a7466c66b1a3b873165a7ee Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/swiper.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/tabContent.gif b/zh-cn/application-dev/reference/arkui-ts/figures/tabContent.gif new file mode 100644 index 0000000000000000000000000000000000000000..088045f41a884700791adf9fd6709f239c3269c0 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/tabContent.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/textArea.gif b/zh-cn/application-dev/reference/arkui-ts/figures/textArea.gif new file mode 100644 index 0000000000000000000000000000000000000000..52253c3693b7626a5959a2e88e4744d01b80d057 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/textArea.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/timePicker.gif b/zh-cn/application-dev/reference/arkui-ts/figures/timePicker.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ae06ee5b27f1b4ce369b8e90ef5602a1ea0f846 Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/timePicker.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/transform.PNG b/zh-cn/application-dev/reference/arkui-ts/figures/transform.PNG new file mode 100644 index 0000000000000000000000000000000000000000..a840e7050d1ae79179722dd9f23e4f383d1db2ec Binary files /dev/null and b/zh-cn/application-dev/reference/arkui-ts/figures/transform.PNG differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174264386.png b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174264386.png index 2ff75f958a860f1ed483d799e2ef6431fbce5a74..8e96bc78a4ab3e3d5c44201def12d73fea1b6db2 100644 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174264386.png and b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174264386.png differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174582844.gif b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174582844.gif index 30e89347337d9e358d4b823c7658490e032eb435..639261bd9e9997074cd45491807a58bb79a5def2 100644 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174582844.gif and b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001174582844.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001186807708.gif b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001186807708.gif index 8eceb3bf5313485a1fedda5768e70cdb5febc464..c2468d1491af049673574a097a107a3e6c1b417d 100644 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001186807708.gif and b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001186807708.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001241668363.gif b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001241668363.gif index 502888c25bb21b3803858f9c436cca23d9dc29d0..fba237dad5fc43609bb5ebcf6b0310328800d9f6 100644 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001241668363.gif and b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001241668363.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001251007721.gif b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001251007721.gif index 32d2334360f9fd90afd1709f50a39add4e2196c1..3c7f41bb43465b26d9545482a6c42621a42b360b 100644 Binary files a/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001251007721.gif and b/zh-cn/application-dev/reference/arkui-ts/figures/zh-cn_image_0000001251007721.gif differ diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-animatorproperty.md b/zh-cn/application-dev/reference/arkui-ts/ts-animatorproperty.md index 7139f0fad8e3df8ec21e83e443150b23e8273ec3..adfe8558de0cf3cac1ec2cbe908c18c75a11f0ab 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-animatorproperty.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-animatorproperty.md @@ -73,3 +73,5 @@ struct AttrAnimationExample { } } ``` + +![animation](figures/animation.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-appendix-enums.md b/zh-cn/application-dev/reference/arkui-ts/ts-appendix-enums.md index bdb96903ab434ebd9d742c651c8e2c3cdd02880f..01bd2021d811cf64c04b249a092e45ba3c45a858 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-appendix-enums.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-appendix-enums.md @@ -1,4 +1,4 @@ -# 文档中涉及到的内置枚举值 +# 枚举说明 ## Color diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md index e1214c92ca2e17e33b7fee457deff31f38ef20a1..c072a4cf54fec80813302d637c748ca382a60306 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-button.md @@ -30,10 +30,10 @@ **参数:** - | 参数名 | 参数类型 | 必填 | 参数描述 | - | ------- | ----------------------------------- | ---- | ------------- | - | label | [ResourceStr](ts-types.md#resourcestr) | 否 | 按钮文本内容。 | - | options | { type?: ButtonType, stateEffect?: boolean } | 否 | 见方法1参数说明。 | +| 参数名 | 参数类型 | 必填 | 参数描述 | +| ------- | ----------------------------------- | ---- | ------------- | +| label | [ResourceStr](ts-types.md#resourcestr) | 否 | 按钮文本内容。 | +| options | { type?: ButtonType, stateEffect?: boolean } | 否 | 见方法1参数说明。 | ## 属性 @@ -89,9 +89,6 @@ struct ButtonExample { Text('loading').fontSize(12).fontColor(0xffffff).margin({ left: 5, right: 12 }) }.alignItems(VerticalAlign.Center).width(90).height(40) }.backgroundColor(0x317aff) - .onClick((event: ClickEvent) => { - AlertDialog.show({ message: 'The login is successful' }) - }) Button('Disable', { type: ButtonType.Capsule, stateEffect: false }).opacity(0.4) .backgroundColor(0x317aff).width(90) @@ -112,3 +109,4 @@ struct ButtonExample { } ``` +![button](figures/button.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-datepicker.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-datepicker.md index defe3b04193661870318afbc1c0980928c3bad33..74c48383609667735a7bd7a1ef1e9adf97f80a00 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-datepicker.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-datepicker.md @@ -7,10 +7,6 @@ > 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 - - - - ## 子组件 无 @@ -32,81 +28,58 @@ DatePicker(options?: {start?: Date, end?: Date, selected?: Date}) ## 属性 -| 名称 | 参数类型 | 描述 | +| 名称 | 参数类型 | 描述 | | ------| -------------- | -------- | -| lunar | boolean | 日期是否显示农历。
- true:展示农历。
- false:不展示农历。
默认值:false | +| lunar | boolean | 日期是否显示农历。
- true:展示农历。
- false:不展示农历。
默认值:false | ## 事件 -| 名称 | 功能描述 | -| -------- | -------- | -| onChange(callback: (value: DatePickerResult) => void) | 选择日期时触发该事件。 | +| 名称 | 功能描述 | +| -------- | -------- | +| onChange(callback: (value: DatePickerResult) => void) | 选择日期时触发该事件。 | ## DatePickerResult对象说明 -| 名称 | 参数类型 | 描述 | +| 名称 | 参数类型 | 描述 | | -------- | -------- | -------- | -| year | number | 选中日期的年。 | -| month | number | 选中日期的月(0~11),0表示1月,11表示12月。 | -| day | number | 选中日期的日。 | +| year | number | 选中日期的年。 | +| month | number | 选中日期的月(0~11),0表示1月,11表示12月。 | +| day | number | 选中日期的日。 | ## 示例 -### 日期选择器(显示农历) - ```ts // xxx.ets @Entry @Component -struct DatePickerExample01 { +struct DatePickerExample { + @State isLunar: boolean = false private selectedDate: Date = new Date('2021-08-08') build() { Column() { + Button('切换公历农历') + .margin({ top: 30 }) + .onClick(() => { + this.isLunar = !this.isLunar + }) DatePicker({ start: new Date('1970-1-1'), end: new Date('2100-1-1'), - selected: this.selectedDate, - }) - .lunar(true) - .onChange((date: DatePickerResult) => { - console.info('select current date is: ' + JSON.stringify(date)) + selected: this.selectedDate }) - }.width('100%') - } -} -``` - -![zh-cn_image_0000001251279761](figures/zh-cn_image_0000001251279761.gif) + .lunar(this.isLunar) + .onChange((value: DatePickerResult) => { + this.selectedDate.setFullYear(value.year, value.month, value.day) + console.info('select current date is: ' + JSON.stringify(value)) + }) - -### 日期选择器(不显示农历) - -```ts -// xxx.ets -@Entry -@Component -struct DatePickerExample02 { - private selectedDate: Date = new Date('2021-08-08') - - build() { - Column() { - DatePicker({ - start: new Date('1970-1-1'), - end: new Date('2100-1-1'), - selected: this.selectedDate, - }) - .lunar(false) - .onChange((date: DatePickerResult) => { - console.info('select current date is: ' + JSON.stringify(date)) - }) }.width('100%') } } ``` -![zh-cn_image_0000001251092975](figures/zh-cn_image_0000001251092975.gif) - +![datePicker](figures/datePicker.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-gauge.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-gauge.md index a6031d9440bc49619853cc154bd01b5d5e13852f..16884200f16f3521dcd875a035f242050afb282a 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-gauge.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-gauge.md @@ -64,7 +64,7 @@ struct GaugeExample { // 参数设置当前值为75,属性设置值为25,属性设置优先级高 Gauge({ value: 75 }) - .value(25) //属性和参数都设置时以参数为准 + .value(25) // 属性和参数都设置时以参数为准 .width(200).height(200) .colors([[0x317AF7, 1], [0x5BA854, 1], [0xE08C3A, 1], [0x9C554B, 1]]) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md index 79c635647e64f55a94a02962f91b4952bb00998c..e8e04417715a97e95f834d5f3002f9b06c0642dc 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md @@ -27,7 +27,7 @@ Image(src: string | PixelMap | Resource) | 参数名 | 参数类型 | 必填 | 参数描述 | | ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | -| src | string\| [PixelMap](../apis/js-apis-image.md#pixelmap7) \| [Resource](ts-types.md#resource类型) | 是 | 图片的数据源,支持本地图片和网络图片。
当使用相对路径引用图片资源时,例如`Image("common/test.jpg")`,不支持跨包/跨模块调用该Image组件,建议使用`$r`方式来管理需全局使用的图片资源。
\- 支持的图片格式包括png、jpg、bmp、svg和gif。
\- 支持`Base64`字符串。格式`data:image/[png\|jpeg\|bmp\|webp];base64,[base64 data]`, 其中`[base64 data]`为`Base64`字符串数据。
\- 支持`dataability://`路径前缀的字符串,用于访问通过data ability提供的图片路径。
\- 支持file:///data/storage路径前缀的字符串,用于读取本应用安装目录下files文件夹下的图片资源。需要保证目录包路径下的文件有可读权限。 | +| src | string\| [PixelMap](../apis/js-apis-image.md#pixelmap7) \| [Resource](ts-types.md#resource类型) | 是 | 图片的数据源,支持本地图片和网络图片。
当使用相对路径引用图片资源时,例如`Image("common/test.jpg")`,不支持跨包/跨模块调用该Image组件,建议使用`$r`方式来管理需全局使用的图片资源。
\- 支持的图片格式包括png、jpg、bmp、svg和gif。
\- 支持`Base64`字符串。格式`data:image/[png\|jpeg\|bmp\|webp];base64,[base64 data]`, 其中`[base64 data]`为`Base64`字符串数据。
\- 支持`datashare://`路径前缀的字符串,用于访问通过data ability提供的图片路径。
\- 支持file:///data/storage路径前缀的字符串,用于读取本应用安装目录下files文件夹下的图片资源。需要保证目录包路径下的文件有可读权限。 | ## 属性 @@ -353,17 +353,17 @@ struct ImageExample3 { ### 渲染沙箱路径图片 ``` -import fileio from '@ohos.fileio'; -import image from '@ohos.multimedia.image'; +import fileio from '@ohos.fileio' +import image from '@ohos.multimedia.image' -const EMPTY_PATH = 'file://'; +const EMPTY_PATH = 'file://' @Entry @Component struct LoadImageExample { - @State fileContent: string = ''; - @State path: string = EMPTY_PATH; - @State accountInfoHeadPic: any = ''; + @State fileContent: string = '' + @State path: string = EMPTY_PATH + @State accountInfoHeadPic: any = '' build() { Column() { @@ -371,22 +371,22 @@ struct LoadImageExample { .margin({ bottom: 10 }) .onClick(() => { try { - this.path = EMPTY_PATH; - let context = getContext(this); - let path = context.getApplicationContext().filesDir + '/icon.png'; - console.log(`读取沙箱图片=========>${path}`); - let fd = fileio.openSync(path, 0o100, 0o666); - console.log(`create file========>${fd}`); - let srcPath = context.bundleCodeDir + '/entry/resource/base/media/icon.png'; - fileio.copyFileSync(srcPath, path); - console.log(`error:=============>${e.message}`); + this.path = EMPTY_PATH + let context = getContext(this) + let path = context.getApplicationContext().filesDir + '/icon.png' + console.log(`读取沙箱图片=========>${path}`) + let fd = fileio.openSync(path, 0o100, 0o666) + console.log(`create file========>${fd}`) + let srcPath = context.bundleCodeDir + '/entry/resource/base/media/icon.png' + fileio.copyFileSync(srcPath, path) + console.log(`error:=============>${e.message}`) } }) Button('读取资源图片') .margin({ bottom: 10 }) .onClick(() => { this.path = EMPTY_PATH; - this.path += getContext(this.bundleCodeDir + '/entry/resource/base/media/icon.png'); + this.path += getContext(this.bundleCodeDir + '/entry/resource/base/media/icon.png') }) Text(`图片路径:${this.path}`) .fontSize(20) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-imageanimator.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-imageanimator.md index 37f7c25716f2de0c46e17ae1d99b94e6ab50b368..9b838578ffc69b47438dd1ae96ec56e90bb7c9dd 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-imageanimator.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-imageanimator.md @@ -22,13 +22,13 @@ ImageAnimator() | 参数名称 | 参数类型 |参数描述 | | ---------- | ----------------------- |-------- | -| images | Array<[ImageFrameInfo](imageframeinfo对象说明)> | 设置图片帧信息集合。每一帧的帧信息(ImageFrameInfo)包含图片路径、图片大小、图片位置和图片播放时长信息,详见ImageFrameInfo属性说明。
默认值:[] | -| state | [AnimationStatus](ts-appendix-enums.md#animationstatus) |默认为初始状态,用于控制播放状态。
默认值:AnimationStatus.Initial | +| images | Array<[ImageFrameInfo](#imageframeinfo对象说明)> | 设置图片帧信息集合。每一帧的帧信息(ImageFrameInfo)包含图片路径、图片大小、图片位置和图片播放时长信息,详见ImageFrameInfo属性说明。
默认值:[]
**说明:**
不支持动态更新。 | +| state | [AnimationStatus](ts-appendix-enums.md#animationstatus) | 默认为初始状态,用于控制播放状态。
默认值:AnimationStatus.Initial | | duration | number | 单位为毫秒,默认时长为1000ms;duration为0时,不播放图片;值的改变只会在下一次循环开始时生效;当images中任意一帧图片设置了单独的duration后,该属性设置无效。
默认值:1000 | | reverse | boolean | 设置播放顺序。false表示从第1张图片播放到最后1张图片; true表示从最后1张图片播放到第1张图片。
默认值:false | | fixedSize | boolean | 设置图片大小是否固定为组件大小。 true表示图片大小与组件大小一致,此时设置图片的width 、height 、top 和left属性是无效的。false表示每一张图片的width 、height 、top和left属性都要单独设置。
默认值:true | | preDecode | number | 是否启用预解码,默认值为0,即不启用预解码,如该值设为2,则播放当前页时会提前加载后面两张图片至缓存以提升性能。
默认值:0 | -| fillMode | [FillMode](ts-appendix-enums.md#fillmode) | 否 | 设置动画开始前和结束后的状态,可选值参见FillMode说明。
默认值:FillMode.Forwards | +| fillMode | [FillMode](ts-appendix-enums.md#fillmode) | 设置动画开始前和结束后的状态,可选值参见FillMode说明。
默认值:FillMode.Forwards | | iterations | number | 默认播放一次,设置为-1时表示无限次播放。
默认值:1 | ## ImageFrameInfo对象说明 @@ -49,7 +49,7 @@ ImageAnimator() | -------- | -------- | | onStart(event: () => void) | 状态回调,动画开始播放时触发。 | | onPause(event: () => void) | 状态回调,动画暂停播放时触发。 | -| onRepeat(event: () => void) | 状态回调,动画重新播放时触发。 | +| onRepeat(event: () => void) | 状态回调,动画重复播放时触发。 | | onCancel(event: () => void) | 状态回调,动画取消播放时触发。 | | onFinish(event: () => void) | 状态回调,动画播放完成时触发。 | @@ -66,47 +66,46 @@ struct ImageAnimatorExample { @State iterations: number = 1 build() { - Column({ space:5 }) { + Column({ space: 10 }) { ImageAnimator() .images([ - { - // comment文件夹与pages同级 - src: '/comment/bg1.jpg', + { + src: $r('app.media.img1'), duration: 500, - width: 325, - height: 200, + width: 170, + height: 120, top: 0, left: 0 }, { - src: '/comment/bg2.jpg', + src: $r('app.media.img2'), duration: 500, - width: 325, - height: 200, + width: 170, + height: 120, top: 0, - left: 0 + left: 170 }, { - src: $r('app.media.bg3'), + src: $r('app.media.img3'), duration: 500, - width: 325, - height: 200, - top: 0, - left: 0 + width: 170, + height: 120, + top: 120, + left: 170 }, { - src: $rawfile('bg4.jpg'), + src: $r('app.media.img4'), duration: 500, - width: 325, - height: 200, - top: 0, + width: 170, + height: 120, + top: 120, left: 0 } ]) .state(this.state).reverse(this.reverse).fixedSize(false).preDecode(2) - .fillMode(FillMode.None).iterations(this.iterations).width(325).height(210) - .margin({top:100}) - .onStart(() => { // 当帧动画开始播放后触发 + .fillMode(FillMode.None).iterations(this.iterations).width(340).height(240) + .margin({ top: 100 }) + .onStart(() => { console.info('Start') }) .onPause(() => { @@ -118,35 +117,35 @@ struct ImageAnimatorExample { .onCancel(() => { console.info('Cancel') }) - .onFinish(() => { // 当帧动画播放完成后触发 - this.state = AnimationStatus.Stopped + .onFinish(() => { console.info('Finish') }) Row() { Button('start').width(100).padding(5).onClick(() => { this.state = AnimationStatus.Running - }) + }).margin(5) Button('pause').width(100).padding(5).onClick(() => { - this.state = AnimationStatus.Paused - }) + this.state = AnimationStatus.Paused // 显示当前帧图片 + }).margin(5) Button('stop').width(100).padding(5).onClick(() => { - this.state = AnimationStatus.Stopped - }) + this.state = AnimationStatus.Stopped // 显示动画的起始帧图片 + }).margin(5) } + Row() { Button('reverse').width(100).padding(5).onClick(() => { this.reverse = !this.reverse - }) + }).margin(5) Button('once').width(100).padding(5).onClick(() => { this.iterations = 1 - }) - Button('iteration').width(100).padding(5).onClick(() => { - this.iterations = -1 - }) + }).margin(5) + Button('infinite').width(100).padding(5).onClick(() => { + this.iterations = -1 // 无限循环播放 + }).margin(5) } - }.width('100%').height('100%').backgroundColor(0xF1F3F5) + }.width('100%').height('100%') } } ``` -![zh-cn_image_0000001219662643](figures/zh-cn_image_0000001219662643.gif) +![imageAnimator](figures/imageAnimator.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-patternlock.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-patternlock.md index 7edd6d11691ffaa297f809d16372f6ebe4bb6662..13653c27a6f350091794ea36af4c6847209fe355 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-patternlock.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-patternlock.md @@ -66,9 +66,9 @@ reset(): void @Entry @Component struct PatternLockExample { - @State passwords: Number[] = []; - @State message: string = 'please input password!'; - private patternLockController: PatternLockController = new PatternLockController(); + @State passwords: Number[] = [] + @State message: string = 'please input password!' + private patternLockController: PatternLockController = new PatternLockController() build() { Column() { @@ -85,29 +85,29 @@ struct PatternLockExample { .onPatternComplete((input: Array) => { // 输入的密码长度小于5时,提示重新输入 if (input === null || input === undefined || input.length < 5) { - this.message = 'The password length needs to be greater than 5, please enter again.'; - return; + this.message = 'The password length needs to be greater than 5, please enter again.' + return } // 判断密码长度是否大于0 if (this.passwords.length > 0) { // 判断两次输入的密码是否相同,相同则提示密码设置成功,否则提示重新输入 if (this.passwords.toString() === input.toString()) { - this.passwords = input; - this.message = 'Set password successfully: ' + this.passwords.toString(); + this.passwords = input + this.message = 'Set password successfully: ' + this.passwords.toString() } else { - this.message = 'Inconsistent passwords, please enter again.'; + this.message = 'Inconsistent passwords, please enter again.' } } else { // 提示第二次输入密码 - this.passwords = input; - this.message = "Please enter again."; + this.passwords = input + this.message = "Please enter again." } }) Button('Reset PatternLock').margin(30).onClick(() => { // 重置密码锁 - this.patternLockController.reset(); - this.passwords = []; - this.message = 'Please input password'; + this.patternLockController.reset() + this.passwords = [] + this.message = 'Please input password' }) }.width('100%').height('100%') } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-search.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-search.md index 77e5cd47836947ba9efe003504a41147cf1508c2..a336251138f20d8f02d64fefbe30e18b423d0dbb 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-search.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-search.md @@ -75,9 +75,9 @@ caretPosition(value: number): void @Entry @Component struct SearchExample { - @State changeValue: string = ''; - @State submitValue: string = ''; - controller: SearchController = new SearchController(); + @State changeValue: string = '' + @State submitValue: string = '' + controller: SearchController = new SearchController() build() { Column() { @@ -92,16 +92,16 @@ struct SearchExample { .placeholderFont({ size: 14, weight: 400 }) .textFont({ size: 14, weight: 400 }) .onSubmit((value: string) => { - this.submitValue = value; + this.submitValue = value }) .onChange((value: string) => { - this.changeValue = value; + this.changeValue = value }) .margin(20) Button('Set caretPosition 1') .onClick(() => { // 设置光标位置到输入的第一个字符后 - this.controller.caretPosition(1); + this.controller.caretPosition(1) }) }.width('100%') } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-slider.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-slider.md index 80ff26bdd482cdd46e2ac803bd0b896274f4e336..4ee4b62624d053f2198c44f1cfa14d60d83d6d87 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-slider.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-slider.md @@ -75,14 +75,14 @@ Slider(options?: {value?: number, min?: number, max?: number, step?: number, sty @Entry @Component struct SliderExample { - @State outSetValueOne: number = 40; - @State inSetValueOne: number = 40; - @State outSetValueTwo: number = 40; - @State inSetValueTwo: number = 40; - @State vOutSetValueOne: number = 40; - @State vInSetValueOne: number = 40; - @State vOutSetValueTwo: number = 40; - @State vInSetValueTwo: number = 40; + @State outSetValueOne: number = 40 + @State inSetValueOne: number = 40 + @State outSetValueTwo: number = 40 + @State inSetValueTwo: number = 40 + @State vOutSetValueOne: number = 40 + @State vInSetValueOne: number = 40 + @State vOutSetValueTwo: number = 40 + @State vInSetValueTwo: number = 40 build() { Column({ space: 8 }) { @@ -96,8 +96,8 @@ struct SliderExample { }) .showTips(true) .onChange((value: number, mode: SliderChangeMode) => { - this.outSetValueOne = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.outSetValueOne = value + console.info('value:' + value + 'mode:' + mode.toString()) }) // toFixed(0)将滑动条返回值处理为整数精度 Text(this.outSetValueOne.toFixed(0)).fontSize(12) @@ -111,8 +111,8 @@ struct SliderExample { }) .showSteps(true) .onChange((value: number, mode: SliderChangeMode) => { - this.outSetValueTwo = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.outSetValueTwo = value + console.info('value:' + value + 'mode:' + mode.toString()) }) Text(this.outSetValueTwo.toFixed(0)).fontSize(12) } @@ -131,8 +131,8 @@ struct SliderExample { .selectedColor('#4169E1') .showTips(true) .onChange((value: number, mode: SliderChangeMode) => { - this.inSetValueOne = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.inSetValueOne = value + console.info('value:' + value + 'mode:' + mode.toString()) }) Text(this.inSetValueOne.toFixed(0)).fontSize(12) } @@ -148,8 +148,8 @@ struct SliderExample { .selectedColor('#4169E1') .showSteps(true) .onChange((value: number, mode: SliderChangeMode) => { - this.inSetValueTwo = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.inSetValueTwo = value + console.info('value:' + value + 'mode:' + mode.toString()) }) Text(this.inSetValueTwo.toFixed(0)).fontSize(12) } @@ -169,8 +169,8 @@ struct SliderExample { .selectedColor('#4169E1') .showTips(true) .onChange((value: number, mode: SliderChangeMode) => { - this.vOutSetValueOne = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.vOutSetValueOne = value + console.info('value:' + value + 'mode:' + mode.toString()) }) Slider({ value: this.vOutSetValueTwo, @@ -183,8 +183,8 @@ struct SliderExample { .selectedColor('#4169E1') .showSteps(true) .onChange((value: number, mode: SliderChangeMode) => { - this.vOutSetValueTwo = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.vOutSetValueTwo = value + console.info('value:' + value + 'mode:' + mode.toString()) }) } }.width('50%').height(300) @@ -200,8 +200,8 @@ struct SliderExample { }) .showTips(true) .onChange((value: number, mode: SliderChangeMode) => { - this.vInSetValueOne = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.vInSetValueOne = value + console.info('value:' + value + 'mode:' + mode.toString()) }) Slider({ value: this.vInSetValueTwo, @@ -212,8 +212,8 @@ struct SliderExample { }) .showSteps(true) .onChange((value: number, mode: SliderChangeMode) => { - this.vInSetValueTwo = value; - console.info('value:' + value + 'mode:' + mode.toString()); + this.vInSetValueTwo = value + console.info('value:' + value + 'mode:' + mode.toString()) }) } }.width('50%').height(300) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-stepper.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-stepper.md index 12b32146b34e2ac75dd03e2e887037c7a6a0e016..d289dd65cb227bd32f908925cd2947812e73411d 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-stepper.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-stepper.md @@ -48,10 +48,10 @@ Stepper(value?: { index?: number }) @Entry @Component struct StepperExample { - @State currentIndex: number = 0; - @State firstState: ItemState = ItemState.Normal; - @State secondState: ItemState = ItemState.Normal; - @State thirdState: ItemState = ItemState.Normal; + @State currentIndex: number = 0 + @State firstState: ItemState = ItemState.Normal + @State secondState: ItemState = ItemState.Normal + @State thirdState: ItemState = ItemState.Normal build() { Stepper({ @@ -67,7 +67,7 @@ struct StepperExample { .margin({ top: 250, bottom: 50 }) Button('change status:' + this.firstState) .onClick(() => { - this.firstState = this.firstState === ItemState.Skip ? ItemState.Normal : ItemState.Skip; + this.firstState = this.firstState === ItemState.Skip ? ItemState.Normal : ItemState.Skip }) }.width('100%') } @@ -83,7 +83,7 @@ struct StepperExample { .margin({ top: 250, bottom: 50 }) Button('change status:' + this.secondState) .onClick(() => { - this.secondState = this.secondState === ItemState.Disabled ? ItemState.Normal : ItemState.Disabled; + this.secondState = this.secondState === ItemState.Disabled ? ItemState.Normal : ItemState.Disabled }) }.width('100%') } @@ -100,7 +100,7 @@ struct StepperExample { .margin({ top: 250, bottom: 50 }) Button('change status:' + this.thirdState) .onClick(() => { - this.thirdState = this.thirdState === ItemState.Waiting ? ItemState.Normal : ItemState.Waiting; + this.thirdState = this.thirdState === ItemState.Waiting ? ItemState.Normal : ItemState.Waiting }) }.width('100%') } @@ -119,14 +119,14 @@ struct StepperExample { } .onFinish(() => { // 此处可处理点击最后一页的Finish时的逻辑,例如路由跳转等 - console.info('onFinish'); + console.info('onFinish') }) .onSkip(() => { // 此处可处理点击跳过时的逻辑,例如动态修改Stepper的index值使其跳转到某一步骤页等 - console.info('onSkip'); + console.info('onSkip') }) .onChange((prevIndex: number, index: number) => { - this.currentIndex = index; + this.currentIndex = index }) } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textarea.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textarea.md index d13a14c6835699a69d9f5e88211b0ef8d0e8bf11..a36b7afae827d0421190ad5d788fcf06ce0a2080 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textarea.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textarea.md @@ -85,9 +85,10 @@ struct TextAreaExample { build() { Column() { - TextArea({ placeholder: 'input your word', controller: this.controller }) + TextArea({ placeholder: 'The text area can hold an unlimited amount of text. input your word', controller: this.controller }) .placeholderFont({ size: 14, weight: 400 }) .width(400) + .height(50) .margin(20) .fontSize(14) .onChange((value: string) => { @@ -104,3 +105,5 @@ struct TextAreaExample { } } ``` + +![textArea](figures/textArea.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textclock.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textclock.md index d3201827e9f9528d5b449a760534c996958e5ab5..d03b65792c3c407408870796225e0bbada42f951 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textclock.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textclock.md @@ -65,9 +65,9 @@ stop() @Entry @Component struct Second { - @State accumulateTime: number = 0; + @State accumulateTime: number = 0 // 导入对象 - controller: TextClockController = new TextClockController(); + controller: TextClockController = new TextClockController() build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text('Current milliseconds is ' + this.accumulateTime) @@ -76,7 +76,7 @@ struct Second { TextClock({ timeZoneOffset: -8, controller: this.controller }) .format('hms') .onDateChange((value: number) => { - this.accumulateTime = value; + this.accumulateTime = value }) .margin(20) .fontSize(30) @@ -84,12 +84,12 @@ struct Second { .margin({ bottom: 10 }) .onClick(() => { // 启动文本时钟 - this.controller.start(); + this.controller.start() }) Button("stop TextClock") .onClick(() => { // 停止文本时钟 - this.controller.stop(); + this.controller.stop() }) } .width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textinput.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textinput.md index cc71f7e53cf4147ce72488e148a7659bce8c4662..8853f258c7bb80d731dcaf6d78319d005cd94d43 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textinput.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textinput.md @@ -112,8 +112,8 @@ caretPosition(value: number): void @Entry @Component struct TextInputExample { - @State text: string = ''; - controller: TextInputController = new TextInputController(); + @State text: string = '' + controller: TextInputController = new TextInputController() build() { Column() { @@ -127,14 +127,14 @@ struct TextInputExample { .fontSize(14) .fontColor(Color.Black) .onChange((value: string) => { - this.text = value; + this.text = value }) Text(this.text) Button('Set caretPosition 1') .margin(15) .onClick(() => { // 将光标移动至第一个字符后 - this.controller.caretPosition(1); + this.controller.caretPosition(1) }) // 密码输入框 TextInput({ placeholder: 'input your password...' }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textpicker.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textpicker.md index feea880eb6a5486c8bbf2263ecfdc93bcb520ed6..6a85cfa4b5e25080a61ffabfb1bcc05660b802bd 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textpicker.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-textpicker.md @@ -1,6 +1,6 @@ # TextPicker -滚动选择文本的组件。 +滑动选择文本内容的组件。 > **说明:** > @@ -23,14 +23,14 @@ TextPicker(options?: {range: string[]|Resource, selected?: number, value?: strin | 参数名 | 参数类型 | 必填 | 参数描述 | | -------- | -------- | -------- | -------- | | range | string[] \| [Resource](ts-types.md#resource类型) | 是 | 选择器的数据选择列表。 | -| selected | number | 否 | 设置默认选中项在数组中的index值。
默认值:0 | +| selected | number | 否 | 设置默认选中项在数组中的索引值。
默认值:0 | | value | string | 否 | 设置默认选中项的值,优先级低于selected。
默认值:第一个元素值 | ## 属性 | 名称 | 参数类型 | 描述 | | -------- | -------- | -------- | -| defaultPickerItemHeight | number \| string | 默认Picker内容项元素高度。 | +| defaultPickerItemHeight | number \| string | 设置Picker各选择项的高度。 | ## 事件 @@ -53,7 +53,7 @@ struct TextPickerExample { build() { Column() { - TextPicker({range: this.fruits, selected: this.select}) + TextPicker({ range: this.fruits, selected: this.select }) .onChange((value: string, index: number) => { console.info('Picker item changed, value: ' + value + ', index: ' + index) }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-texttimer.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-texttimer.md index d5e0b6879170894cd859e1882783c798a6afeb76..8396476e8ad0867408a4cd801fd7d65e9758a88c 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-texttimer.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-texttimer.md @@ -71,11 +71,11 @@ reset() @Component struct TextTimerExample { textTimerController: TextTimerController = new TextTimerController() - @State format: string = 'HH:mm:ss.SS' + @State format: string = 'mm:ss.SS' build() { Column() { - TextTimer({controller: this.textTimerController}) + TextTimer({ controller: this.textTimerController, isCountDown: true, count: 30000 }) .format(this.format) .fontColor(Color.Black) .fontSize(50) @@ -84,14 +84,14 @@ struct TextTimerExample { }) Row() { Button("start").onClick(() => { - this.textTimerController.start(); - }); + this.textTimerController.start() + }) Button("pause").onClick(() => { - this.textTimerController.pause(); - }); + this.textTimerController.pause() + }) Button("reset").onClick(() => { - this.textTimerController.reset(); - }); + this.textTimerController.reset() + }) } } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-timepicker.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-timepicker.md index 13855a9815cc2ab0ba23ca1e3b0c5c02c2cc8d62..c2bdbd8b10ce8588b99e41090ac5c27b34bad87c 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-timepicker.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-timepicker.md @@ -1,6 +1,6 @@ # TimePicker -滚动选择时间的组件。 +滑动选择时间的组件。 > **说明:** > @@ -16,7 +16,7 @@ TimePicker(options?: {selected?: Date}) -默认以00:00至23:59的时间区间创建滑动选择器。 +默认以24小时的时间区间创建滑动选择器。 **参数:** @@ -55,20 +55,27 @@ TimePicker(options?: {selected?: Date}) @Entry @Component struct TimePickerExample { + @State isMilitaryTime: boolean = false private selectedTime: Date = new Date('2022-07-22T08:00:00') build() { Column() { + Button('切换12小时制/24小时制') + .margin({ top: 30 }) + .onClick(() => { + this.isMilitaryTime = !this.isMilitaryTime + }) TimePicker({ selected: this.selectedTime, }) - .useMilitaryTime(true) - .onChange((date: TimePickerResult) => { - console.info('select current date is: ' + JSON.stringify(date)) - }) + .useMilitaryTime(this.isMilitaryTime) + .onChange((value: TimePickerResult) => { + this.selectedTime.setHours(value.hour, value.minute) + console.info('select current date is: ' + JSON.stringify(value)) + }) }.width('100%') } } ``` -![zh-cn_image_0000001251292933](figures/zh-cn_image_0000001251292933.gif) +![timePicker](figures/timePicker.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-toggle.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-toggle.md index 3928f356b22cc0066f87e55ad2ebd6ea136ff530..bf56800c5b2345d524b0d321b9986e3a0dbb99d6 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-toggle.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-toggle.md @@ -23,7 +23,7 @@ Toggle(options: { type: ToggleType, isOn?: boolean }) | 参数名 | 参数类型 | 必填 | 参数描述 | | ---- | ---------- | -----| -------------- | -| type | ToggleType | 是 | 开关类型。 | +| type | [ToggleType](#toggletype枚举说明) | 是 | 开关类型。 | | isOn | boolean | 否 | 开关是否打开,true:打开,false:关闭。
默认值:false | diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md index 6a53c8b54acf74ecb26f23dbd4e38b1f397cb5b3..c98b994e927e91c33a8f7d559536941e92bfdc92 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-web.md @@ -37,7 +37,7 @@ Web(options: { src: ResourceStr, controller: WebController | WebviewController}) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -52,7 +52,7 @@ Web(options: { src: ResourceStr, controller: WebController | WebviewController}) @Entry @Component struct WebComponent { - controller: web_webview.WebviewController = new web_webview.WebviewController(); + controller: web_webview.WebviewController = new web_webview.WebviewController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -67,7 +67,7 @@ Web(options: { src: ResourceStr, controller: WebController | WebviewController}) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: $rawfile("index.html"), controller: this.controller }) @@ -109,7 +109,7 @@ domStorageAccess(domStorageAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -138,7 +138,7 @@ fileAccess(fileAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -167,7 +167,7 @@ fileFromUrlAccess(fileFromUrlAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -195,7 +195,7 @@ imageAccess(imageAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -228,16 +228,16 @@ javaScriptProxy(javaScriptProxy: { object: object, name: string, methodList: Arr @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() testObj = { test: (data1, data2, data3) => { - console.log("data1:" + data1); - console.log("data2:" + data2); - console.log("data3:" + data3); - return "AceString"; + console.log("data1:" + data1) + console.log("data2:" + data2) + console.log("data3:" + data3) + return "AceString" }, toString: () => { - console.log('toString' + "interface instead."); + console.log('toString' + "interface instead.") } } build() { @@ -261,16 +261,16 @@ javaScriptProxy(javaScriptProxy: { object: object, name: string, methodList: Arr @Entry @Component struct WebComponent { - controller: web_webview.WebviewController = new web_webview.WebviewController(); + controller: web_webview.WebviewController = new web_webview.WebviewController() testObj = { test: (data1, data2, data3) => { - console.log("data1:" + data1); - console.log("data2:" + data2); - console.log("data3:" + data3); - return "AceString"; + console.log("data1:" + data1) + console.log("data2:" + data2) + console.log("data3:" + data3) + return "AceString" }, toString: () => { - console.log('toString' + "interface instead."); + console.log('toString' + "interface instead.") } } build() { @@ -307,7 +307,7 @@ javaScriptAccess(javaScriptAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -336,8 +336,8 @@ mixedMode(mixedMode: MixedMode) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State mode: MixedMode = MixedMode.All; + controller: WebController = new WebController() + @State mode: MixedMode = MixedMode.All build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -366,7 +366,7 @@ onlineImageAccess(onlineImageAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -395,7 +395,7 @@ zoomAccess(zoomAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -424,7 +424,7 @@ overviewModeAccess(overviewModeAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -453,7 +453,7 @@ databaseAccess(databaseAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -482,7 +482,7 @@ geolocationAccess(geolocationAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -511,8 +511,8 @@ mediaPlayGestureAccess(access: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State access: boolean = true; + controller: WebController = new WebController() + @State access: boolean = true build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -541,7 +541,7 @@ multiWindowAccess(multiWindow: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -570,8 +570,8 @@ cacheMode(cacheMode: CacheMode) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State mode: CacheMode = CacheMode.None; + controller: WebController = new WebController() + @State mode: CacheMode = CacheMode.None build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -600,8 +600,8 @@ textZoomRatio(textZoomRatio: number) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State atio: number = 150; + controller: WebController = new WebController() + @State atio: number = 150 build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -630,8 +630,8 @@ userAgent(userAgent: string) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State userAgent:string = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'; + controller: WebController = new WebController() + @State userAgent:string = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36' build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -660,8 +660,8 @@ webDebuggingAccess(webDebuggingAccess: boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State webDebuggingAccess: boolean = true; + controller: WebController = new WebController() + @State webDebuggingAccess: boolean = true build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -706,7 +706,7 @@ onAlert(callback: (event?: { url: string; message: string; result: JsResult }) = @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -730,7 +730,7 @@ onAlert(callback: (event?: { url: string; message: string; result: JsResult }) = event.result.handleCancel() } }) - return true; + return true }) } } @@ -764,14 +764,14 @@ onBeforeUnload(callback: (event?: { url: string; message: string; result: JsResu @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onBeforeUnload((event) => { - console.log("event.url:" + event.url); - console.log("event.message:" + event.message); + console.log("event.url:" + event.url) + console.log("event.message:" + event.message) AlertDialog.show({ title: 'onBeforeUnload', message: 'text', @@ -791,7 +791,7 @@ onBeforeUnload(callback: (event?: { url: string; message: string; result: JsResu event.result.handleCancel() } }) - return true; + return true }) } } @@ -825,15 +825,15 @@ onConfirm(callback: (event?: { url: string; message: string; result: JsResult }) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onConfirm((event) => { - console.log("event.url:" + event.url); - console.log("event.message:" + event.message); - console.log("event.result:" + event.result); + console.log("event.url:" + event.url) + console.log("event.message:" + event.message) + console.log("event.result:" + event.result) AlertDialog.show({ title: 'onConfirm', message: 'text', @@ -853,7 +853,7 @@ onConfirm(callback: (event?: { url: string; message: string; result: JsResult }) event.result.handleCancel() } }) - return true; + return true }) } } @@ -885,15 +885,15 @@ onPrompt(callback: (event?: { url: string; message: string; value: string; resul @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onPrompt((event) => { - console.log("url:" + event.url); - console.log("message:" + event.message); - console.log("value:" + event.value); + console.log("url:" + event.url) + console.log("message:" + event.message) + console.log("value:" + event.value) AlertDialog.show({ title: 'onPrompt', message: 'text', @@ -913,7 +913,7 @@ onPrompt(callback: (event?: { url: string; message: string; value: string; resul event.result.handleCancel() } }) - return true; + return true }) } } @@ -945,17 +945,17 @@ onConsole(callback: (event?: { message: ConsoleMessage }) => boolean) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onConsole((event) => { - console.log('getMessage:' + event.message.getMessage()); - console.log('getSourceId:' + event.message.getSourceId()); - console.log('getLineNumber:' + event.message.getLineNumber()); - console.log('getMessageLevel:' + event.message.getMessageLevel()); - return false; + console.log('getMessage:' + event.message.getMessage()) + console.log('getSourceId:' + event.message.getSourceId()) + console.log('getLineNumber:' + event.message.getLineNumber()) + console.log('getMessageLevel:' + event.message.getMessageLevel()) + return false }) } } @@ -982,17 +982,17 @@ onDownloadStart(callback: (event?: { url: string, userAgent: string, contentDisp @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onDownloadStart((event) => { - console.log('url:' + event.url); - console.log('userAgent:' + event.userAgent); - console.log('contentDisposition:' + event.contentDisposition); - console.log('contentLength:' + event.contentLength); - console.log('mimetype:' + event.mimetype); + console.log('url:' + event.url) + console.log('userAgent:' + event.userAgent) + console.log('contentDisposition:' + event.contentDisposition) + console.log('contentLength:' + event.contentLength) + console.log('mimetype:' + event.mimetype) }) } } @@ -1019,23 +1019,23 @@ onErrorReceive(callback: (event?: { request: WebResourceRequest, error: WebResou @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onErrorReceive((event) => { - console.log('getErrorInfo:' + event.error.getErrorInfo()); - console.log('getErrorCode:' + event.error.getErrorCode()); - console.log('url:' + event.request.getRequestUrl()); - console.log('isMainFrame:' + event.request.isMainFrame()); - console.log('isRedirect:' + event.request.isRedirect()); - console.log('isRequestGesture:' + event.request.isRequestGesture()); - console.log('getRequestHeader_headerKey:' + event.request.getRequestHeader().toString()); - let result = event.request.getRequestHeader(); - console.log('The request header result size is ' + result.length); + console.log('getErrorInfo:' + event.error.getErrorInfo()) + console.log('getErrorCode:' + event.error.getErrorCode()) + console.log('url:' + event.request.getRequestUrl()) + console.log('isMainFrame:' + event.request.isMainFrame()) + console.log('isRedirect:' + event.request.isRedirect()) + console.log('isRequestGesture:' + event.request.isRequestGesture()) + console.log('getRequestHeader_headerKey:' + event.request.getRequestHeader().toString()) + let result = event.request.getRequestHeader() + console.log('The request header result size is ' + result.length) for (let i of result) { - console.log('The request header key is : ' + i.headerKey + ', value is : ' + i.headerValue); + console.log('The request header key is : ' + i.headerKey + ', value is : ' + i.headerValue) } }) } @@ -1063,30 +1063,30 @@ onHttpErrorReceive(callback: (event?: { request: WebResourceRequest, response: W @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onHttpErrorReceive((event) => { - console.log('url:' + event.request.getRequestUrl()); - console.log('isMainFrame:' + event.request.isMainFrame()); - console.log('isRedirect:' + event.request.isRedirect()); - console.log('isRequestGesture:' + event.request.isRequestGesture()); - console.log('getResponseData:' + event.response.getResponseData()); - console.log('getResponseEncoding:' + event.response.getResponseEncoding()); - console.log('getResponseMimeType:' + event.response.getResponseMimeType()); - console.log('getResponseCode:' + event.response.getResponseCode()); - console.log('getReasonMessage:' + event.response.getReasonMessage()); - let result = event.request.getRequestHeader(); - console.log('The request header result size is ' + result.length); + console.log('url:' + event.request.getRequestUrl()) + console.log('isMainFrame:' + event.request.isMainFrame()) + console.log('isRedirect:' + event.request.isRedirect()) + console.log('isRequestGesture:' + event.request.isRequestGesture()) + console.log('getResponseData:' + event.response.getResponseData()) + console.log('getResponseEncoding:' + event.response.getResponseEncoding()) + console.log('getResponseMimeType:' + event.response.getResponseMimeType()) + console.log('getResponseCode:' + event.response.getResponseCode()) + console.log('getReasonMessage:' + event.response.getReasonMessage()) + let result = event.request.getRequestHeader() + console.log('The request header result size is ' + result.length) for (let i of result) { - console.log('The request header key is : ' + i.headerKey + ' , value is : ' + i.headerValue); + console.log('The request header key is : ' + i.headerKey + ' , value is : ' + i.headerValue) } - let resph = event.response.getResponseHeader(); - console.log('The response header result size is ' + resph.length); + let resph = event.response.getResponseHeader() + console.log('The response header result size is ' + resph.length) for (let i of resph) { - console.log('The response header key is : ' + i.headerKey + ' , value is : ' + i.headerValue); + console.log('The response header key is : ' + i.headerKey + ' , value is : ' + i.headerValue) } }) } @@ -1114,13 +1114,13 @@ onPageBegin(callback: (event?: { url: string }) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onPageBegin((event) => { - console.log('url:' + event.url); + console.log('url:' + event.url) }) } } @@ -1147,13 +1147,13 @@ onPageEnd(callback: (event?: { url: string }) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onPageEnd((event) => { - console.log('url:' + event.url); + console.log('url:' + event.url) }) } } @@ -1179,7 +1179,7 @@ onProgressChange(callback: (event?: { newProgress: number }) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -1211,7 +1211,7 @@ onTitleReceive(callback: (event?: { title: string }) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -1244,13 +1244,13 @@ onRefreshAccessedHistory(callback: (event?: { url: string, isRefreshed: boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onRefreshAccessedHistory((event) => { - console.log('url:' + event.url + ' isReload:' + event.isRefreshed); + console.log('url:' + event.url + ' isReload:' + event.isRefreshed) }) } } @@ -1276,13 +1276,13 @@ onRenderExited(callback: (event?: { renderExitReason: RenderExitReason }) => voi @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'chrome://crash/', controller: this.controller }) .onRenderExited((event) => { - console.log('reason:' + event.renderExitReason); + console.log('reason:' + event.renderExitReason) }) } } @@ -1315,7 +1315,7 @@ onShowFileSelector(callback: (event?: { result: FileSelectorResult, fileSelector @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -1338,7 +1338,7 @@ onShowFileSelector(callback: (event?: { result: FileSelectorResult, fileSelector event.result.handleFileList(fileList) } }) - return true; + return true }) } } @@ -1370,14 +1370,14 @@ onUrlLoadIntercept(callback: (event?: { data:string | WebResourceRequest }) => b @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onUrlLoadIntercept((event) => { console.log('onUrlLoadIntercept ' + event.data.toString()) - return true; + return true }) } } @@ -1409,9 +1409,9 @@ onInterceptRequest(callback: (event?: { request: WebResourceRequest}) => WebReso @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - responseweb: WebResourceResponse = new WebResourceResponse(); - heads:Header[] = new Array(); + controller: WebController = new WebController() + responseweb: WebResourceResponse = new WebResourceResponse() + heads:Header[] = new Array() @State webdata: string = "\n" + "\n"+ "\n"+ @@ -1425,7 +1425,7 @@ onInterceptRequest(callback: (event?: { request: WebResourceRequest}) => WebReso Column() { Web({ src: 'www.example.com', controller: this.controller }) .onInterceptRequest((event) => { - console.log('url:' + event.request.getRequestUrl()); + console.log('url:' + event.request.getRequestUrl()) var head1:Header = { headerKey:"Connection", headerValue:"keep-alive" @@ -1434,15 +1434,15 @@ onInterceptRequest(callback: (event?: { request: WebResourceRequest}) => WebReso headerKey:"Cache-Control", headerValue:"no-cache" } - var length = this.heads.push(head1); - length = this.heads.push(head2); - this.responseweb.setResponseHeader(this.heads); - this.responseweb.setResponseData(this.webdata); - this.responseweb.setResponseEncoding('utf-8'); - this.responseweb.setResponseMimeType('text/html'); - this.responseweb.setResponseCode(200); - this.responseweb.setReasonMessage('OK'); - return this.responseweb; + var length = this.heads.push(head1) + length = this.heads.push(head2) + this.responseweb.setResponseHeader(this.heads) + this.responseweb.setResponseData(this.webdata) + this.responseweb.setResponseEncoding('utf-8') + this.responseweb.setResponseMimeType('text/html') + this.responseweb.setResponseCode(200) + this.responseweb.setReasonMessage('OK') + return this.responseweb }) } } @@ -1477,8 +1477,8 @@ onHttpAuthRequest(callback: (event?: { handler: HttpAuthHandler, host: string, r @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - httpAuth: boolean = false; + controller: WebController = new WebController() + httpAuth: boolean = false build() { Column() { @@ -1490,13 +1490,13 @@ onHttpAuthRequest(callback: (event?: { handler: HttpAuthHandler, host: string, r primaryButton: { value: 'cancel', action: () => { - event.handler.cancel(); + event.handler.cancel() } }, secondaryButton: { value: 'ok', action: () => { - this.httpAuth = event.handler.isHttpAuthInfoSaved(); + this.httpAuth = event.handler.isHttpAuthInfoSaved() if (this.httpAuth == false) { web_webview.WebDataBase.saveHttpAuthCredentials( event.host, @@ -1504,15 +1504,15 @@ onHttpAuthRequest(callback: (event?: { handler: HttpAuthHandler, host: string, r "2222", "2222" ) - event.handler.cancel(); + event.handler.cancel() } } }, cancel: () => { - event.handler.cancel(); + event.handler.cancel() } }) - return true; + return true }) } } @@ -1539,7 +1539,7 @@ onSslErrorEventReceive(callback: (event: { handler: SslErrorHandler, error: SslE @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -1551,20 +1551,20 @@ onSslErrorEventReceive(callback: (event: { handler: SslErrorHandler, error: SslE primaryButton: { value: 'confirm', action: () => { - event.handler.handleConfirm(); + event.handler.handleConfirm() } }, secondaryButton: { value: 'cancel', action: () => { - event.handler.handleCancel(); + event.handler.handleCancel() } }, cancel: () => { - event.handler.handleCancel(); + event.handler.handleCancel() } }) - return true; + return true }) } } @@ -1594,7 +1594,7 @@ onClientAuthenticationRequest(callback: (event: {handler : ClientAuthenticationH @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -1606,20 +1606,20 @@ onClientAuthenticationRequest(callback: (event: {handler : ClientAuthenticationH primaryButton: { value: 'confirm', action: () => { - event.handler.confirm("/system/etc/user.pk8", "/system/etc/chain-user.pem"); + event.handler.confirm("/system/etc/user.pk8", "/system/etc/chain-user.pem") } }, secondaryButton: { value: 'cancel', action: () => { - event.handler.cancel(); + event.handler.cancel() } }, cancel: () => { - event.handler.ignore(); + event.handler.ignore() } }) - return true; + return true }) } } @@ -1645,7 +1645,7 @@ onPermissionRequest(callback: (event?: { request: PermissionRequest }) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) @@ -1656,17 +1656,17 @@ onPermissionRequest(callback: (event?: { request: PermissionRequest }) => void) primaryButton: { value: 'deny', action: () => { - event.request.deny(); + event.request.deny() } }, secondaryButton: { value: 'onConfirm', action: () => { - event.request.grant(event.request.getAccessibleResource()); + event.request.grant(event.request.getAccessibleResource()) } }, cancel: () => { - event.request.deny(); + event.request.deny() } }) }) @@ -1701,14 +1701,14 @@ onContextMenuShow(callback: (event?: { param: WebContextMenuParam, result: WebCo @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onContextMenuShow((event) => { - console.info("x coord = " + event.param.x()); - console.info("link url = " + event.param.getLinkUrl()); - return true; + console.info("x coord = " + event.param.x()) + console.info("link url = " + event.param.getLinkUrl()) + return true }) } } @@ -1735,13 +1735,13 @@ onScroll(callback: (event: {xOffset: number, yOffset: number}) => void) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onScroll((event) => { - console.info("x = " + event.xOffset); - console.info("y = " + event.yOffset); + console.info("x = " + event.xOffset) + console.info("y = " + event.yOffset) }) } } @@ -1768,7 +1768,7 @@ onGeolocationShow(callback: (event?: { origin: string, geolocation: JsGeolocatio @Entry @Component struct WebComponent { - controller:WebController = new WebController(); + controller:WebController = new WebController() build() { Column() { Web({ src:'www.example.com', controller:this.controller }) @@ -1780,11 +1780,11 @@ onGeolocationShow(callback: (event?: { origin: string, geolocation: JsGeolocatio confirm: { value: 'onConfirm', action: () => { - event.geolocation.invoke(event.origin, true, true); + event.geolocation.invoke(event.origin, true, true) } }, cancel: () => { - event.geolocation.invoke(event.origin, false, true); + event.geolocation.invoke(event.origin, false, true) } }) }) @@ -1812,14 +1812,14 @@ onFullScreenEnter(callback: (event: { handler: FullScreenExitHandler }) => void) @Entry @Component struct WebComponent { - controller:WebController = new WebController(); - handler: FullScreenExitHandler = null; + controller:WebController = new WebController() + handler: FullScreenExitHandler = null build() { Column() { Web({ src:'www.example.com', controller:this.controller }) .onFullScreenEnter((event) => { - console.log("onFullScreenEnter..."); - this.handler = event.handler; + console.log("onFullScreenEnter...") + this.handler = event.handler }) } } @@ -1845,17 +1845,17 @@ onFullScreenExit(callback: () => void) @Entry @Component struct WebComponent { - controller:WebController = new WebController(); - handler: FullScreenExitHandler = null; + controller:WebController = new WebController() + handler: FullScreenExitHandler = null build() { Column() { Web({ src:'www.example.com', controller:this.controller }) .onFullScreenExit(() => { - console.log("onFullScreenExit..."); - this.handler.exitFullScreen(); + console.log("onFullScreenExit...") + this.handler.exitFullScreen() }) .onFullScreenEnter((event) => { - this.handler = event.handler; + this.handler = event.handler }) } } @@ -1884,15 +1884,15 @@ onWindowNew(callback: (event: {isAlert: boolean, isUserTrigger: boolean, targetU @Entry @Component struct WebComponent { - controller:WebController = new WebController(); + controller:WebController = new WebController() build() { Column() { Web({ src:'www.example.com', controller: this.controller }) .multiWindowAccess(true) .onWindowNew((event) => { - console.log("onWindowNew..."); - var popController: WebController = new WebController(); - event.handler.setWebController(popController); + console.log("onWindowNew...") + var popController: WebController = new WebController() + event.handler.setWebController(popController) }) } } @@ -1918,12 +1918,12 @@ onWindowExit(callback: () => void) @Entry @Component struct WebComponent { - controller:WebController = new WebController(); + controller:WebController = new WebController() build() { Column() { Web({ src:'www.example.com', controller: this.controller }) .onWindowExit((event) => { - console.log("onWindowExit..."); + console.log("onWindowExit...") }) } } @@ -2619,13 +2619,13 @@ requestFocus() @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('requestFocus') .onClick(() => { - this.controller.requestFocus(); + this.controller.requestFocus() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2652,14 +2652,14 @@ accessBackward(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('accessBackward') .onClick(() => { - let result = this.controller.accessBackward(); - console.log('result:' + result); + let result = this.controller.accessBackward() + console.log('result:' + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2686,14 +2686,14 @@ accessForward(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('accessForward') .onClick(() => { - let result = this.controller.accessForward(); - console.log('result:' + result); + let result = this.controller.accessForward() + console.log('result:' + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2726,15 +2726,15 @@ accessStep(step: number): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State steps: number = 2; + controller: WebController = new WebController() + @State steps: number = 2 build() { Column() { Button('accessStep') .onClick(() => { - let result = this.controller.accessStep(this.steps); - console.log('result:' + result); + let result = this.controller.accessStep(this.steps) + console.log('result:' + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2755,13 +2755,13 @@ backward(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('backward') .onClick(() => { - this.controller.backward(); + this.controller.backward() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2782,13 +2782,13 @@ forward(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('forward') .onClick(() => { - this.controller.forward(); + this.controller.forward() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2815,14 +2815,14 @@ backOrForward(step: number): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State step: number = -2; + controller: WebController = new WebController() + @State step: number = -2 build() { Column() { Button('backOrForward') .onClick(() => { - this.controller.backOrForward(this.step); + this.controller.backOrForward(this.step) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2849,14 +2849,14 @@ deleteJavaScriptRegister(name: string) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State name: string = 'Object'; + controller: WebController = new WebController() + @State name: string = 'Object' build() { Column() { Button('deleteJavaScriptRegister') .onClick(() => { - this.controller.deleteJavaScriptRegister(this.name); + this.controller.deleteJavaScriptRegister(this.name) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2883,14 +2883,14 @@ getHitTest(): HitTestType @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getHitTest') .onClick(() => { - let hitType = this.controller.getHitTest(); - console.log("hitType: " + hitType); + let hitType = this.controller.getHitTest() + console.log("hitType: " + hitType) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2916,15 +2916,15 @@ getHitTestValue(): HitTestValue @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getHitTestValue') .onClick(() => { - let hitValue = this.controller.getHitTestValue(); - console.log("hitType: " + hitValue.getType()); - console.log("extra: " + hitValue.getExtra()); + let hitValue = this.controller.getHitTestValue() + console.log("hitType: " + hitValue.getType()) + console.log("extra: " + hitValue.getExtra()) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2950,14 +2950,14 @@ getWebId(): number @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getWebId') .onClick(() => { - let id = this.controller.getWebId(); - console.log("id: " + id); + let id = this.controller.getWebId() + console.log("id: " + id) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -2983,14 +2983,14 @@ getTitle(): string @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getTitle') .onClick(() => { - let title = this.controller.getTitle(); - console.log("title: " + title); + let title = this.controller.getTitle() + console.log("title: " + title) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3016,14 +3016,14 @@ getPageHeight(): number @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getPageHeight') .onClick(() => { - let pageHeight = this.controller.getPageHeight(); - console.log("pageHeight: " + pageHeight); + let pageHeight = this.controller.getPageHeight() + console.log("pageHeight: " + pageHeight) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3049,14 +3049,14 @@ getDefaultUserAgent(): string @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getDefaultUserAgent') .onClick(() => { - let userAgent = this.controller.getDefaultUserAgent(); - console.log("userAgent: " + userAgent); + let userAgent = this.controller.getDefaultUserAgent() + console.log("userAgent: " + userAgent) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3091,7 +3091,7 @@ baseUrl为空时,通过”data“协议加载指定的一段字符串。 @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -3101,7 +3101,7 @@ baseUrl为空时,通过”data“协议加载指定的一段字符串。 data: "Source:
source
", mimeType: "text/html", encoding: "UTF-8" - }); + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3133,13 +3133,13 @@ loadUrl(options: { url: string | Resource, headers?: Array\ }) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('loadUrl') .onClick(() => { - this.controller.loadUrl({ url: 'www.example.com' }); + this.controller.loadUrl({ url: 'www.example.com' }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3160,13 +3160,13 @@ onActive(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('onActive') .onClick(() => { - this.controller.onActive(); + this.controller.onActive() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3187,13 +3187,13 @@ onInactive(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('onInactive') .onClick(() => { - this.controller.onInactive(); + this.controller.onInactive() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3219,14 +3219,14 @@ zoom(factor: number): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State factor: number = 1; + controller: WebController = new WebController() + @State factor: number = 1 build() { Column() { Button('zoom') .onClick(() => { - this.controller.zoom(this.factor); + this.controller.zoom(this.factor) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3252,14 +3252,14 @@ zoomIn(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('zoomIn') .onClick(() => { - let result = this.controller.zoomIn(); - console.log("result: " + result); + let result = this.controller.zoomIn() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3285,14 +3285,14 @@ zoomOut(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('zoomOut') .onClick(() => { - let result = this.controller.zoomOut(); - console.log("result: " + result); + let result = this.controller.zoomOut() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3313,13 +3313,13 @@ refresh() @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('refresh') .onClick(() => { - this.controller.refresh(); + this.controller.refresh() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3351,10 +3351,10 @@ registerJavaScriptProxy(options: { object: object, name: string, methodList: Arr controller: WebController = new WebController() testObj = { test: (data) => { - return "ArkUI Web Component"; + return "ArkUI Web Component" }, toString: () => { - console.log('Web Component toString'); + console.log('Web Component toString') } } build() { @@ -3365,7 +3365,7 @@ registerJavaScriptProxy(options: { object: object, name: string, methodList: Arr object: this.testObj, name: "objName", methodList: ["test", "toString"], - }); + }) }) } Web({ src: $rawfile('index.html'), controller: this.controller }) @@ -3385,8 +3385,8 @@ registerJavaScriptProxy(options: { object: object, name: string, methodList: Arr @@ -3413,7 +3413,7 @@ runJavaScript(options: { script: string, callback?: (result: string) => void }) @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() @State webResult: string = '' build() { Column() { @@ -3426,8 +3426,8 @@ runJavaScript(options: { script: string, callback?: (result: string) => void }) callback: (result: string)=> { this.webResult = result console.info(`The test() return value is: ${result}`) - }}); - console.info('url: ', e.url); + }}) + console.info('url: ', e.url) }) } } @@ -3444,7 +3444,7 @@ runJavaScript(options: { script: string, callback?: (result: string) => void }) @@ -3465,13 +3465,13 @@ stop() @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('stop') .onClick(() => { - this.controller.stop(); + this.controller.stop() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3492,13 +3492,13 @@ clearHistory(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('clearHistory') .onClick(() => { - this.controller.clearHistory(); + this.controller.clearHistory() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3519,13 +3519,13 @@ clearSslCache(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('clearSslCache') .onClick(() => { - this.controller.clearSslCache(); + this.controller.clearSslCache() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3546,13 +3546,13 @@ clearClientAuthenticationCache(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('clearClientAuthenticationCache') .onClick(() => { - this.controller.clearClientAuthenticationCache(); + this.controller.clearClientAuthenticationCache() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3579,13 +3579,13 @@ getCookieManager(): WebCookie @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getCookieManager') .onClick(() => { - let cookieManager = this.controller.getCookieManager(); + let cookieManager = this.controller.getCookieManager() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3613,13 +3613,13 @@ createWebMessagePorts(): Array\ @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; + controller: WebController = new WebController() + ports: WebMessagePort[] = null build() { Column() { Button('createWebMessagePorts') .onClick(() => { - this.ports = this.controller.createWebMessagePorts(); + this.ports = this.controller.createWebMessagePorts() console.log("createWebMessagePorts size:" + this.ports.length) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -3648,10 +3648,10 @@ postMessage(options: { message: WebMessageEvent, uri: string}): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; - @State sendFromEts: string = 'Send this message from ets to HTML'; - @State receivedFromHtml: string = 'Display received message send from HTML'; + controller: WebController = new WebController() + ports: WebMessagePort[] = null + @State sendFromEts: string = 'Send this message from ets to HTML' + @State receivedFromHtml: string = 'Display received message send from HTML' build() { Column() { @@ -3660,41 +3660,41 @@ postMessage(options: { message: WebMessageEvent, uri: string}): void // 输入框的内容发送到HTML TextInput({placeholder: 'Send this message from ets to HTML'}) .onChange((value: string) => { - this.sendFromEts = value; + this.sendFromEts = value }) // 1、创建两个消息端口 Button('1.CreateWebMessagePorts') .onClick(() => { - this.ports = this.controller.createWebMessagePorts(); + this.ports = this.controller.createWebMessagePorts() console.log("createWebMessagePorts size:" + this.ports.length) }) // 2、将其中一个消息端口发送到HTML侧,由HTML侧保存并使用。 Button('2.PostMessagePort') .onClick(() => { - var sendPortArray = new Array(this.ports[1]); - var msgEvent = new WebMessageEvent(); - msgEvent.setData("__init_port__"); - msgEvent.setPorts(sendPortArray); - this.controller.postMessage({message: msgEvent, uri: "*"}); + var sendPortArray = new Array(this.ports[1]) + var msgEvent = new WebMessageEvent() + msgEvent.setData("__init_port__") + msgEvent.setPorts(sendPortArray) + this.controller.postMessage({message: msgEvent, uri: "*"}) }) // 3、另一个消息端口在应用侧注册回调事件。 Button('3.RegisterCallback') .onClick(() => { this.ports[0].onMessageEvent((result: string) => { - var msg = 'Got msg from HTML: ' + result; - this.receivedFromHtml = msg; + var msg = 'Got msg from HTML: ' + result + this.receivedFromHtml = msg }) }) // 4、使用应用侧的端口给另一个已经发送到HTML的消息端口发送消息。 Button('4.SendDataToHtml5') .onClick(() => { - var msg = new WebMessageEvent(); - msg.setData(this.sendFromEts); - this.ports[0].postMessageEvent(msg); + var msg = new WebMessageEvent() + msg.setData(this.sendFromEts) + this.ports[0].postMessageEvent(msg) }) Web({ src: $rawfile("index.html"), controller: this.controller }) .javaScriptAccess(true) @@ -3758,12 +3758,12 @@ getUrl(): string @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getUrl') .onClick(() => { - console.log("url: " + this.controller.getUrl()); + console.log("url: " + this.controller.getUrl()) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3826,14 +3826,14 @@ setCookie(url: string, value: string): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('setCookie') .onClick(() => { - let result = this.controller.getCookieManager().setCookie("www.example.com", "a=b"); - console.log("result: " + result); + let result = this.controller.getCookieManager().setCookie("www.example.com", "a=b") + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3859,14 +3859,14 @@ saveCookieSync(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('saveCookieSync') .onClick(() => { - let result = this.controller.getCookieManager().saveCookieSync(); - console.log("result: " + result); + let result = this.controller.getCookieManager().saveCookieSync() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3899,14 +3899,14 @@ getCookie(url: string): string @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getCookie') .onClick(() => { - let value = webview.WebCookieManager.getCookie('www.example.com'); - console.log("value: " + value); + let value = webview.WebCookieManager.getCookie('www.example.com') + console.log("value: " + value) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3940,14 +3940,14 @@ setCookie(url: string, value: string): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('setCookie') .onClick(() => { - let result = web_webview.WebCookieManager.setCookie('www.example.com', 'a=b'); - console.log("result: " + result); + let result = web_webview.WebCookieManager.setCookie('www.example.com', 'a=b') + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -3974,14 +3974,14 @@ saveCookieSync(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('saveCookieSync') .onClick(() => { - let result = web_webview.WebCookieManager.saveCookieSync(); - console.log("result: " + result); + let result = web_webview.WebCookieManager.saveCookieSync() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4008,7 +4008,7 @@ saveCookieAsync(): Promise\ @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { @@ -4016,11 +4016,11 @@ saveCookieAsync(): Promise\ .onClick(() => { web_webview.WebCookieManager.saveCookieAsync() .then (function(result) { - console.log("result: " + result); + console.log("result: " + result) }) .catch(function(error) { - console.error("error: " + error); - }); + console.error("error: " + error) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4047,15 +4047,15 @@ saveCookieAsync(callback: AsyncCallback\): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('saveCookieAsync') .onClick(() => { web_webview.WebCookieManager.saveCookieAsync(function(result) { - console.log("result: " + result); - }); + console.log("result: " + result) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4082,14 +4082,14 @@ isCookieAllowed(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('isCookieAllowed') .onClick(() => { - let result = web_webview.WebCookieManager.isCookieAllowed(); - console.log("result: " + result); + let result = web_webview.WebCookieManager.isCookieAllowed() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4116,13 +4116,13 @@ putAcceptCookieEnabled(accept: boolean): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('putAcceptCookieEnabled') .onClick(() => { - web_webview.WebCookieManager.putAcceptCookieEnabled(false); + web_webview.WebCookieManager.putAcceptCookieEnabled(false) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4149,14 +4149,14 @@ isThirdCookieAllowed(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('isThirdPartyCookieAllowed') .onClick(() => { - let result = web_webview.WebCookieManager.isThirdPartyCookieAllowed(); - console.log("result: " + result); + let result = web_webview.WebCookieManager.isThirdPartyCookieAllowed() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4183,13 +4183,13 @@ putAcceptThirdPartyCookieEnabled(accept: boolean): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('putAcceptThirdPartyCookieEnabled') .onClick(() => { - web_webview.WebCookieManager.putAcceptThirdPartyCookieEnabled(false); + web_webview.WebCookieManager.putAcceptThirdPartyCookieEnabled(false) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4216,14 +4216,14 @@ existCookie(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('existCookie') .onClick(() => { - let result = web_webview.WebCookieManager.existCookie(); - console.log("result: " + result); + let result = web_webview.WebCookieManager.existCookie() + console.log("result: " + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4244,13 +4244,13 @@ deleteEntireCookie(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('deleteEntireCookie') .onClick(() => { - web_webview.WebCookieManager.deleteEntireCookie(); + web_webview.WebCookieManager.deleteEntireCookie() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4271,13 +4271,13 @@ deleteSessionCookie(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('deleteSessionCookie') .onClick(() => { - webview.WebCookieManager.deleteSessionCookie(); + webview.WebCookieManager.deleteSessionCookie() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4308,14 +4308,14 @@ static existHttpAuthCredentials(): boolean @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('existHttpAuthCredentials') .onClick(() => { - let result = web_webview.WebDataBase.existHttpAuthCredentials(); - console.log('result: ' + result); + let result = web_webview.WebDataBase.existHttpAuthCredentials() + console.log('result: ' + result) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4337,13 +4337,13 @@ static deleteHttpAuthCredentials(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('deleteHttpAuthCredentials') .onClick(() => { - web_webview.WebDataBase.deleteHttpAuthCredentials(); + web_webview.WebDataBase.deleteHttpAuthCredentials() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4378,18 +4378,18 @@ static getHttpAuthCredentials(host: string, realm: string): Array\ @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - host: string = "www.spincast.org"; - realm: string = "protected example"; - username_password: string[]; + controller: WebController = new WebController() + host: string = "www.spincast.org" + realm: string = "protected example" + username_password: string[] build() { Column() { Button('getHttpAuthCredentials') .onClick(() => { - this.username_password = web_webview.WebDataBase.getHttpAuthCredentials(this.host, this.realm); - console.log('num: ' + this.username_password.length); + this.username_password = web_webview.WebDataBase.getHttpAuthCredentials(this.host, this.realm) + console.log('num: ' + this.username_password.length) ForEach(this.username_password, (item) => { - console.log('username_password: ' + item); + console.log('username_password: ' + item) }, item => item) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -4421,14 +4421,14 @@ static saveHttpAuthCredentials(host: string, realm: string, username: string, pa @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - host: string = "www.spincast.org"; - realm: string = "protected example"; + controller: WebController = new WebController() + host: string = "www.spincast.org" + realm: string = "protected example" build() { Column() { Button('saveHttpAuthCredentials') .onClick(() => { - web_webview.WebDataBase.saveHttpAuthCredentials(this.host, this.realm, "Stromgol", "Laroche"); + web_webview.WebDataBase.saveHttpAuthCredentials(this.host, this.realm, "Stromgol", "Laroche") }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4456,17 +4456,17 @@ static allowGeolocation(origin: string): void ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "file:///"; + controller: WebController = new WebController() + origin: string = "file:///" build() { Column() { Button('allowGeolocation') .onClick(() => { - web_webview.GeolocationPermissions.allowGeolocation(this.origin); + web_webview.GeolocationPermissions.allowGeolocation(this.origin) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4490,17 +4490,17 @@ static deleteGeolocation(origin: string): void ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "file:///"; + controller: WebController = new WebController() + origin: string = "file:///" build() { Column() { Button('deleteGeolocation') .onClick(() => { - web_webview.GeolocationPermissions.deleteGeolocation(this.origin); + web_webview.GeolocationPermissions.deleteGeolocation(this.origin) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4518,16 +4518,16 @@ static deleteAllGeolocation(): void ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('deleteAllGeolocation') .onClick(() => { - web_webview.GeolocationPermissions.deleteAllGeolocation(); + web_webview.GeolocationPermissions.deleteAllGeolocation() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4552,23 +4552,23 @@ static getAccessibleGeolocation(origin: string, callback: AsyncCallback\ { web_webview.GeolocationPermissions.getAccessibleGeolocation(this.origin, (error, result) => { if (error) { - console.log('getAccessibleGeolocationAsync error: ' + JSON.stringify(error)); - return; + console.log('getAccessibleGeolocationAsync error: ' + JSON.stringify(error)) + return } - console.log('getAccessibleGeolocationAsync result: ' + result); - }); + console.log('getAccessibleGeolocationAsync result: ' + result) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4598,21 +4598,21 @@ static getAccessibleGeolocation(origin: string): Promise\ ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "file:///"; + controller: WebController = new WebController() + origin: string = "file:///" build() { Column() { Button('getAccessibleGeolocationPromise') .onClick(() => { web_webview.GeolocationPermissions.getAccessibleGeolocation(this.origin).then(result => { - console.log('getAccessibleGeolocationPromise result: ' + result); + console.log('getAccessibleGeolocationPromise result: ' + result) }).catch(error => { - console.log('getAccessibleGeolocationPromise error: ' + JSON.stringify(error)); - }); + console.log('getAccessibleGeolocationPromise error: ' + JSON.stringify(error)) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4636,23 +4636,23 @@ static getStoredGeolocation(callback: AsyncCallback\\>): void ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getStoredGeolocationAsync') .onClick(() => { web_webview.GeolocationPermissions.getStoredGeolocation((error, origins) => { if (error) { - console.log('getStoredGeolocationAsync error: ' + JSON.stringify(error)); - return; + console.log('getStoredGeolocationAsync error: ' + JSON.stringify(error)) + return } - let origins_str: string = origins.join(); - console.log('getStoredGeolocationAsync origins: ' + origins_str); - }); + let origins_str: string = origins.join() + console.log('getStoredGeolocationAsync origins: ' + origins_str) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4682,21 +4682,21 @@ static getStoredGeolocation(): Promise\\> ```ts // xxx.ets - import web_webview from '@ohos.web.webview'; + import web_webview from '@ohos.web.webview' @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('getStoredGeolocationPromise') .onClick(() => { web_webview.GeolocationPermissions.getStoredGeolocation().then(origins => { - let origins_str: string = origins.join(); - console.log('getStoredGeolocationPromise origins: ' + origins_str); + let origins_str: string = origins.join() + console.log('getStoredGeolocationPromise origins: ' + origins_str) }).catch(error => { - console.log('getStoredGeolocationPromise error: ' + JSON.stringify(error)); - }); + console.log('getStoredGeolocationPromise error: ' + JSON.stringify(error)) + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -4719,12 +4719,12 @@ static deleteAllData(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('deleteAllData') .onClick(() => { - web_webview.WebStorage.deleteAllData(); + web_webview.WebStorage.deleteAllData() }) Web({ src: 'www.example.com', controller: this.controller }) .databaseAccess(true) @@ -4752,13 +4752,13 @@ static deleteOrigin(origin : string): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "origin"; + controller: WebController = new WebController() + origin: string = "origin" build() { Column() { Button('getHttpAuthCredentials') .onClick(() => { - web_webview.WebStorage.deleteOrigin(this.origin); + web_webview.WebStorage.deleteOrigin(this.origin) }) Web({ src: 'www.example.com', controller: this.controller }) .databaseAccess(true) @@ -4786,21 +4786,21 @@ static getOrigins(callback: AsyncCallback\>) : void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "origin"; + controller: WebController = new WebController() + origin: string = "origin" build() { Column() { Button('getOrigins') .onClick(() => { web_webview.WebStorage.getOrigins((error, origins) => { if (error) { - console.log('error: ' + error); - return; + console.log('error: ' + error) + return } for (let i = 0; i < origins.length; i++) { - console.log('origin: ' + origins[i].origin); - console.log('usage: ' + origins[i].usage); - console.log('quota: ' + origins[i].quota); + console.log('origin: ' + origins[i].origin) + console.log('usage: ' + origins[i].usage) + console.log('quota: ' + origins[i].quota) } }) }) @@ -4830,8 +4830,8 @@ static getOrigins() : Promise\> @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "origin"; + controller: WebController = new WebController() + origin: string = "origin" build() { Column() { Button('getOrigins') @@ -4839,13 +4839,13 @@ static getOrigins() : Promise\> web_webview.WebStorage.getOrigins() .then(origins => { for (let i = 0; i < origins.length; i++) { - console.log('origin: ' + origins[i].origin); - console.log('usage: ' + origins[i].usage); - console.log('quota: ' + origins[i].quota); + console.log('origin: ' + origins[i].origin) + console.log('usage: ' + origins[i].usage) + console.log('quota: ' + origins[i].quota) } }) .catch(error => { - console.log('error: ' + error); + console.log('error: ' + error) }) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -4875,18 +4875,18 @@ static getOriginQuota(origin : string, callback : AsyncCallback\) : void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - origin: string = "origin"; + controller: WebController = new WebController() + origin: string = "origin" build() { Column() { Button('getOriginQuota') .onClick(() => { web_webview.WebStorage.getOriginQuota(this.origin, (error, quota) => { if (error) { - console.log('error: ' + error); - return; + console.log('error: ' + error) + return } - console.log('quota: ' + quota); + console.log('quota: ' + quota) }) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -4922,17 +4922,17 @@ static getOriginQuota(origin : string) : Promise\ @Component struct WebComponent { controller: WebController = new WebController(); - origin: string = "origin"; + origin: string = "origin" build() { Column() { Button('getOriginQuota') .onClick(() => { web_webview.WebStorage.getOriginQuota(this.origin) .then(quota => { - console.log('quota: ' + quota); + console.log('quota: ' + quota) }) .catch(error => { - console.log('error: ' + error); + console.log('error: ' + error) }) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -4963,17 +4963,17 @@ static getOriginUsage(origin : string, callback : AsyncCallback\) : void @Component struct WebComponent { controller: WebController = new WebController(); - origin: string = "origin"; + origin: string = "origin" build() { Column() { Button('getOriginUsage') .onClick(() => { web_webview.WebStorage.getOriginUsage(this.origin, (error, usage) => { if (error) { - console.log('error: ' + error); - return; + console.log('error: ' + error) + return } - console.log('usage: ' + usage); + console.log('usage: ' + usage) }) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -5009,17 +5009,17 @@ static getOriginUsage(origin : string) : Promise\ @Component struct WebComponent { controller: WebController = new WebController(); - origin: string = "origin"; + origin: string = "origin" build() { Column() { Button('getOriginQuota') .onClick(() => { web_webview.WebStorage.getOriginUsage(this.origin) .then(usage => { - console.log('usage: ' + usage); + console.log('usage: ' + usage) }) .catch(error => { - console.log('error: ' + error); + console.log('error: ' + error) }) }) Web({ src: 'www.example.com', controller: this.controller }) @@ -5047,27 +5047,27 @@ searchAllAsync(searchString: string): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - @State searchString: string = "xxx"; + controller: WebController = new WebController() + @State searchString: string = "xxx" build() { Column() { Button('searchString') .onClick(() => { - this.controller.searchAllAsync(this.searchString); + this.controller.searchAllAsync(this.searchString) }) Button('clearMatches') .onClick(() => { - this.controller.clearMatches(); + this.controller.clearMatches() }) Button('searchNext') .onClick(() => { - this.controller.searchNext(true); + this.controller.searchNext(true) }) Web({ src: 'www.example.com', controller: this.controller }) .onSearchResultReceive(ret => { console.log("on search result receive:" + "[cur]" + ret.activeMatchOrdinal + - "[total]" + ret.numberOfMatches + "[isDone]"+ ret.isDoneCounting); + "[total]" + ret.numberOfMatches + "[isDone]"+ ret.isDoneCounting) }) } } @@ -5087,13 +5087,13 @@ clearMatches(): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('clearMatches') .onClick(() => { - this.controller.clearMatches(); + this.controller.clearMatches() }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -5121,13 +5121,13 @@ searchNext(forward: boolean): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Button('searchNext') .onClick(() => { - this.controller.searchNext(true); + this.controller.searchNext(true) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -5156,14 +5156,14 @@ onSearchResultReceive(callback: (event?: {activeMatchOrdinal: number, numberOfMa @Entry @Component struct WebComponent { - controller: WebController = new WebController(); + controller: WebController = new WebController() build() { Column() { Web({ src: 'www.example.com', controller: this.controller }) .onSearchResultReceive(ret => { console.log("on search result receive:" + "[cur]" + ret.activeMatchOrdinal + - "[total]" + ret.numberOfMatches + "[isDone]"+ ret.isDoneCounting); + "[total]" + ret.numberOfMatches + "[isDone]"+ ret.isDoneCounting) }) } } @@ -5290,17 +5290,17 @@ storeWebArchive(baseName: string, autoName: boolean, callback: AsyncCallback { - let webAsyncController = new web_webview.WebAsyncController(this.controller); + let webAsyncController = new web_webview.WebAsyncController(this.controller) webAsyncController.storeWebArchive("/data/storage/el2/base/", true, (filename) => { if (filename != null) { console.info(`save web archive success: ${filename}`) } - }); + }) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -5381,16 +5381,16 @@ postMessageEvent(message: WebMessageEvent): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; + controller: WebController = new WebController() + ports: WebMessagePort[] = null build() { Column() { Button('postMessageEvent') .onClick(() => { - var msg = new WebMessageEvent(); - msg.setData("post message from ets to html5"); - this.ports[0].postMessageEvent(msg); + var msg = new WebMessageEvent() + msg.setData("post message from ets to html5") + this.ports[0].postMessageEvent(msg) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -5416,8 +5416,8 @@ onMessageEvent(callback: (result: string) => void): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; + controller: WebController = new WebController() + ports: WebMessagePort[] = null build() { Column() { @@ -5461,9 +5461,9 @@ getData(): string Button('getPorts') .onClick(() => { var msgEvent = new WebMessageEvent(); - msgEvent.setData("message event data"); - var messageData = msgEvent.getData(); - console.log("message is:" + messageData); + msgEvent.setData("message event data") + var messageData = msgEvent.getData() + console.log("message is:" + messageData) }) } } @@ -5488,16 +5488,16 @@ setData(data: string): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; + controller: WebController = new WebController() + ports: WebMessagePort[] = null build() { Column() { Button('setData') .onClick(() => { - var msg = new WebMessageEvent(); - msg.setData("post message from ets to HTML5"); - this.ports[0].postMessageEvent(msg); + var msg = new WebMessageEvent() + msg.setData("post message from ets to HTML5") + this.ports[0].postMessageEvent(msg) }) Web({ src: 'www.example.com', controller: this.controller }) } @@ -5522,16 +5522,16 @@ getPorts(): Array\ @Entry @Component struct WebComponent { - ports: WebMessagePort[] = null; + ports: WebMessagePort[] = null build() { Column() { Button('getPorts') .onClick(() => { - var sendPortArray = new Array(this.ports[0]); - var msgEvent = new WebMessageEvent(); - msgEvent.setPorts(sendPortArray); - var getPorts = msgEvent.getPorts(); - console.log("Ports is:" + getPorts); + var sendPortArray = new Array(this.ports[0]) + var msgEvent = new WebMessageEvent() + msgEvent.setPorts(sendPortArray) + var getPorts = msgEvent.getPorts() + console.log("Ports is:" + getPorts) }) } } @@ -5556,18 +5556,18 @@ setPorts(ports: Array\): void @Entry @Component struct WebComponent { - controller: WebController = new WebController(); - ports: WebMessagePort[] = null; + controller: WebController = new WebController() + ports: WebMessagePort[] = null build() { Column() { Button('setPorts') .onClick(() => { - var sendPortArray = new Array(this.ports[1]); - var msgEvent = new WebMessageEvent(); - msgEvent.setData("__init_ports__"); - msgEvent.setPorts(sendPortArray); - this.controller.postMessage({message: msgEvent, uri: "*"}); + var sendPortArray = new Array(this.ports[1]) + var msgEvent = new WebMessageEvent() + msgEvent.setData("__init_ports__") + msgEvent.setPorts(sendPortArray) + this.controller.postMessage({message: msgEvent, uri: "*"}) }) Web({ src: 'www.example.com', controller: this.controller }) } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-xcomponent.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-xcomponent.md index a46b23d875209a0e3d4c1102829b4db44c3a542e..e047ed2da951bb898627b9830bdb12737d6ad4c5 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-xcomponent.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-xcomponent.md @@ -107,7 +107,7 @@ getXComponentContext() ```ts // xxx.ets -import camera from '@ohos.multimedia.camera'; +import camera from '@ohos.multimedia.camera' @Entry @Component struct PreviewArea { @@ -122,9 +122,9 @@ struct PreviewArea { }) .onLoad(() => { this.xcomponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080}); - this.surfaceId = this.xcomponentController.getXComponentSurfaceId(); + this.surfaceId = this.xcomponentController.getXComponentSurfaceId() camera.createPreviewOutput(this.surfaceId).then((previewOutput) => { - console.log('Promise returned with the PreviewOutput instance'); + console.log('Promise returned with the PreviewOutput instance') }) }) .width('640px') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-longpressgesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-longpressgesture.md index 3afc63f5d272ee02dd2d8fbea1b9e45144bd4d2e..1073d8738dbf000826b4a9ab70ef4dcda1079bf5 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-longpressgesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-longpressgesture.md @@ -36,7 +36,7 @@ LongPressGesture(value?: { fingers?: number, repeat?: boolean, duration?: number @Entry @Component struct LongPressGestureExample { - @State count: number = 0; + @State count: number = 0 build() { Column() { @@ -47,12 +47,12 @@ struct LongPressGestureExample { // 由于repeat设置为true,长按动作存在时会连续触发,触发间隔为duration(默认值500ms) .onAction((event: GestureEvent) => { if (event.repeat) { - this.count++; + this.count++ } }) // 长按动作一结束触发 .onActionEnd(() => { - this.count = 0; + this.count = 0 }) ) } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md index 0ed73fb6fbf0ea42b8d0343791b18f374f94b88e..d52be4b42cf43deaf76502b419e26a36fa63694e 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md @@ -75,11 +75,11 @@ PanGestureOptions(value?: { fingers?: number; direction?: PanDirection; distance @Entry @Component struct PanGestureExample { - @State offsetX: number = 0; - @State offsetY: number = 0; - @State positionX: number = 0; - @State positionY: number = 0; - private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Left | PanDirection.Right }); + @State offsetX: number = 0 + @State offsetY: number = 0 + @State positionX: number = 0 + @State positionY: number = 0 + private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Left | PanDirection.Right }) build() { Column() { @@ -96,24 +96,24 @@ struct PanGestureExample { .gesture( PanGesture(this.panOption) .onActionStart((event: GestureEvent) => { - console.info('Pan start'); + console.info('Pan start') }) .onActionUpdate((event: GestureEvent) => { - this.offsetX = this.positionX + event.offsetX; - this.offsetY = this.positionY + event.offsetY; + this.offsetX = this.positionX + event.offsetX + this.offsetY = this.positionY + event.offsetY }) .onActionEnd(() => { - this.positionX = this.offsetX; - this.positionY = this.offsetY; - console.info('Pan end'); + this.positionX = this.offsetX + this.positionY = this.offsetY + console.info('Pan end') }) ) Button('修改PanGesture触发条件') .onClick(() => { // 将PanGesture手势事件触发条件改为双指以任意方向拖动 - this.panOption.setDirection(PanDirection.All); - this.panOption.setFingers(2); + this.panOption.setDirection(PanDirection.All) + this.panOption.setFingers(2) }) } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pinchgesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pinchgesture.md index 4de9579ea246c83950967a078c48cb10e223bfcf..59a11311a2beb9e089a1a1f8e7d491f810c3f84f 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pinchgesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pinchgesture.md @@ -36,10 +36,10 @@ PinchGesture(value?: { fingers?: number, distance?: number }) @Entry @Component struct PinchGestureExample { - @State scaleValue: number = 1; - @State pinchValue: number = 1; - @State pinchX: number = 0; - @State pinchY: number = 0; + @State scaleValue: number = 1 + @State pinchValue: number = 1 + @State pinchX: number = 0 + @State pinchY: number = 0 build() { Column() { @@ -57,16 +57,16 @@ struct PinchGestureExample { .gesture( PinchGesture({ fingers: 3 }) .onActionStart((event: GestureEvent) => { - console.info('Pinch start'); + console.info('Pinch start') }) .onActionUpdate((event: GestureEvent) => { - this.scaleValue = this.pinchValue * event.scale; - this.pinchX = event.pinchCenterX; - this.pinchY = event.pinchCenterY; + this.scaleValue = this.pinchValue * event.scale + this.pinchX = event.pinchCenterX + this.pinchY = event.pinchCenterY }) .onActionEnd(() => { - this.pinchValue = this.scaleValue; - console.info('Pinch end'); + this.pinchValue = this.scaleValue + console.info('Pinch end') }) ) }.width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-rotationgesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-rotationgesture.md index 35d0bf0f5dac4a4c7cfd34adffa646be1c995ea2..3c4a56b76cf7c8d7866566b80a38af8be0587f0f 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-rotationgesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-rotationgesture.md @@ -36,8 +36,8 @@ RotationGesture(value?: { fingers?: number, angle?: number }) @Entry @Component struct RotationGestureExample { - @State angle: number = 0; - @State rotateValue: number = 0; + @State angle: number = 0 + @State rotateValue: number = 0 build() { Column() { @@ -54,14 +54,14 @@ struct RotationGestureExample { .gesture( RotationGesture() .onActionStart((event: GestureEvent) => { - console.info('Rotation start'); + console.info('Rotation start') }) .onActionUpdate((event: GestureEvent) => { - this.angle = this.rotateValue + event.angle; + this.angle = this.rotateValue + event.angle }) .onActionEnd(() => { - this.rotateValue = this.angle; - console.info('Rotation end'); + this.rotateValue = this.angle + console.info('Rotation end') }) ) }.width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-swipegesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-swipegesture.md index 7e5706a19f443340a02512f055539332cd6f3e8c..6a2daf6dff7daad928caefbb6e2ed4aa32f3c5a9 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-swipegesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-swipegesture.md @@ -42,8 +42,8 @@ SwipeGesture(value?: { fingers?: number; direction?: SwipeDirection; speed?: num @Entry @Component struct SwipeGestureExample { - @State rotateAngle: number = 0; - @State speed: number = 1; + @State rotateAngle: number = 0 + @State speed: number = 1 build() { Column() { @@ -60,8 +60,8 @@ struct SwipeGestureExample { .gesture( SwipeGesture({ direction: SwipeDirection.Vertical }) .onAction((event: GestureEvent) => { - this.speed = event.speed; - this.rotateAngle = event.angle; + this.speed = event.speed + this.rotateAngle = event.angle }) ) }.width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md index d71847aebda3c1dadd06d24f135060bd3faff079..0bc8ae2307857deca73d21c02c55a1be8f53c17f 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md @@ -33,7 +33,7 @@ TapGesture(value?: { count?: number, fingers?: number }) @Entry @Component struct TapGestureExample { - @State value: string = ''; + @State value: string = '' build() { Column() { @@ -42,7 +42,7 @@ struct TapGestureExample { .gesture( TapGesture({ count: 2 }) .onAction((event: GestureEvent) => { - this.value = JSON.stringify(event.fingerList[0]); + this.value = JSON.stringify(event.fingerList[0]) }) ) Text(this.value) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md b/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md index 40a3f6611fba38b4e552c80c95246e8ec951c5cc..b9efef870d9d5be85079e46c3f4b9c9624652212 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md @@ -34,25 +34,25 @@ RenderingContextSettings(antialias?: boolean) ## 属性 -| 名称 | 类型 | 描述 | -| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| [fillStyle](#fillstyle) | string \| [CanvasGradient](ts-components-canvas-canvasgradient.md) \| [CanvasPattern](#canvaspattern) | 指定绘制的填充色。
- 类型为string时,表示设置填充区域的颜色。
- 类型为CanvasGradient时,表示渐变对象,使用[createLinearGradient](#createlineargradient)方法创建。
- 类型为CanvasPattern时,使用[createPattern](#createpattern)方法创建。 | -| [lineWidth](#linewidth) | number | 设置绘制线条的宽度。 | -| [strokeStyle](#strokestyle) | string \| [CanvasGradient](ts-components-canvas-canvasgradient.md) \| [CanvasPattern](#canvaspattern) | 设置描边的颜色。
- 类型为string时,表示设置描边使用的颜色。
- 类型为CanvasGradient时,表示渐变对象,使用[createLinearGradient](#createlineargradient)方法创建。
- 类型为CanvasPattern时,使用[createPattern](#createpattern)方法创建。 | -| [lineCap](#linecap) | CanvasLineCap | 指定线端点的样式,可选值为:
- 'butt':线端点以方形结束。
- 'round':线端点以圆形结束。
- 'square':线端点以方形结束,该样式下会增加一个长度和线段厚度相同,宽度是线段厚度一半的矩形。
默认值:'butt'。 | -| [lineJoin](#linejoin) | CanvasLineJoin | 指定线段间相交的交点样式,可选值为:
- 'round':在线段相连处绘制一个扇形,扇形的圆角半径是线段的宽度。
- 'bevel':在线段相连处使用三角形为底填充, 每个部分矩形拐角独立。
- 'miter':在相连部分的外边缘处进行延伸,使其相交于一点,形成一个菱形区域,该属性可以通过设置miterLimit属性展现效果。
默认值:'miter'。 | -| [miterLimit](#miterlimit) | number | 设置斜接面限制值,该值指定了线条相交处内角和外角的距离。
默认值:10。 | -| [font](#font) | string | 设置文本绘制中的字体样式。
语法:ctx.font='font-size font-family'
- font-size(可选),指定字号和行高,单位只支持px。
- font-family(可选),指定字体系列。
语法:ctx.font='font-style font-weight font-size font-family'
- font-style(可选),用于指定字体样式,支持如下几种样式:'normal','italic'。
- font-weight(可选),用于指定字体的粗细,支持如下几种类型:'normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900。
- font-size(可选),指定字号和行高,单位只支持px。
- font-family(可选),指定字体系列,支持如下几种类型:'sans-serif', 'serif', 'monospace'。
默认值:'normal normal 14px sans-serif'。 | -| [textAlign](#textalign) | CanvasTextAlign | 设置文本绘制中的文本对齐方式,可选值为:
- 'left':文本左对齐。
- 'right':文本右对齐。
- 'center':文本居中对齐。
- 'start':文本对齐界线开始的地方。
- 'end':文本对齐界线结束的地方。
ltr布局模式下'start'和'left'一致,rtl布局模式下'start'和'right'一致·。
默认值:'left'。 | -| [textBaseline](#textbaseline) | CanvasTextBaseline | 设置文本绘制中的水平对齐方式,可选值为:
- 'alphabetic':文本基线是标准的字母基线。
- 'top':文本基线在文本块的顶部。
- 'hanging':文本基线是悬挂基线。
- 'middle':文本基线在文本块的中间。
- 'ideographic':文字基线是表意字基线;如果字符本身超出了alphabetic基线,那么ideograhpic基线位置在字符本身的底部。
- 'bottom':文本基线在文本块的底部。 与ideographic基线的区别在于ideographic基线不需要考虑下行字母。
默认值:'alphabetic'。 | -| [globalAlpha](#globalalpha) | number | 设置透明度,0.0为完全透明,1.0为完全不透明。 | -| [lineDashOffset](#linedashoffset) | number | 设置画布的虚线偏移量,精度为float。
默认值:0.0。 | -| [globalCompositeOperation](#globalcompositeoperation) | string | 设置合成操作的方式。类型字段可选值有'source-over','source-atop','source-in','source-out','destination-over','destination-atop','destination-in','destination-out','lighter','copy','xor'。
默认值:'source-over'。 | -| [shadowBlur](#shadowblur) | number | 设置绘制阴影时的模糊级别,值越大越模糊,精度为float。
默认值:0.0。 | -| [shadowColor](#shadowcolor) | string | 设置绘制阴影时的阴影颜色。 | -| [shadowOffsetX](#shadowoffsetx) | number | 设置绘制阴影时和原有对象的水平偏移值。 | -| [shadowOffsetY](#shadowoffsety) | number | 设置绘制阴影时和原有对象的垂直偏移值。 | -| [imageSmoothingEnabled](#imagesmoothingenabled) | boolean | 用于设置绘制图片时是否进行图像平滑度调整,true为启用,false为不启用。
默认值:true。 | +| 名称 | 类型 | 描述 | +| ----------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| [fillStyle](#fillstyle) | string \| [CanvasGradient](ts-components-canvas-canvasgradient.md) \| [CanvasPattern](#canvaspattern) | 指定绘制的填充色。
- 类型为string时,表示设置填充区域的颜色。
- 类型为CanvasGradient时,表示渐变对象,使用[createLinearGradient](#createlineargradient)方法创建。
- 类型为CanvasPattern时,使用[createPattern](#createpattern)方法创建。 | +| [lineWidth](#linewidth) | number | 设置绘制线条的宽度。 | +| [strokeStyle](#strokestyle) | string \| [CanvasGradient](ts-components-canvas-canvasgradient.md) \| [CanvasPattern](#canvaspattern) | 设置描边的颜色。
- 类型为string时,表示设置描边使用的颜色。
- 类型为CanvasGradient时,表示渐变对象,使用[createLinearGradient](#createlineargradient)方法创建。
- 类型为CanvasPattern时,使用[createPattern](#createpattern)方法创建。 | +| [lineCap](#linecap) | CanvasLineCap | 指定线端点的样式,可选值为:
- 'butt':线端点以方形结束。
- 'round':线端点以圆形结束。
- 'square':线端点以方形结束,该样式下会增加一个长度和线段厚度相同,宽度是线段厚度一半的矩形。
默认值:'butt' | +| [lineJoin](#linejoin) | CanvasLineJoin | 指定线段间相交的交点样式,可选值为:
- 'round':在线段相连处绘制一个扇形,扇形的圆角半径是线段的宽度。
- 'bevel':在线段相连处使用三角形为底填充, 每个部分矩形拐角独立。
- 'miter':在相连部分的外边缘处进行延伸,使其相交于一点,形成一个菱形区域,该属性可以通过设置miterLimit属性展现效果。
默认值:'miter' | +| [miterLimit](#miterlimit) | number | 设置斜接面限制值,该值指定了线条相交处内角和外角的距离。
默认值:10 | +| [font](#font) | string | 设置文本绘制中的字体样式。
语法:ctx.font='font-size font-family'
- font-size(可选),指定字号和行高,单位只支持px。
- font-family(可选),指定字体系列。
语法:ctx.font='font-style font-weight font-size font-family'
- font-style(可选),用于指定字体样式,支持如下几种样式:'normal','italic'。
- font-weight(可选),用于指定字体的粗细,支持如下几种类型:'normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900。
- font-size(可选),指定字号和行高,单位只支持px。
- font-family(可选),指定字体系列,支持如下几种类型:'sans-serif', 'serif', 'monospace'。
默认值:'normal normal 14px sans-serif' | +| [textAlign](#textalign) | CanvasTextAlign | 设置文本绘制中的文本对齐方式,可选值为:
- 'left':文本左对齐。
- 'right':文本右对齐。
- 'center':文本居中对齐。
- 'start':文本对齐界线开始的地方。
- 'end':文本对齐界线结束的地方。
ltr布局模式下'start'和'left'一致,rtl布局模式下'start'和'right'一致·。
默认值:'left' | +| [textBaseline](#textbaseline) | CanvasTextBaseline | 设置文本绘制中的水平对齐方式,可选值为:
- 'alphabetic':文本基线是标准的字母基线。
- 'top':文本基线在文本块的顶部。
- 'hanging':文本基线是悬挂基线。
- 'middle':文本基线在文本块的中间。
- 'ideographic':文字基线是表意字基线;如果字符本身超出了alphabetic基线,那么ideograhpic基线位置在字符本身的底部。
- 'bottom':文本基线在文本块的底部。 与ideographic基线的区别在于ideographic基线不需要考虑下行字母。
默认值:'alphabetic' | +| [globalAlpha](#globalalpha) | number | 设置透明度,0.0为完全透明,1.0为完全不透明。 | +| [lineDashOffset](#linedashoffset) | number | 设置画布的虚线偏移量,精度为float。
默认值:0.0 | +| [globalCompositeOperation](#globalcompositeoperation) | string | 设置合成操作的方式。类型字段可选值有'source-over','source-atop','source-in','source-out','destination-over','destination-atop','destination-in','destination-out','lighter','copy','xor'。
默认值:'source-over' | +| [shadowBlur](#shadowblur) | number | 设置绘制阴影时的模糊级别,值越大越模糊,精度为float。
默认值:0.0 | +| [shadowColor](#shadowcolor) | string | 设置绘制阴影时的阴影颜色。 | +| [shadowOffsetX](#shadowoffsetx) | number | 设置绘制阴影时和原有对象的水平偏移值。 | +| [shadowOffsetY](#shadowoffsety) | number | 设置绘制阴影时和原有对象的垂直偏移值。 | +| [imageSmoothingEnabled](#imagesmoothingenabled) | boolean | 用于设置绘制图片时是否进行图像平滑度调整,true为启用,false为不启用。
默认值:true | > **说明:** > @@ -66,8 +66,8 @@ RenderingContextSettings(antialias?: boolean) @Entry @Component struct FillStyleExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -96,8 +96,8 @@ struct FillStyleExample { @Entry @Component struct LineWidthExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -126,8 +126,8 @@ struct LineWidthExample { @Entry @Component struct StrokeStyleExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -158,8 +158,8 @@ struct StrokeStyleExample { @Entry @Component struct LineCapExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -192,8 +192,8 @@ struct LineCapExample { @Entry @Component struct LineJoinExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -227,8 +227,8 @@ struct LineJoinExample { @Entry @Component struct MiterLimit { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -262,8 +262,8 @@ struct MiterLimit { @Entry @Component struct Fonts { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -292,8 +292,8 @@ struct Fonts { @Entry @Component struct CanvasExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -337,8 +337,8 @@ struct CanvasExample { @Entry @Component struct TextBaseline { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -382,8 +382,8 @@ struct TextBaseline { @Entry @Component struct GlobalAlpha { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -415,8 +415,8 @@ struct GlobalAlpha { @Entry @Component struct LineDashOffset { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -427,8 +427,8 @@ struct LineDashOffset { .onReady(() =>{ this.context.arc(100, 75, 50, 0, 6.28) this.context.setLineDash([10,20]) - this.context.lineDashOffset = 10.0; - this.context.stroke(); + this.context.lineDashOffset = 10.0 + this.context.stroke() }) } .width('100%') @@ -461,8 +461,8 @@ struct LineDashOffset { @Entry @Component struct GlobalCompositeOperation { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -499,8 +499,8 @@ struct GlobalCompositeOperation { @Entry @Component struct ShadowBlur { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -531,8 +531,8 @@ struct ShadowBlur { @Entry @Component struct ShadowColor { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -563,8 +563,8 @@ struct ShadowColor { @Entry @Component struct ShadowOffsetX { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -596,8 +596,8 @@ struct ShadowOffsetX { @Entry @Component struct ShadowOffsetY { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Canvas(this.context) @@ -628,9 +628,9 @@ struct ShadowOffsetY { @Entry @Component struct ImageSmoothingEnabled { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); - private img:ImageBitmap = new ImageBitmap("common/images/icon.jpg"); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) + private img:ImageBitmap = new ImageBitmap("common/images/icon.jpg") build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -677,8 +677,8 @@ fillRect(x: number, y: number, w: number, h: number): void @Entry @Component struct FillRect { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -721,8 +721,8 @@ strokeRect(x: number, y: number, w: number, h: number): void @Entry @Component struct StrokeRect { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -765,8 +765,8 @@ clearRect(x: number, y: number, w: number, h: number): void @Entry @Component struct ClearRect { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -797,12 +797,12 @@ fillText(text: string, x: number, y: number, maxWidth?: number): void **参数:** -| 参数 | 类型 | 必填 | 默认值 | 说明 | -| -------- | ------ | ---- | ---- | --------------- | -| text | string | 是 | "" | 需要绘制的文本内容。 | -| x | number | 是 | 0 | 需要绘制的文本的左下角x坐标。 | -| y | number | 是 | 0 | 需要绘制的文本的左下角y坐标。 | -| maxWidth | number | 否 | - | 指定文本允许的最大宽度。 | +| 参数 | 类型 | 必填 | 默认值 | 说明 | +| -------- | ------ | ---- | ------ | ----------------------------- | +| text | string | 是 | '' | 需要绘制的文本内容。 | +| x | number | 是 | 0 | 需要绘制的文本的左下角x坐标。 | +| y | number | 是 | 0 | 需要绘制的文本的左下角y坐标。 | +| maxWidth | number | 否 | - | 指定文本允许的最大宽度。 | **示例:** @@ -811,8 +811,8 @@ fillText(text: string, x: number, y: number, maxWidth?: number): void @Entry @Component struct FillText { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -842,12 +842,12 @@ strokeText(text: string, x: number, y: number, maxWidth?:number): void **参数:** -| 参数 | 类型 | 必填 | 默认值 | 描述 | -| -------- | ------ | ---- | ---- | --------------- | -| text | string | 是 | “” | 需要绘制的文本内容。 | -| x | number | 是 | 0 | 需要绘制的文本的左下角x坐标。 | -| y | number | 是 | 0 | 需要绘制的文本的左下角y坐标。 | -| maxWidth | number | 否 | - | 需要绘制的文本的最大宽度 。 | +| 参数 | 类型 | 必填 | 默认值 | 描述 | +| -------- | ------ | ---- | ------ | ----------------------------- | +| text | string | 是 | '' | 需要绘制的文本内容。 | +| x | number | 是 | 0 | 需要绘制的文本的左下角x坐标。 | +| y | number | 是 | 0 | 需要绘制的文本的左下角y坐标。 | +| maxWidth | number | 否 | - | 需要绘制的文本的最大宽度 。 | **示例:** @@ -856,8 +856,8 @@ strokeText(text: string, x: number, y: number, maxWidth?:number): void @Entry @Component struct StrokeText { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -887,15 +887,15 @@ measureText(text: string): TextMetrics **参数:** -| 参数 | 类型 | 必填 | 默认值 | 说明 | -| ---- | ------ | ---- | ---- | ---------- | -| text | string | 是 | "" | 需要进行测量的文本。 | +| 参数 | 类型 | 必填 | 默认值 | 说明 | +| ---- | ------ | ---- | ------ | -------------------- | +| text | string | 是 | '' | 需要进行测量的文本。 | **返回值:** -| 类型 | 说明 | -| ----------- | ------- | -| TextMetrics | 文本的尺寸信息 | +| 类型 | 说明 | +| ----------- | ---------------- | +| TextMetrics | 文本的尺寸信息。 | **TextMetrics类型描述:** @@ -925,8 +925,8 @@ measureText(text: string): TextMetrics @Entry @Component struct MeasureText { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -968,8 +968,8 @@ stroke(path?: Path2D): void @Entry @Component struct Stroke { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1008,8 +1008,8 @@ beginPath(): void @Entry @Component struct BeginPath { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1055,8 +1055,8 @@ moveTo(x: number, y: number): void @Entry @Component struct MoveTo { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1100,8 +1100,8 @@ lineTo(x: number, y: number): void @Entry @Component struct LineTo { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1138,8 +1138,8 @@ closePath(): void @Entry @Component struct ClosePath { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1173,10 +1173,10 @@ createPattern(image: ImageBitmap, repetition: string | null): CanvasPattern | nu **参数:** -| 参数 | 类型 | 必填 | 默认值 | 描述 | -| ---------- | ---------------------------------------- | ---- | ---- | ---------------------------------------- | -| image | [ImageBitmap](ts-components-canvas-imagebitmap.md) | 是 | null | 图源对象,具体参考ImageBitmap对象。 | -| repetition | string | 是 | “” | 设置图像重复的方式,取值为:'repeat'、'repeat-x'、 'repeat-y'、'no-repeat'。 | +| 参数 | 类型 | 必填 | 描述 | +| ---------- | -------------------------------------------------- | ---- | ------------------------------------------------------------ | +| image | [ImageBitmap](ts-components-canvas-imagebitmap.md) | 是 | 图源对象,具体参考ImageBitmap对象。 | +| repetition | string | 是 | 设置图像重复的方式,取值为:'repeat'、'repeat-x'、 'repeat-y'、'no-repeat'。
默认值:'' | **返回值:**: @@ -1191,9 +1191,9 @@ createPattern(image: ImageBitmap, repetition: string | null): CanvasPattern | nu @Entry @Component struct CreatePattern { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); - private img:ImageBitmap = new ImageBitmap("common/images/icon.jpg"); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) + private img:ImageBitmap = new ImageBitmap("common/images/icon.jpg") build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1240,8 +1240,8 @@ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, @Entry @Component struct BezierCurveTo { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1287,8 +1287,8 @@ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void @Entry @Component struct QuadraticCurveTo { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1297,10 +1297,10 @@ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.beginPath(); - this.context.moveTo(20, 20); - this.context.quadraticCurveTo(100, 100, 200, 20); - this.context.stroke(); + this.context.beginPath() + this.context.moveTo(20, 20) + this.context.quadraticCurveTo(100, 100, 200, 20) + this.context.stroke() }) } .width('100%') @@ -1336,8 +1336,8 @@ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, @Entry @Component struct Arc { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1383,8 +1383,8 @@ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void @Entry @Component struct ArcTo { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1393,9 +1393,9 @@ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.moveTo(100, 20); - this.context.arcTo(150, 20, 150, 70, 50); - this.context.stroke(); + this.context.moveTo(100, 20) + this.context.arcTo(150, 20, 150, 70, 50) + this.context.stroke() }) } .width('100%') @@ -1433,8 +1433,8 @@ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number @Entry @Component struct CanvasExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1479,8 +1479,8 @@ rect(x: number, y: number, w: number, h: number): void @Entry @Component struct CanvasExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1522,8 +1522,8 @@ fill(fillRule?: CanvasFillRule): void @Entry @Component struct Fill { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1574,17 +1574,17 @@ struct Fill { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - let region = new Path2D(); - region.moveTo(30, 90); - region.lineTo(110, 20); - region.lineTo(240, 130); - region.lineTo(60, 130); - region.lineTo(190, 20); - region.lineTo(270, 90); - region.closePath(); + let region = new Path2D() + region.moveTo(30, 90) + region.lineTo(110, 20) + region.lineTo(240, 130) + region.lineTo(60, 130) + region.lineTo(190, 20) + region.lineTo(270, 90) + region.closePath() // Fill path - this.context.fillStyle = 'green'; - this.context.fill(region, "evenodd"); + this.context.fillStyle = 'green' + this.context.fill(region, "evenodd") }) } .width('100%') @@ -1615,8 +1615,8 @@ clip(fillRule?: CanvasFillRule): void @Entry @Component struct Clip { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1669,9 +1669,9 @@ struct Clip { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - let region = new Path2D(); - region.rect(80,10,20,130); - region.rect(40,50,100,50); + let region = new Path2D() + region.rect(80,10,20,130) + region.rect(40,50,100,50) this.context.clip(region,"evenodd") this.context.fillStyle = "rgb(255,0,0)" this.context.fillRect(0, 0, this.context.width, this.context.height) @@ -1739,8 +1739,8 @@ rotate(angle: number): void @Entry @Component struct Rotate { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1782,8 +1782,8 @@ scale(x: number, y: number): void @Entry @Component struct Scale { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1838,8 +1838,8 @@ transform方法对应一个变换矩阵,想对一个图形进行变化的时 @Entry @Component struct Transform { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1891,8 +1891,8 @@ setTransform方法使用的参数和transform()方法相同,但setTransform() @Entry @Component struct SetTransform { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1942,8 +1942,8 @@ translate(x: number, y: number): void @Entry @Component struct Translate { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -1998,9 +1998,9 @@ drawImage(image: ImageBitmap | PixelMap, sx: number, sy: number, sw: number, sh: @Entry @Component struct ImageExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); - private img:ImageBitmap = new ImageBitmap("common/images/example.jpg"); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) + private img:ImageBitmap = new ImageBitmap("common/images/example.jpg") build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -2009,7 +2009,7 @@ drawImage(image: ImageBitmap | PixelMap, sx: number, sy: number, sw: number, sh: .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.drawImage( this.img,0,0,500,500,0,0,400,200); + this.context.drawImage( this.img,0,0,500,500,0,0,400,200) }) } .width('100%') @@ -2102,8 +2102,8 @@ getImageData(sx: number, sy: number, sw: number, sh: number): ImageData @Entry @Component struct GetImageData { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) private img:ImageBitmap = new ImageBitmap("/common/images/1234.png") build() { @@ -2113,9 +2113,9 @@ struct GetImageData { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.drawImage(this.img,0,0,130,130); - var imagedata = this.context.getImageData(50,50,130,130); - this.context.putImageData(imagedata,150,150); + this.context.drawImage(this.img,0,0,130,130) + var imagedata = this.context.getImageData(50,50,130,130) + this.context.putImageData(imagedata,150,150) }) } .width('100%') @@ -2154,8 +2154,8 @@ putImageData(imageData: ImageData, dx: number, dy: number, dirtyX: number, dirty @Entry @Component struct PutImageData { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -2268,7 +2268,7 @@ struct CanvasGetLineDash { .onReady(() => { this.context.arc(100, 75, 50, 0, 6.28) this.context.setLineDash([10,20]) - this.context.stroke(); + this.context.stroke() let res = this.context.getLineDash() }) } @@ -2382,7 +2382,7 @@ struct ToDataURL { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - var dataURL = this.context.toDataURL(); + var dataURL = this.context.toDataURL() }) } .width('100%') @@ -2405,8 +2405,8 @@ restore(): void @Entry @Component struct CanvasExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -2415,11 +2415,11 @@ restore(): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.save(); // save the default state - this.context.fillStyle = "green"; - this.context.fillRect(20, 20, 100, 100); - this.context.restore(); // restore to the default state - this.context.fillRect(150, 75, 100, 100); + this.context.save() // save the default state + this.context.fillStyle = "green" + this.context.fillRect(20, 20, 100, 100) + this.context.restore() // restore to the default state + this.context.fillRect(150, 75, 100, 100) }) } .width('100%') @@ -2443,8 +2443,8 @@ save(): void @Entry @Component struct CanvasExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -2453,11 +2453,11 @@ save(): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.save(); // save the default state - this.context.fillStyle = "green"; - this.context.fillRect(20, 20, 100, 100); - this.context.restore(); // restore to the default state - this.context.fillRect(150, 75, 100, 100); + this.context.save() // save the default state + this.context.fillStyle = "green" + this.context.fillRect(20, 20, 100, 100) + this.context.restore() // restore to the default state + this.context.fillRect(150, 75, 100, 100) }) } .width('100%') @@ -2490,8 +2490,8 @@ createLinearGradient(x0: number, y0: number, x1: number, y1: number): void @Entry @Component struct CreateLinearGradient { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -2541,8 +2541,8 @@ createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, @Entry @Component struct CreateRadialGradient { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-combined-gestures.md b/zh-cn/application-dev/reference/arkui-ts/ts-combined-gestures.md index 583aa6775a1a807995a5d3c2e9628c8dfb8fae77..ec9d2e8021068ffde8cf932df2ca0fea5612f381 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-combined-gestures.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-combined-gestures.md @@ -39,12 +39,12 @@ GestureGroup(mode: GestureMode, ...gesture: GestureType[]) @Entry @Component struct GestureGroupExample { - @State count: number = 0; - @State offsetX: number = 0; - @State offsetY: number = 0; - @State positionX: number = 0; - @State positionY: number = 0; - @State borderStyles: BorderStyle = BorderStyle.Solid; + @State count: number = 0 + @State offsetX: number = 0 + @State offsetY: number = 0 + @State positionX: number = 0 + @State positionY: number = 0 + @State borderStyles: BorderStyle = BorderStyle.Solid build() { Column() { @@ -57,37 +57,37 @@ struct GestureGroupExample { .margin(20) .border({ width: 3, style: this.borderStyles }) .gesture( - //以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件 + // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件 GestureGroup(GestureMode.Sequence, LongPressGesture({ repeat: true }) .onAction((event: GestureEvent) => { if (event.repeat) { - this.count++; + this.count++ } - console.info('LongPress onAction'); + console.info('LongPress onAction') }) .onActionEnd(() => { - console.info('LongPress end'); + console.info('LongPress end') }), PanGesture() .onActionStart(() => { - this.borderStyles = BorderStyle.Dashed; - console.info('pan start'); + this.borderStyles = BorderStyle.Dashed + console.info('pan start') }) .onActionUpdate((event: GestureEvent) => { - this.offsetX = this.positionX + event.offsetX; - this.offsetY = this.positionY + event.offsetY; - console.info('pan update'); + this.offsetX = this.positionX + event.offsetX + this.offsetY = this.positionY + event.offsetY + console.info('pan update') }) .onActionEnd(() => { - this.positionX = this.offsetX; - this.positionY = this.offsetY; - this.borderStyles = BorderStyle.Solid; - console.info('pan end'); + this.positionX = this.offsetX + this.positionY = this.offsetY + this.borderStyles = BorderStyle.Solid + console.info('pan end') }) ) .onCancel(() => { - console.info('sequence gesture canceled'); + console.info('sequence gesture canceled') }) ) } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagebitmap.md b/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagebitmap.md index 12063d494b68b2c694ec35090730d4625a81e620..8785206dcef551053042f745837aa8e664757c5d 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagebitmap.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagebitmap.md @@ -10,10 +10,10 @@ ImageBitmap对象可以存储canvas渲染的像素数据。 ## 属性 -| 属性 | 类型 | 描述 | +| 属性 | 类型 | 描述 | | -------- | -------- | -------- | -| width | number | ImageBitmap的像素宽度。 | -| height | number | ImageBitmap的像素高度。 | +| width | number | ImageBitmap的像素宽度。 | +| height | number | ImageBitmap的像素高度。 | **示例:** @@ -22,9 +22,9 @@ ImageBitmap对象可以存储canvas渲染的像素数据。 @Entry @Component struct ImageExample { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); - private img:ImageBitmap = new ImageBitmap("common/images/example.jpg"); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) + private img:ImageBitmap = new ImageBitmap("common/images/example.jpg") build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { @@ -33,7 +33,7 @@ ImageBitmap对象可以存储canvas渲染的像素数据。 .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.drawImage( this.img,0,0,500,500,0,0,400,200); + this.context.drawImage( this.img,0,0,500,500,0,0,400,200) }) } .width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagedata.md b/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagedata.md index 00ca2d47e15d1efc2e71777f11fef69a70e1eeb7..f3dd34c03f3578b435ded7faa34f7d3e01ea65a7 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagedata.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-imagedata.md @@ -10,11 +10,11 @@ ImageData对象可以存储canvas渲染的像素数据。 ## 属性 -| 属性 | 类型 | 描述 | +| 属性 | 类型 | 描述 | | -------- | -------- | -------- | -| width | number | 矩形区域实际像素宽度。 | -| height | number | 矩形区域实际像素高度。 | -| data | Uint8ClampedArray | 一维数组,保存了相应的颜色数据,数据值范围为0到255。 | +| width | number | 矩形区域实际像素宽度。 | +| height | number | 矩形区域实际像素高度。 | +| data | Uint8ClampedArray | 一维数组,保存了相应的颜色数据,数据值范围为0到255。 | **示例:** @@ -23,8 +23,8 @@ ImageData对象可以存储canvas渲染的像素数据。 @Entry @Component struct Translate { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) private img:ImageBitmap = new ImageBitmap("/common/images/1234.png") build() { @@ -34,9 +34,9 @@ struct Translate { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.context.drawImage(this.img,0,0,130,130); - var imagedata = this.context.getImageData(50,50,130,130); - this.context.putImageData(imagedata,150,150); + this.context.drawImage(this.img,0,0,130,130) + var imagedata = this.context.getImageData(50,50,130,130) + this.context.putImageData(imagedata,150,150) }) } .width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-ability-component.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-ability-component.md index 86c6d07bdfa37959bf8e15714ade8ce4786e2c22..086230f8b37b74650ed96120f8daf35916d14f7e 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-ability-component.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-ability-component.md @@ -65,10 +65,10 @@ struct MyComponent { }, }) .onConnect(() => { - console.log('AbilityComponent connect'); + console.log('AbilityComponent connect') }) .onDisconnect(() => { - console.log('AbilityComponent disconnect'); + console.log('AbilityComponent disconnect') }) } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-alphabet-indexer.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-alphabet-indexer.md index 60ea9a024d52626e00e67e5ba4fd7f27ae89043e..b4ba444f881be19c4be8bc5f5a422e3c0f3ec2d2 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-alphabet-indexer.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-alphabet-indexer.md @@ -162,3 +162,4 @@ struct AlphabetIndexerSample { } ``` +![alphabet](figures/alphabet.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-badge.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-badge.md index 7e03805a45bfb67da494a67a7025450c05ffa42f..43487f3c6d291a02fdc8526423500110b6887bc8 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-badge.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-badge.md @@ -61,8 +61,8 @@ @Entry @Component struct BadgeExample { - @State counts: number = 1; - @State message: string = 'new'; + @State counts: number = 1 + @State message: string = 'new' build() { Column() { @@ -77,7 +77,7 @@ struct BadgeExample { }) { Button('message') .onClick(() => { - this.counts++; + this.counts++ }) .width(100).height(50).backgroundColor(0x317aff) }.width(100).height(50) @@ -91,7 +91,7 @@ struct BadgeExample { }) { Button('message') .onClick(() => { - this.counts++; + this.counts++ }) .width(100).height(50).backgroundColor(0x317aff) }.width(100).height(50) @@ -106,7 +106,7 @@ struct BadgeExample { }) { Button('message') .onClick(() => { - this.counts++; + this.counts++ }) .width(100).height(50).backgroundColor(0x317aff) }.width(100).height(50) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-counter.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-counter.md index 27fbd173f704132eb302d27c2191d258761e8533..0628db7cfcfb691e410c71a17e98d5bcb432e0ec 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-counter.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-counter.md @@ -6,10 +6,6 @@ > 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 - - - - ## 子组件 可以包含子组件。 @@ -24,10 +20,10 @@ Counter() 不支持通用事件和手势, 仅支持如下事件: -| 名称 | 功能描述 | +| 名称 | 功能描述 | | -------- | -------- | -| onInc(event: () => void) | 监听数值增加事件。 | -| onDec(event: () => void) | 监听数值减少事件。 | +| onInc(event: () => void) | 监听数值增加事件。 | +| onDec(event: () => void) | 监听数值减少事件。 | ## 示例 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-flex.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-flex.md index 7dbc84e4eb1c0b9cf3e0165503d8e95c8efa3f1a..b04c09c7804046cfdce174a35b9291371f34ffaa 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-flex.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-flex.md @@ -1,10 +1,10 @@ # Flex -应用弹性方式布局子组件的容器组件。 +以弹性方式布局子组件的容器组件。 > **说明:** > - 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 -> - Flex组件在设置flexShrink、flexGrow时存在二次布局过程,因此在对性能有严格要求的场景下建议使用[Column](ts-container-column.md)、[Row](ts-container-row.md)代替。 +> - Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用[Column](ts-container-column.md)、[Row](ts-container-row.md)代替。 ## 权限列表 @@ -148,7 +148,7 @@ struct FlexExample2 { // xxx.ets @Component struct JustifyContentFlex { - @Prop justifyContent : number + justifyContent : number build() { Flex({ justifyContent: this.justifyContent }) { @@ -197,7 +197,7 @@ struct FlexExample3 { // xxx.ets @Component struct AlignItemsFlex { - @Prop alignItems : number + alignItems : number build() { Flex({ alignItems: this.alignItems }) { @@ -246,7 +246,7 @@ struct FlexExample4 { // xxx.ets @Component struct AlignContentFlex { - @Prop alignContent: number + alignContent: number build() { Flex({ wrap: FlexWrap.Wrap, alignContent: this.alignContent }) { diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-list.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-list.md index 70faec26cdd7476b88fc73e4c878f0b4cc888e9a..09544a366d55618f9b6b11f1cf57148ec0983d5a 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-list.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-list.md @@ -183,7 +183,7 @@ struct ListLanesExample { .width("90%") .editMode(true) .border({ width: 3, color: Color.Red }) - .lanes({ minLength: 40, maxLength: 60 }) + .lanes({ minLength: 40, maxLength: 40 }) .alignListItem(this.alignListItem) Button("点击更改alignListItem:" + this.alignListItem).onClick(() => { @@ -200,3 +200,4 @@ struct ListLanesExample { } ``` +![list](figures/list1.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-navigator.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-navigator.md index 59b184476c6458269984d678abb4df476e9b576c..a5c39cd63bb5a4d76bf939a4748781b1187ebace 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-navigator.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-navigator.md @@ -49,21 +49,21 @@ Navigator(value?: {target: string, type?: NavigationType}) @Entry @Component struct NavigatorExample { - @State active: boolean = false; + @State active: boolean = false @State Text: object = {name: 'news'} build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) { Navigator({ target: 'pages/container/navigator/Detail', type: NavigationType.Push }) { Text('Go to ' + this.Text['name'] + ' page') - .width('100%').textAlign(TextAlign.Center) + .width('100%').textAlign(TextAlign.Center) }.params({ text: this.Text }) // 传参数到Detail页面 Navigator() { Text('Back to previous page').width('100%').textAlign(TextAlign.Center) }.active(this.active) .onClick(() => { - this.active = true; + this.active = true }) }.height(150).width(350).padding(35) } @@ -78,7 +78,7 @@ import router from '@ohos.router' @Component struct DetailExample { // 接收Navigator.ets的传参 - @State text: any = router.getParams().text; + @State text: any = router.getParams().text build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) { @@ -87,7 +87,7 @@ struct DetailExample { } Text('This is ' + this.text['name'] + ' page') - .width('100%').textAlign(TextAlign.Center) + .width('100%').textAlign(TextAlign.Center) } .width('100%').height(200).padding({ left: 35, right: 35, top: 35 }) } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-panel.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-panel.md index e567fe57f5126acc77059a759a43469bae1e22fa..ec239c8400514c7e41cb3b5f37cbee6afd6a0fb0 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-panel.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-panel.md @@ -58,7 +58,7 @@ Panel(show: boolean) | 名称 | 功能描述 | | -------- | -------- | | onChange(event: (width: number, height: number, mode: PanelMode) => void) | 当可滑动面板发生状态变化时触发, 返回的height值为内容区高度值,当dragbar属性为true时,panel本身的高度值为dragbar高度加上内容区高度。 | -| onHeightChange(callback: (value: number) => void)9+ |当可滑动面板发生高度变化时触发,返回的height值为内容区高度值,当dragbar属性为true时,panel本身的高度值为dragbar高度加上内容区高度。因用户体验设计原因,panel最高只能滑到 fullHeight-8vp。 | +| onHeightChange(callback: (value: number) => void)9+ |当可滑动面板发生高度变化时触发,返回的height值为内容区高度值,默认返回值单位为px。当dragbar属性为true时,panel本身的高度值为dragbar高度加上内容区高度。因用户体验设计原因,panel最高只能滑到 fullHeight-8vp。 | ## 示例 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-scroll.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-scroll.md index b6e0e30f1490ec2b2a80d57893ee97f41058d19d..305facc51a69b54fe0fe82e8e5b37d1f55a9abe4 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-scroll.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-scroll.md @@ -168,8 +168,8 @@ scrollBy(dx: Length, dy: Length): void @Entry @Component struct ScrollExample { - scroller: Scroller = new Scroller(); - private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + scroller: Scroller = new Scroller() + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] build() { Stack({ alignContent: Alignment.TopStart }) { @@ -193,33 +193,33 @@ struct ScrollExample { .scrollBarWidth(30) // 滚动条宽度 .edgeEffect(EdgeEffect.None) .onScroll((xOffset: number, yOffset: number) => { - console.info(xOffset + ' ' + yOffset); + console.info(xOffset + ' ' + yOffset) }) .onScrollEdge((side: Edge) => { - console.info('To the edge'); + console.info('To the edge') }) .onScrollEnd(() => { - console.info('Scroll Stop'); + console.info('Scroll Stop') }) Button('scroll 150') .onClick(() => { // 点击后下滑指定距离150.0vp - this.scroller.scrollBy(0,150); + this.scroller.scrollBy(0,150) }) .margin({ top: 10, left: 20 }) Button('scroll 100') .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离 - this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 }); + this.scroller.scrollTo({ xOffset: 0, yOffset: this.scroller.currentOffset().yOffset + 100 }) }) .margin({ top: 60, left: 20 }) Button('back top') .onClick(() => { // 点击后回到顶部 - this.scroller.scrollEdge(Edge.Top); + this.scroller.scrollEdge(Edge.Top) }) .margin({ top: 110, left: 20 }) Button('next page') .onClick(() => { // 点击后滑到下一页 - this.scroller.scrollPage({ next: true }); + this.scroller.scrollPage({ next: true }) }) .margin({ top: 170, left: 20 }) }.width('100%').height('100%').backgroundColor(0xDCDCDC) @@ -235,8 +235,8 @@ struct ScrollExample { @Component struct NestedScroll { @State listPosition: number = 0; // 0代表滚动到List顶部,1代表中间值,2代表滚动到List底部。 - private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - private scroller: Scroller = new Scroller(); + private arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + private scroller: Scroller = new Scroller() build() { Flex() { @@ -257,17 +257,17 @@ struct NestedScroll { } .width("100%").height("50%").edgeEffect(EdgeEffect.None) .onReachStart(() => { - this.listPosition = 0; + this.listPosition = 0 }) .onReachEnd(() => { - this.listPosition = 2; + this.listPosition = 2 }) .onScrollBegin((dx: number, dy: number) => { if ((this.listPosition == 0 && dy >= 0) || (this.listPosition == 2 && dy <= 0)) { - this.scroller.scrollBy(0, -dy); - return { dxRemain: dx, dyRemain: 0 }; + this.scroller.scrollBy(0, -dy) + return { dxRemain: dx, dyRemain: 0 } } - this.listPosition = 1; + this.listPosition = 1 return { dxRemain: dx, dyRemain: dy }; }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-swiper.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-swiper.md index 3ee143d2a165be8aef8e1b72df05461b5b021a00..b9d2e3f3300160393745c24a49bc8b3ac82b479b 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-swiper.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-swiper.md @@ -180,3 +180,5 @@ struct SwiperExample { } } ``` + +![swiper](figures/swiper.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-tabcontent.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-tabcontent.md index 3d9639247408e19edc2f5614306cabf12a5e5080..ac63672ce50807e39794c19b9aef87d9be25728c 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-tabcontent.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-tabcontent.md @@ -113,3 +113,4 @@ struct TabContentExample { } ``` +![tabContent](figures/tabContent.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-rect.md b/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-rect.md index d2549d5bb3d22419b36aae65fc144f9bd56fb3fb..9ea5950c76a29569a4352278022675b9d4235e67 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-rect.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-rect.md @@ -61,27 +61,35 @@ struct RectExample { Column({ space: 10 }) { Text('normal').fontSize(11).fontColor(0xCCCCCC).width('90%') // 绘制90% * 50的矩形 - Rect({ width: '90%', height: 50 }) - .fill(Color.Pink) - // 绘制90% * 50的矩形框 - Rect() - .width('90%') - .height(50) - .fillOpacity(0) - .stroke(Color.Red) - .strokeWidth(3) - - Text('with rounded corners').fontSize(11).fontColor(0xCCCCCC).width('90%') - // 绘制90% * 80的矩形, 圆角宽高分别为40、20 - Rect({ width: '90%', height: 80 }) - .radiusHeight(20) - .radiusWidth(40) - .fill(Color.Pink) - // 绘制90% * 80的矩形, 圆角宽高为20 + Column({ space: 5 }) { + Text('normal').fontSize(9).fontColor(0xCCCCCC).width('90%') + // 绘制90% * 50矩形 + Rect({ width: '90%', height: 50 }) + .fill(Color.Pink) + // 绘制90% * 50的矩形框 + Rect() + .width('90%') + .height(50) + .fillOpacity(0) + .stroke(Color.Red) + .strokeWidth(3) + + Text('with rounded corners').fontSize(11).fontColor(0xCCCCCC).width('90%') + // 绘制90% * 80的矩形, 圆角宽高分别为40、20 + Rect({ width: '90%', height: 80 }) + .radiusHeight(20) + .radiusWidth(40) + .fill(Color.Pink) + // 绘制90% * 80的矩形, 圆角宽高为20 + Rect({ width: '90%', height: 80 }) + .radius(20) + .fill(Color.Pink) + }.width('100%').margin({ top: 10 }) + // 绘制90% * 50矩形, 左上圆角宽高40,右上圆角宽高20,右下圆角宽高40,左下圆角宽高20 Rect({ width: '90%', height: 80 }) - .radius(20) + .radius([[40, 40], [20, 20], [40, 40], [20, 20]]) .fill(Color.Pink) - }.width('100%').margin({ top: 10 }) + }.width('100%').margin({ top: 5 }) } } ``` diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-shape.md b/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-shape.md index c6634faf732e678e7609827cb81606410f185645..365f1333b677c98e55b5323b45cb20c2daa6ebde 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-shape.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-drawing-components-shape.md @@ -152,12 +152,12 @@ struct ShapeExample { @Entry @Component struct ShapeMeshExample { - @State columnVal: number = 0; - @State rowVal: number = 0; - @State count: number = 0; - @State verts: Array = []; - @State shapeWidth: number = 600; - @State shapeHeight: number = 600; + @State columnVal: number = 0 + @State rowVal: number = 0 + @State count: number = 0 + @State verts: Array = [] + @State shapeWidth: number = 600 + @State shapeHeight: number = 600 build() { Column() { @@ -186,34 +186,34 @@ struct ShapeMeshExample { .height(this.shapeHeight + 'px') // 手指触摸Shape组件时会显示mesh扭曲效果 .onTouch((event: TouchEvent) => { - var touchX = event.touches[0].x * 2; - var touchY = event.touches[0].y * 2; - this.columnVal = 20; - this.rowVal = 20; - this.count = (this.columnVal + 1) * (this.rowVal + 1); - var orig = [this.count * 2]; - var index = 0; + var touchX = event.touches[0].x * 2 + var touchY = event.touches[0].y * 2 + this.columnVal = 20 + this.rowVal = 20 + this.count = (this.columnVal + 1) * (this.rowVal + 1) + var orig = [this.count * 2] + var index = 0 for (var i = 0; i <= this.rowVal; i++) { - var fy = this.shapeWidth * i / this.rowVal; + var fy = this.shapeWidth * i / this.rowVal for (var j = 0; j <= this.columnVal; j++) { - var fx = this.shapeWidth * j / this.columnVal; - orig[index * 2 + 0] = this.verts[index * 2 + 0] = fx; - orig[index * 2 + 1] = this.verts[index * 2 + 1] = fy; + var fx = this.shapeWidth * j / this.columnVal + orig[index * 2 + 0] = this.verts[index * 2 + 0] = fx + orig[index * 2 + 1] = this.verts[index * 2 + 1] = fy index++; } } for (var k = 0; k < this.count * 2; k += 2) { - var dx = touchX - orig[k + 0]; - var dy = touchY - orig[k + 1]; - var dd = dx * dx + dy * dy; - var d = Math.sqrt(dd); - var pull = 80000 / (dd * d); + var dx = touchX - orig[k + 0] + var dy = touchY - orig[k + 1] + var dd = dx * dx + dy * dy + var d = Math.sqrt(dd) + var pull = 80000 / (dd * d) if (pull >= 1) { - this.verts[k + 0] = touchX; - this.verts[k + 1] = touchY; + this.verts[k + 0] = touchX + this.verts[k + 1] = touchY } else { - this.verts[k + 0] = orig[k + 0] + dx * pull; - this.verts[k + 1] = orig[k + 1] + dy * pull; + this.verts[k + 0] = orig[k + 0] + dx * pull + this.verts[k + 1] = orig[k + 1] + dy * pull } } }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md b/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md index fec478c62d03e2ebcc3816c032b71e13f23d14f3..eef21726017bab7f983eaa66d92615778127de09 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md @@ -88,3 +88,11 @@ struct AnimateToExample { } } ``` + +示意图: + +![animation](figures/animation.PNG) + +点击第一个按钮播放改变按钮大小的动画,点击第二个按钮播放按钮顺时针旋转90度的动画。 + +![animation1](figures/animation1.PNG) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-gesture-settings.md b/zh-cn/application-dev/reference/arkui-ts/ts-gesture-settings.md index dcc4bf1065fbf418faf35acfe9b4392ee82ee600..d31658612f6d098d7bac990af1899929c541aed6 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-gesture-settings.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-gesture-settings.md @@ -85,8 +85,8 @@ @Entry @Component struct GestureSettingsExample { - @State priorityTestValue: string = ''; - @State parallelTestValue: string = ''; + @State priorityTestValue: string = '' + @State parallelTestValue: string = '' build() { Column() { @@ -95,7 +95,7 @@ struct GestureSettingsExample { .gesture( TapGesture() .onAction(() => { - this.priorityTestValue += '\nText'; + this.priorityTestValue += '\nText' })) } .height(200) @@ -107,7 +107,7 @@ struct GestureSettingsExample { .priorityGesture( TapGesture() .onAction((event: GestureEvent) => { - this.priorityTestValue += '\nColumn'; + this.priorityTestValue += '\nColumn' }), GestureMask.IgnoreInternal) Column() { @@ -115,7 +115,7 @@ struct GestureSettingsExample { .gesture( TapGesture() .onAction(() => { - this.parallelTestValue += '\nText'; + this.parallelTestValue += '\nText' })) } .height(200) @@ -127,7 +127,7 @@ struct GestureSettingsExample { .parallelGesture( TapGesture() .onAction((event: GestureEvent) => { - this.parallelTestValue += '\nColumn'; + this.parallelTestValue += '\nColumn' }), GestureMask.Normal) } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-methods-action-sheet.md b/zh-cn/application-dev/reference/arkui-ts/ts-methods-action-sheet.md index b00ecd9c6be46ac428f017c744e1115b1a07cd35..eefeda849adbbaa2e4d9333f31da124de59ce010 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-methods-action-sheet.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-methods-action-sheet.md @@ -3,13 +3,9 @@ 列表弹窗。 > **说明:** -> 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 +> 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 -## 权限 - -无 - ## ActionSheet.show @@ -21,10 +17,10 @@ show(value: { title: string | Resource, message: string  | 参数名 | 参数类型 | 必填 | 参数描述 | | ---------- | -------------------------- | ------- | ----------------------------- | -| title | string \| [Resource](ts-types.md#resource) | 是 | 弹窗标题。 | -| message | string \| [Resource](ts-types.md#resource) | 是 | 弹窗内容。 | +| title | [ResourceStr](ts-types.md#resourcestr) | 是 | 弹窗标题。 | +| message | [ResourceStr](ts-types.md#resourcestr) | 是 | 弹窗内容。 | | autoCancel | boolean | 否 | 点击遮障层时,是否关闭弹窗。
默认值:true | -| confirm | {
value: string \| [Resource](ts-types.md#resource),
action: () => void
} | 否 | 确认按钮的文本内容和点击回调。
默认值:
value:按钮文本内容。
action: 按钮选中时的回调。 | +| confirm | {
value: [ResourceStr](ts-types.md#resourcestr),
action: () => void
} | 否 | 确认按钮的文本内容和点击回调。
默认值:
value:按钮文本内容。
action: 按钮选中时的回调。 | | cancel | () => void | 否 | 点击遮障层关闭dialog时的回调。 | | alignment | [DialogAlignment](ts-methods-custom-dialog-box.md#dialogalignment枚举说明) | 否 | 弹窗在竖直方向上的对齐方式。
默认值:DialogAlignment.Bottom | | offset | {
dx: Length,
dy: Length
} | 否 | 弹窗相对alignment所在位置的偏移量。{
dx: 0,
dy: 0
} | @@ -34,8 +30,8 @@ show(value: { title: string | Resource, message: string  | 参数名 | 参数类型 | 必填 | 参数描述 | | ------ | ------------------------------------------------------------ | ---- | ----------------- | -| title | string \| [Resource](ts-types.md#resource) | 是 | 选项的文本内容。 | -| icon | string \| [Resource](ts-types.md#resource) | 否 | 选项的图标,默认无图标显示。 | +| title | [ResourceStr](ts-types.md#resourcestr) | 是 | 选项的文本内容。 | +| icon | [ResourceStr](ts-types.md#resourcestr) | 否 | 选项的图标,默认无图标显示。 | | action | ()=>void | 是 | 选项选中的回调。 | @@ -43,7 +39,6 @@ show(value: { title: string | Resource, message: string  ```ts -// xxx.ets @Entry @Component struct ActionSheetExample { @@ -54,29 +49,35 @@ struct ActionSheetExample { ActionSheet.show({ title: 'ActionSheet title', message: 'message', + autoCancel: true, confirm: { value: 'Confirm button', action: () => { - console.log('Get Alert Dialog handled'); + console.log('Get Alert Dialog handled') } }, + cancel: () => { + console.log('actionSheet canceled') + }, + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -10 }, sheets: [ { title: 'apples', action: () => { - console.log('apples'); + console.log('apples') } }, { title: 'bananas', action: () => { - console.log('bananas'); + console.log('bananas') } }, { title: 'pears', action: () => { - console.log('pears'); + console.log('pears') } } ] diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-methods-alert-dialog-box.md b/zh-cn/application-dev/reference/arkui-ts/ts-methods-alert-dialog-box.md index ffb54ddf303b00aa927bdc538a69dfd4022c9c66..4b3bdc23ba12b695df9873770610be0362a31628 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-methods-alert-dialog-box.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-methods-alert-dialog-box.md @@ -11,7 +11,7 @@ | 名称 | 参数类型 | 参数描述 | | ---- | --------------- | -------- | -| show | AlertDialogParamWithConfirm \| AlertDialogParamWithButtons | 定义并显示AlertDialog组件。 | +| show | [AlertDialogParamWithConfirm](#alertdialogparamwithconfirm对象说明) \| [AlertDialogParamWithButtons](#alertdialogparamwithbuttons对象说明) | 定义并显示AlertDialog组件。 | ## AlertDialogParamWithConfirm对象说明 | 参数名 | 参数类型 | 必填 | 参数描述 | @@ -19,11 +19,11 @@ | title | [ResourceStr](ts-types.md#resourcestr) | 否 | 弹窗标题。 | | message | [ResourceStr](ts-types.md#resourcestr) | 是 | 弹窗内容。 | | autoCancel | boolean | 否 | 点击遮障层时,是否关闭弹窗。
默认值:true | -| confirm | {
value: string \| [Resource](ts-types.md#resource),
fontColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
backgroundColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
action: () => void
} | 否 | 确认按钮的文本内容、文本色、按钮背景色和点击回调。 | +| confirm | {
value: [ResourceStr](ts-types.md#resourcestr),
fontColor?: [ResourceColor](ts-types.md#resourcecolor),
backgroundColor?:  [ResourceColor](ts-types.md#resourcecolor),
action: () => void
} | 否 | 确认按钮的文本内容、文本色、按钮背景色和点击回调。 | | cancel | () => void | 否 | 点击遮障层关闭dialog时的回调。 | | alignment | [DialogAlignment](#dialogalignment枚举说明) | 否 | 弹窗在竖直方向上的对齐方式。
默认值:DialogAlignment.Default | | offset | [Offset](ts-types.md#offset) | 否 | 弹窗相对alignment所在位置的偏移量。 | -| gridCount | number | 否 | 弹窗容器宽度所占用栅格数。
**说明:**
当gridCount小于等于0时,弹窗宽度是固定的;大于0时,按照设置的数值显示宽度,最大值为4,若值为小数,则向下取整。 | +| gridCount | number | 否 | 弹窗容器宽度所占用栅格数。 | ## AlertDialogParamWithButtons对象说明 | 参数名 | 参数类型 | 必填 | 参数描述 | @@ -31,12 +31,12 @@ | title | [ResourceStr](ts-types.md#resourcestr) | 否 | 弹窗标题。 | | message | [ResourceStr](ts-types.md#resourcestr) | 是 | 弹窗内容。 | | autoCancel | boolean | 否 | 点击遮障层时,是否关闭弹窗。
默认值:true | -| primaryButton | {
value: string \| [Resource](ts-types.md#resource),
fontColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
backgroundColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
action: () => void;
} | 否 | 按钮的文本内容、文本色、按钮背景色和点击回调。 | -| secondaryButton | {
value: string \| [Resource](ts-types.md#resource),
fontColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
backgroundColor?: Color \| number \| string \| [Resource](ts-types.md#resource),
action: () => void;
} | 否 | 按钮的文本内容、文本色、按钮背景色和点击回调。 | +| primaryButton | {
value: [ResourceStr](ts-types.md#resourcestr),
fontColor?: [ResourceColor](ts-types.md#resourcecolor),
backgroundColor?: [ResourceColor](ts-types.md#resourcecolor),
action: () => void;
} | 否 | 按钮的文本内容、文本色、按钮背景色和点击回调。 | +| secondaryButton | {
value: [ResourceStr](ts-types.md#resourcestr),
fontColor?: [ResourceColor](ts-types.md#resourcecolor),
backgroundColor?: [ResourceColor](ts-types.md#resourcecolor),
action: () => void;
} | 否 | 按钮的文本内容、文本色、按钮背景色和点击回调。 | | cancel | () => void | 否 | 点击遮障层关闭dialog时的回调。 | | alignment | [DialogAlignment](#dialogalignment枚举说明) | 否 | 弹窗在竖直方向上的对齐方式。
默认值:DialogAlignment.Default | | offset | [Offset](ts-types.md#offset) | 否 | 弹窗相对alignment所在位置的偏移量。 | -| gridCount | number | 否 | 弹窗容器宽度所占用栅格数。 | +| gridCount | number | 否 | 弹窗容器宽度所占用栅格数。 | ## DialogAlignment枚举说明 @@ -60,7 +60,6 @@ @Entry @Component struct AlertDialogExample { - build() { Column({ space: 5 }) { Button('one button dialog') @@ -69,6 +68,10 @@ struct AlertDialogExample { { title: 'title', message: 'text', + autoCancel: true, + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -20 }, + gridCount: 3, confirm: { value: 'button', action: () => { @@ -80,7 +83,7 @@ struct AlertDialogExample { } } ) - }) + }) .backgroundColor(0x317aff) Button('two button dialog') .onClick(() => { @@ -88,6 +91,10 @@ struct AlertDialogExample { { title: 'title', message: 'text', + autoCancel: true, + alignment: DialogAlignment.Bottom, + gridCount: 4, + offset: { dx: 0, dy: -20 }, primaryButton: { value: 'cancel', action: () => { @@ -105,7 +112,7 @@ struct AlertDialogExample { } } ) - }).backgroundColor(0x317aff) + }).backgroundColor(0x317aff) }.width('100%').margin({ top: 5 }) } } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md b/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md index 69dce85187ccc50c4f54e253fe9ce85b5c4fcf77..86965454a213ad5db466bdbf9e2e4ac8a1f6c8ba 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-methods-custom-dialog-box.md @@ -22,24 +22,9 @@ CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, aut | cancel | () => void | 否 | 点击遮障层退出时的回调。 | | autoCancel | boolean | 否 | 是否允许点击遮障层退出。
默认值:true | | alignment | [DialogAlignment](ts-methods-alert-dialog-box.md#dialogalignment枚举说明) | 否 | 弹窗在竖直方向上的对齐方式。
默认值:DialogAlignment.Default | -| offset | {
dx: Length \| [Resource](ts-types.md#resource),
dy: Length  \| [Resource](ts-types.md#resource)
} | 否 | 弹窗相对alignment所在位置的偏移量。 | +| offset | [Offset](ts-types.md#offset) | 否 | 弹窗相对alignment所在位置的偏移量。 | | customStyle | boolean | 否 | 弹窗容器样式是否自定义。
默认值:false | -| gridCount8+ | number | 否 | 弹窗宽度占栅格宽度的个数。 | - -## DialogAlignment枚举说明 - -| 名称 | 描述 | -| ------------------------ | ------------------------------------------------------ | -| Top | 垂直顶部对齐。 | -| Center | 垂直居中对齐。 | -| Bottom | 垂直底部对齐。 | -| Default | 默认对齐。
**说明:**
与枚举值Center效果相同。 | -| TopStart8+ | 左上对齐。 | -| TopEnd8+ | 右上对齐。 | -| CenterStart8+ | 左中对齐。 | -| CenterEnd8+ | 右中对齐。 | -| BottomStart8+ | 左下对齐。 | -| BottomEnd8+ | 右下对齐。 | +| gridCount8+ | number | 否 | 弹窗宽度占[栅格宽度](../../ui/ui-ts-layout-grid-container-new.md)的个数。 | ## CustomDialogController @@ -107,17 +92,28 @@ struct CustomDialogUser { @State textValue: string = '' @State inputValue: string = 'click me' dialogController: CustomDialogController = new CustomDialogController({ - builder: CustomDialogExample({ cancel: this.onCancel, confirm: this.onAccept, textValue: $textValue, inputValue: $inputValue }), + builder: CustomDialogExample({ + cancel: this.onCancel, + confirm: this.onAccept, + textValue: $textValue, + inputValue: $inputValue + }), cancel: this.existApp, - autoCancel: true + autoCancel: true, + alignment: DialogAlignment.Default, + offset: { dx: 0, dy: -20 }, + gridCount: 4, + customStyle: false }) onCancel() { console.info('Callback when the first button is clicked') } + onAccept() { console.info('Callback when the second button is clicked') } + existApp() { console.info('Click the callback in the blank area') } diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-methods-menu.md b/zh-cn/application-dev/reference/arkui-ts/ts-methods-menu.md index df6b4f8b24e75937f0d1109893055cd3b00a03a5..25616026704a2146cdc171cd6ceb250a3aee3e79 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-methods-menu.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-methods-menu.md @@ -49,7 +49,7 @@ struct Index { .bindContextMenu(this.MenuBuilder, ResponseType.LongPress) .onDragStart(()=>{ // 拖拽时关闭菜单 - ContextMenu.close(); + ContextMenu.close() }) } .width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-methods-timepicker-dialog.md b/zh-cn/application-dev/reference/arkui-ts/ts-methods-timepicker-dialog.md index 76ea01dc98ffc8ac952cba14b5192b8bebcc26da..61dd5ab8e724f97b8e9d0b4a87bc71627980d9da 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-methods-timepicker-dialog.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-methods-timepicker-dialog.md @@ -41,13 +41,13 @@ struct TimePickerDialogExample { onAccept: (value: TimePickerResult) => { // 设置selectTime为按下确定按钮时的时间,这样当弹窗再次弹出时显示选中的为上一次确定的时间 this.selectTime.setHours(value.hour, value.minute) - console.info("TimePickerDialog:onAccept()" + JSON.stringify(value)); + console.info("TimePickerDialog:onAccept()" + JSON.stringify(value)) }, onCancel: () => { - console.info("TimePickerDialog:onCancel()"); + console.info("TimePickerDialog:onCancel()") }, onChange: (value: TimePickerResult) => { - console.info("TimePickerDialog:onChange()" + JSON.stringify(value)); + console.info("TimePickerDialog:onChange()" + JSON.stringify(value)) } }) }) @@ -59,13 +59,13 @@ struct TimePickerDialogExample { useMilitaryTime: true, onAccept: (value: TimePickerResult) => { this.selectTime.setHours(value.hour, value.minute) - console.info("TimePickerDialog:onAccept()" + JSON.stringify(value)); + console.info("TimePickerDialog:onAccept()" + JSON.stringify(value)) }, onCancel: () => { - console.info("TimePickerDialog:onCancel()"); + console.info("TimePickerDialog:onCancel()") }, onChange: (value: TimePickerResult) => { - console.info("TimePickerDialog:onChange()" + JSON.stringify(value)); + console.info("TimePickerDialog:onChange()" + JSON.stringify(value)) } }) }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-offscreencanvasrenderingcontext2d.md b/zh-cn/application-dev/reference/arkui-ts/ts-offscreencanvasrenderingcontext2d.md index 5928d2c9c52ee3b4d17d4c72b6e86853d92d4a90..f243c3342ad7ee14e6d77fece525d2c149cd1e78 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-offscreencanvasrenderingcontext2d.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-offscreencanvasrenderingcontext2d.md @@ -67,8 +67,8 @@ struct FillStyleExample { .onReady(() =>{ this.offContext.fillStyle = '#0000ff' this.offContext.fillRect(20, 160, 150, 100) - var image = this.offContext.transferToImageBitmap(); - this.context.transferFromImageBitmap(image); + var image = this.offContext.transferToImageBitmap() + this.context.transferFromImageBitmap(image) }) } .width('100%') @@ -445,8 +445,8 @@ struct LineDashOffset { .onReady(() =>{ this.offContext.arc(100, 75, 50, 0, 6.28) this.offContext.setLineDash([10,20]) - this.offContext.lineDashOffset = 10.0; - this.offContext.stroke(); + this.offContext.lineDashOffset = 10.0 + this.offContext.stroke() var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -1016,7 +1016,7 @@ stroke(path?: Path2D): void | path | [Path2D](ts-components-canvas-path2d.md) | 否 | null | 需要绘制的Path2D。 | **示例:** - + ```ts // xxx.ets @Entry @@ -1373,10 +1373,10 @@ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.offContext.beginPath(); - this.offContext.moveTo(20, 20); - this.offContext.quadraticCurveTo(100, 100, 200, 20); - this.offContext.stroke(); + this.offContext.beginPath() + this.offContext.moveTo(20, 20) + this.offContext.quadraticCurveTo(100, 100, 200, 20) + this.offContext.stroke() var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -1475,9 +1475,9 @@ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.offContext.moveTo(100, 20); - this.offContext.arcTo(150, 20, 150, 70, 50); - this.offContext.stroke(); + this.offContext.moveTo(100, 20) + this.offContext.arcTo(150, 20, 150, 70, 50) + this.offContext.stroke() var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -1664,17 +1664,17 @@ struct Fill { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - let region = new Path2D(); - region.moveTo(30, 90); - region.lineTo(110, 20); - region.lineTo(240, 130); - region.lineTo(60, 130); - region.lineTo(190, 20); - region.lineTo(270, 90); - region.closePath(); + let region = new Path2D() + region.moveTo(30, 90) + region.lineTo(110, 20) + region.lineTo(240, 130) + region.lineTo(60, 130) + region.lineTo(190, 20) + region.lineTo(270, 90) + region.closePath() // Fill path - this.offContext.fillStyle = 'green'; - this.offContext.fill(region, "evenodd"); + this.offContext.fillStyle = 'green' + this.offContext.fill(region, "evenodd") var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -1766,9 +1766,9 @@ struct Clip { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - let region = new Path2D(); - region.rect(80,10,20,130); - region.rect(40,50,100,50); + let region = new Path2D() + region.rect(80,10,20,130) + region.rect(40,50,100,50) this.offContext.clip(region,"evenodd") this.offContext.fillStyle = "rgb(255,0,0)" this.offContext.fillRect(0, 0, 600, 600) @@ -2214,8 +2214,8 @@ getImageData(sx: number, sy: number, sw: number, sh: number): ImageData @Entry @Component struct GetImageData { - private settings: RenderingContextSettings = new RenderingContextSettings(true); - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + private settings: RenderingContextSettings = new RenderingContextSettings(true) + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings) private img:ImageBitmap = new ImageBitmap("/common/images/1234.png") @@ -2226,9 +2226,9 @@ struct GetImageData { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.offContext.drawImage(this.img,0,0,130,130); - var imagedata = this.offContext.getImageData(50,50,130,130); - this.offContext.putImageData(imagedata,150,150); + this.offContext.drawImage(this.img,0,0,130,130) + var imagedata = this.offContext.getImageData(50,50,130,130) + this.offContext.putImageData(imagedata,150,150) var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -2330,7 +2330,7 @@ struct SetLineDash { .onReady(() =>{ this.offContext.arc(100, 75, 50, 0, 6.28) this.offContext.setLineDash([10,20]) - this.offContext.stroke(); + this.offContext.stroke() var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -2384,7 +2384,7 @@ struct OffscreenCanvasGetLineDash { .onReady(() => { this.offContext.arc(100, 75, 50, 0, 6.28) this.offContext.setLineDash([10,20]) - this.offContext.stroke(); + this.offContext.stroke() let res = this.offContext.getLineDash() var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) @@ -2437,7 +2437,7 @@ struct ToDataURL { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - var dataURL = this.offContext.toDataURL(); + var dataURL = this.offContext.toDataURL() }) } .width('100%') @@ -2534,11 +2534,11 @@ struct CanvasExample { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.offContext.save(); // save the default state - this.offContext.fillStyle = "green"; - this.offContext.fillRect(20, 20, 100, 100); - this.offContext.restore(); // restore to the default state - this.offContext.fillRect(150, 75, 100, 100); + this.offContext.save() // save the default state + this.offContext.fillStyle = "green" + this.offContext.fillRect(20, 20, 100, 100) + this.offContext.restore() // restore to the default state + this.offContext.fillRect(150, 75, 100, 100) var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) @@ -2575,11 +2575,11 @@ struct CanvasExample { .height('100%') .backgroundColor('#ffff00') .onReady(() =>{ - this.offContext.save(); // save the default state - this.offContext.fillStyle = "green"; - this.offContext.fillRect(20, 20, 100, 100); - this.offContext.restore(); // restore to the default state - this.offContext.fillRect(150, 75, 100, 100); + this.offContext.save() // save the default state + this.offContext.fillStyle = "green" + this.offContext.fillRect(20, 20, 100, 100) + this.offContext.restore() // restore to the default state + this.offContext.fillRect(150, 75, 100, 100) var image = this.offContext.transferToImageBitmap() this.context.transferFromImageBitmap(image) }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-state-management.md b/zh-cn/application-dev/reference/arkui-ts/ts-state-management.md index c9f4cb0422c71be641d1ebc404597a5ca5fbcdfe..11fb2e197ce9d067af664db6c0b96028acce3663 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-state-management.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-state-management.md @@ -2,7 +2,9 @@ 状态管理模块提供了应用程序的数据存储能力、持久化数据管理能力、Ability数据存储能力和应用程序需要的环境状态,其中Ability数据存储从API version9开始支持。 -> 说明:本模块首批接口从API version 7开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。 +> **说明:** +> +> 本模块首批接口从API version 7开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。 ## AppStorage @@ -142,7 +144,7 @@ let simple = AppStorage.Get('simpleProp') ### Set -Set(propName: string, newValue: T): boolean +Set\(propName: string, newValue: T): boolean 对已保存的key值,替换其value值。 @@ -165,7 +167,7 @@ let simple = AppStorage.Set('simpleProp', 121); ### SetOrCreate -SetOrCreate(propName: string, newValue: T): void +SetOrCreate\(propName: string, newValue: T): void 创建或更新setOrCreate内部的值。 @@ -646,7 +648,7 @@ PersistentStorage.PersistProps([{'highScore', '0'},{'wightScore','1'}]) ### Keys -Keys(): Array +Keys(): Array\ 返回所有持久化属性的标记。 @@ -654,7 +656,7 @@ Keys(): Array | 类型 | 描述 | | ------------- | -------------------------- | -| Array | 返回所有持久化属性的标记。 | +| Array\ | 返回所有持久化属性的标记。 | ```ts let simple = PersistentStorage.Keys() @@ -728,7 +730,7 @@ Environment.EnvProps([{'accessibilityEnabled', 'default'},{'accessibilityUnEnabl ### Keys -Keys(): Array +Keys(): Array\ 返回关联的系统项。 @@ -736,7 +738,7 @@ Keys(): Array | 类型 | 描述 | | ------------- | ---------------------- | -| Array | 返回关联的系统项数组。 | +| Array\ | 返回关联的系统项数组。 | ```ts let simple = Environment.Keys() diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-component.md b/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-component.md index 054824b2f7f471468a57cb0d41f48a1a7d66f439..1f97c15861aa8fb6b9e0627760346dd2a5262e58 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-component.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-component.md @@ -59,3 +59,5 @@ struct TransitionExample { } } ``` + +![animateTo](figures/animateTo.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md b/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md index 504037c0f918cb24e11f718434d084d363ab064e..021cc278c448273ae8cf0fbec7af7d77cf919152 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md @@ -53,3 +53,4 @@ struct pageBExample { } ``` +![shared](figures/shared.gif) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-border-image.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-border-image.md index 574b3191a8a64b5d67f2e5bd17408e6b71e7f72c..268745a58a2edbff9dd22bd06d6ca3558eb84fd5 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-border-image.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-border-image.md @@ -41,19 +41,31 @@ @Entry @Component struct Index { + @State outSetValue: number = 40 build() { Row() { Column() { - Text('This is borderImage.').textAlign(TextAlign.Center) + Text('This is borderImage.').textAlign(TextAlign.Center).fontSize(50) .borderImage({ - source: "borderOrigin.png", - slice: {top:"31%", bottom:"31%", left:"31%", right:"31%"}, - width: {top:"20px", bottom:"20px", left:"20px", right:"20px"}, - outset: {top:"5px", bottom:"5px", left:"5px", right:"5px"}, + source: $r('app.media.heart'), + slice: `${this.outSetValue}%`, + width: `${this.outSetValue}px`, + outset: '5px', repeat: RepeatMode.Repeat, fill: false }) + Slider({ + value: this.outSetValue, + min: 0, + max: 100, + style: SliderStyle.OutSet + }) + .margin({ top: 30 }) + .onChange((value: number, mode: SliderChangeMode) => { + this.outSetValue = value + console.info('value:' + value + 'mode:' + mode.toString()) + }) } .width('100%') } @@ -62,7 +74,7 @@ struct Index { } ``` -![zh-cn_image_borderImage](figures/borderImage.png) +![zh-cn_image_borderImage](figures/borderImage.gif) ```ts diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-component-id.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-component-id.md index 9f43f0a9139c4489a313bdf3a208dad2d1fee6d2..f1ad36dfd7f9caec182fb07f44812112c588ebe6 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-component-id.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-component-id.md @@ -126,19 +126,19 @@ sendMouseEvent(event: MouseEvent): boolean ```ts // xxx.ets class Utils { - static rect_left; - static rect_top; - static rect_right; - static rect_bottom; - static rect_value; + static rect_left + static rect_top + static rect_right + static rect_bottom + static rect_value //获取组件所占矩形区域坐标 static getComponentRect(key) { - let strJson = getInspectorByKey(key); - let obj = JSON.parse(strJson); - console.info("[getInspectorByKey] current component obj is: " + JSON.stringify(obj)); + let strJson = getInspectorByKey(key) + let obj = JSON.parse(strJson) + console.info("[getInspectorByKey] current component obj is: " + JSON.stringify(obj)) let rectInfo = JSON.parse('[' + obj.$rect + ']') - console.info("[getInspectorByKey] rectInfo is: " + rectInfo); + console.info("[getInspectorByKey] rectInfo is: " + rectInfo) this.rect_left = JSON.parse('[' + rectInfo[0] + ']')[0] this.rect_top = JSON.parse('[' + rectInfo[0] + ']')[1] this.rect_right = JSON.parse('[' + rectInfo[1] + ']')[0] diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-flex-layout.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-flex-layout.md index 8dbcd0c5782d3f641edaa1a61049e1bd79c2a41d..176b1d4b04e4ba33d3adca9b8d309f2d3da6c7b8 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-flex-layout.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-flex-layout.md @@ -105,4 +105,4 @@ struct FlexExample { } ``` - +![flex](figures/flex.PNG) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-focus.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-focus.md index f417b1f8d1e02e97998dda9da036f7d9931d966c..e915efdd2c514a9a015f19d6b5060cfb37e30412 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-focus.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-focus.md @@ -63,7 +63,7 @@ struct FocusableExample { .width(165) .height(40) .fontColor(Color.White) - .focusOnTouch(true) //该Button组件点击后可获焦 + .focusOnTouch(true) // 该Button组件点击后可获焦 Row({ space: 5 }) { Button() .width(80) @@ -73,7 +73,7 @@ struct FocusableExample { .width(80) .height(40) .fontColor(Color.White) - .focusOnTouch(true) //该Button组件点击后可获焦 + .focusOnTouch(true) // 该Button组件点击后可获焦 } Row({ space: 5 }) { Button() @@ -86,7 +86,7 @@ struct FocusableExample { .fontColor(Color.White) } }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed) - .tabIndex(1) //该Column组件为按TAB键走焦的第一个获焦的组件 + .tabIndex(1) // 该Column组件为按TAB键走焦的第一个获焦的组件 Column({ space: 5 }) { Button('Group2') .width(165) @@ -101,7 +101,7 @@ struct FocusableExample { .width(80) .height(40) .fontColor(Color.White) - .groupDefaultFocus(true) //该Button组件上级Column组件获焦时获焦 + .groupDefaultFocus(true) // 该Button组件上级Column组件获焦时获焦 } Row({ space: 5 }) { Button() @@ -114,14 +114,14 @@ struct FocusableExample { .fontColor(Color.White) } }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed) - .tabIndex(2) //该Column组件为按TAB键走焦的第二个获焦的组件 + .tabIndex(2) // 该Column组件为按TAB键走焦的第二个获焦的组件 } Column({ space: 5 }) { TextInput({placeholder: 'input', text: this.inputValue}) .onChange((value: string) => { this.inputValue = value }) - .defaultFocus(true) //该TextInput组件为页面的初始默认焦点 + .defaultFocus(true) // 该TextInput组件为页面的初始默认焦点 Button('Group3') .width(165) .height(40) @@ -165,7 +165,7 @@ struct FocusableExample { .fontColor(Color.White) } }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed) - .tabIndex(3) //该Column组件为按TAB键走焦的第三个获焦的组件 + .tabIndex(3) // 该Column组件为按TAB键走焦的第三个获焦的组件 }.alignItems(VerticalAlign.Top) } } @@ -200,7 +200,7 @@ focusControl.requestFocus示例代码: 使用focusContrl.requestFocus接口使指定组件获取焦点。 ```ts // requestFocus.ets -import prompt from '@system.prompt'; +import prompt from '@ohos.prompt' @Entry @Component @@ -250,7 +250,7 @@ struct RequestFocusExample { Button("RequestFocus") .width(200).height(70).fontColor(Color.White) .onClick(() => { - var res = focusControl.requestFocus(this.selectId) //使选中的this.selectId的组件获焦 + var res = focusControl.requestFocus(this.selectId) // 使选中的this.selectId的组件获焦 if (res) { prompt.showToast({message: 'Request success'}) } else { diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-image-effect.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-image-effect.md index 3fc5257703195527dba8b5c37e8497b69fd9bb54..fbdaabe2a84141eb2de4b1f3a6f7387cea5dc96f 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-image-effect.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-image-effect.md @@ -19,9 +19,9 @@ | saturate | number | 1.0 | 为当前组件添加饱和度效果,饱和度为颜色中的含色成分和消色成分(灰)的比例,入参为1时,显示原图像,大于1时含色成分越大,饱和度越大;小于1时消色成分越大,饱和度越小。(百分比) | | contrast | number | 1.0 | 为当前组件添加对比度效果,入参为对比度的值,值为1时,显示原图;大于1时,值越大对比度越高,图像越清晰醒目;小于1时,值越小对比度越低;当对比度为0时,图像变为全灰。(百分比) | | invert | number | 0 | 反转输入的图像。入参为图像反转的比例。值为1时完全反转。值为0则图像无变化。(百分比) | -| colorBlend 8+ | [Color](ts-appendix-enums.md#color) \| string \| [Resource](ts-types.md#resource) | - | 为当前组件添加颜色叠加效果,入参为叠加的颜色。 | | sepia | number | 0 | 将图像转换为深褐色。入参为图像反转的比例。值为1则完全是深褐色的,值为0图像无变化。 (百分比) | | hueRotate | number \| string | '0deg' | 色相旋转效果,输入参数为旋转角度。 | +| colorBlend 8+ | [Color](ts-appendix-enums.md#color) \| string \| [Resource](ts-types.md#resource) | - | 为当前组件添加颜色叠加效果,入参为叠加的颜色。 | ## 示例 @@ -34,7 +34,7 @@ struct BlurEffectsExample { build() { Column({ space: 10 }) { - // 对字体进行模糊 + // 对字体进行模糊 Text('font blur').fontSize(15).fontColor(0xCCCCCC).width('90%') Flex({ alignItems: ItemAlign.Center }) { Text('original text').margin(10) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-layout-constraints.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-layout-constraints.md index 832938c1704c97a306e54eb44448efc33227b9e8..86660cec308c85cb96f356972f8b34b69a3eb850 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-layout-constraints.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-layout-constraints.md @@ -22,7 +22,7 @@ @Entry @Component struct AspectRatioExample { - private children: string[] = ['1', '2', '3', '4', '5', '6']; + private children: string[] = ['1', '2', '3', '4', '5', '6'] build() { Column({ space: 20 }) { diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-menu.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-menu.md index 92463eb228b273e59b141143d599d52b7bbafed5..e95f066470d5881d87ab5b2e32b56b9b25a158a7 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-menu.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-menu.md @@ -25,7 +25,9 @@ ## 示例 -#### 普通菜单 +### 示例1 + +普通菜单 ```ts // xxx.ets @@ -58,58 +60,59 @@ struct MenuExample { ![zh-cn_image_0000001174582862](figures/zh-cn_image_0000001174582862.gif) -#### 自定义内容菜单 +### 示例2 -```ts -// xxx.ets -import router from '@system.router'; +自定义内容菜单 +```ts @Entry @Component struct MenuExample { + @State listData: number[] = [0, 0, 0] + @Builder MenuBuilder() { Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { - Text('text1') - .fontSize(20) - .width(100) - .height(50) - .textAlign(TextAlign.Center) - - Divider().height(10) - - Text('text2') - .fontSize(20) - .width(100) - .height(50) - .textAlign(TextAlign.Center) - - Divider().height(10) - - Button('Next') - .fontSize(20) - .width(100) - .height(50) - .onClick(() => { - router.push({ uri: 'pages/details' }) - }) - + ForEach(this.listData, (item, index) => { + Column() { + Row() { + Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 }) + Text(`Menu${index + 1}`).fontSize(20) + } + .width('100%') + .height(30) + .justifyContent(FlexAlign.Center) + .align(Alignment.Center) + .onClick(() => { + console.info(`Menu${index + 1} Clicked!`) + }) + + if (index != this.listData.length - 1) { + Divider().height(10).width('80%').color('#ccc') + } + }.padding(5).height(40) + }) }.width(100) } build() { Column() { Text('click for menu') + .fontSize(20) + .margin({ top: 20 }) + .bindMenu(this.MenuBuilder) } + .height('100%') .width('100%') - .margin({ top: 5 }) - .bindMenu(this.MenuBuilder) + .backgroundColor('#f0f0f0') } } ``` ![zh-cn_image_0000001186807708](figures/zh-cn_image_0000001186807708.gif) -#### 菜单(右键触发显示) +### 示例3 + +菜单(右键触发显示) ```ts // xxx.ets diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-overlay.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-overlay.md index 14fdb7f1a435f40f82029ed7f207d6ba4457de00..153cb7f34463052a855476f22fda8b76ddbb2233 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-overlay.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-overlay.md @@ -29,7 +29,7 @@ struct OverlayExample { .width(240).height(240) .overlay("Winter is a beautiful season, especially when it snows.", { align: Alignment.Bottom, - offset: { x: 70, y: 100 } + offset: { x: 0, y: -15 } }) }.border({ color: Color.Black, width: 2 }) }.width('100%') diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-popup.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-popup.md index c03775fc9dbeb8e98226a3df3aefd65d7b39d3ae..c909c6988b7711c00f9febca084960e0d3caebe1 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-popup.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-popup.md @@ -20,11 +20,11 @@ | -------------------------| ------------------------------------------------| -----| ----------------------------------------- | | message | string | 是 | 弹窗信息内容。 | | placementOnTop | boolean | 否 | 是否在组件上方显示,默认值为false。 | -| arrowOffset9+ | [Length](ts-types.md#length) | 否 | popup箭头在弹窗处的偏移。箭头在气泡上下方时,数值为0表示箭头居最左侧,偏移量为箭头至最左侧的距离,默认居中。箭头在气泡左右侧时,偏移量为箭头至最上侧的距离,默认居中。 | -| showInSubWindow9+ | boolean | 否 | 是否在子窗口显示气泡,默认值为false。 | | primaryButton | {
value: string,
action: () => void
} | 否 | 第一个按钮。
value: 弹窗里主按钮的文本。
action: 点击主按钮的回调函数。 | | secondaryButton | {
value: string,
action: () => void
} | 否 | 第二个按钮。
value: 弹窗里辅助按钮的文本。
action: 点击辅助按钮的回调函数。 | | onStateChange | (event: { isVisible: boolean }) => void | 否 | 弹窗状态变化事件回调,参数isVisible为弹窗当前的显示状态。 | +| arrowOffset9+ | [Length](ts-types.md#length) | 否 | popup箭头在弹窗处的偏移。箭头在气泡上下方时,默认居左;箭头在气泡左右侧时,默认居上。 | +| showInSubWindow9+ | boolean | 否 | 是否在子窗口显示气泡,默认值为false。 | ## CustomPopupOptions8+类型说明 @@ -32,13 +32,13 @@ | -------------------------| ------------------------- | ---- | ---------------------------------------------------- | | builder | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 提示气泡内容的构造器。 | | placement | [Placement](ts-appendix-enums.md#placement8) | 否 | 气泡组件优先显示的位置,当前位置显示不下时,会自动调整位置。
默认值:Placement.Bottom | -| arrowOffset9+ | [Length](ts-types.md#length) | 否 | popup箭头在弹窗处的偏移。箭头在气泡上下方时,数值为0表示箭头居最左侧,偏移量为箭头至最左侧的距离,默认居中。箭头在气泡左右侧时,偏移量为箭头至最上侧的距离,默认居中。 | -| showInSubWindow9+ | boolean | 否 | 是否在子窗口显示气泡,默认值为false。 | | maskColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 提示气泡遮障层的颜色。 | | popupColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 提示气泡的颜色。 | | enableArrow | boolean | 否 | 是否显示箭头。
从API Version 9开始,如果箭头所在方位侧的气泡长度不足以显示下箭头,则会默认不显示箭头。比如:placement设置为Left,但气泡高度小于箭头的宽度(32vp),则实际不会显示箭头。
默认值:true | | autoCancel | boolean | 否 | 页面有操作时,是否自动关闭气泡。
默认值:true | | onStateChange | (event: { isVisible: boolean }) => void | 否 | 弹窗状态变化事件回调,参数为弹窗当前的显示状态。 | +| arrowOffset9+ | [Length](ts-types.md#length) | 否 | popup箭头在弹窗处的偏移。箭头在气泡上下方时,默认居左;箭头在气泡左右侧时,默认居上。 | +| showInSubWindow9+ | boolean | 否 | 是否在子窗口显示气泡,默认值为false。 | ## 示例 @@ -80,7 +80,7 @@ struct PopupExample { secondaryButton: { value: 'cancel', action: () => { - this.handlePopup = !this.handlePopup; + this.handlePopup = !this.handlePopup console.info('cancel Button click') } }, diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sharp-clipping.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sharp-clipping.md index 31022a190f924f115f28a04a0677333e14d0e823..00fe83401f13a4feded827a272cdba5dad75f4a9 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sharp-clipping.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sharp-clipping.md @@ -53,3 +53,4 @@ struct ClipAndMaskExample { } ``` +![clipAndMask](figures/clipAndMask.PNG) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-touch-target.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-touch-target.md index ffa706268f3bd28b93edaa5944ccca29d365c4ca..aa8a4903a08a0394c911ef53a797789add582904 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-touch-target.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-touch-target.md @@ -40,7 +40,7 @@ @Entry @Component struct TouchTargetExample { - @State text: string = ""; + @State text: string = "" build() { Column({ space: 20 }) { @@ -49,7 +49,7 @@ struct TouchTargetExample { Button("button1") .responseRegion({ x: 0, y: 0, width: '50%', height: '100%' }) .onClick(() => { - this.text = 'button1 clicked'; + this.text = 'button1 clicked' }) // 热区宽度为按钮的一半,且右移一个按钮宽度,点击button2右侧左边,点击事件生效 @@ -57,14 +57,14 @@ struct TouchTargetExample { Button("button2") .responseRegion({ x: '100%', y: 0, width: '50%', height: '100%' }) .onClick(() => { - this.text = 'button2 clicked'; + this.text = 'button2 clicked' }) // 热区大小为整个按钮,且下移一个按钮高度,点击button3下方按钮大小区域,点击事件生效 Text("{x:0,y:'100%',width:'100%',height:'100%'}") Button("button3") .responseRegion({ x: 0, y: '100%', width: '100%', height: '100%' }) .onClick(() => { - this.text = 'button3 clicked'; + this.text = 'button3 clicked' }) Text(this.text).margin({ top: 50 }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md index e80e0321700b9827646268fb4042630ba7b5ef0b..ec171ef02230000c1aad11682469370568732370 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md @@ -14,21 +14,21 @@ | rotate | {
x?: number,
y?: number,
z?: number,
angle?: Angle,
centerX?: number \| string,
centerY?: number \| string
} | (x, y, z)指定一个矢量,表示旋转轴,正角度为顺时针转动,负角度为逆时针转动,默认值为0,同时可以通过centerX和centerY设置旋转的中心点。
默认值:
{
x: 0,
y: 0,
z: 0,
angle: 0,
centerX: '50%',
centerY: '50%'
} | | translate | {
x?: number \| string,
y?: number \| string,
z? : number \| string
} | 可以分别设置X轴、Y轴、Z轴的平移距离,距离的正负控制平移的方向。不支持百分比形式的输入。
默认值:
{
x: 0,
y: 0,
z: 0
}| | scale | {
x?: number,
y?: number,
z?: number,
centerX?: number \| string,
centerY?: number \| string
} | 可以分别设置X轴、Y轴、Z轴的缩放比例,默认值为1,同时可以通过centerX和centerY设置缩放的中心点。
默认值:
{
x: 1,
y: 1,
z: 1,
centerX:'50%',
centerY:'50%'
} | -| transform | Matrix4Transit | 设置当前组件的变换矩阵。 | +| transform | [Matrix4Transit](../apis/js-apis-matrix4.md) | 设置当前组件的变换矩阵。 | ## 示例 ```ts // xxx.ets -import Matrix4 from '@ohos.matrix4' +import matrix4 from '@ohos.matrix4' @Entry @Component struct TransformExample { build() { Column() { - Text('rotate').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(30) + Text('rotate').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(14) Row() .rotate({ x: 1, @@ -37,26 +37,31 @@ struct TransformExample { centerX: '50%', centerY: '50%', angle: 300 - }) // 组件以(1,1,1)为旋转轴,中心点顺时针旋转 300度 + }) // 组件以矢量(1,1,1)为旋转轴,绕中心点顺时针旋转300度 .width(100).height(100).backgroundColor(0xAFEEEE) - Text('translate').width('90%').fontColor(0xCCCCCC).padding(10).fontSize(30) + Text('translate').width('90%').fontColor(0xCCCCCC).padding(10).fontSize(14) Row() - .translate({ x: 100, y: 5 }) // x轴平移100,y轴平移5 - .width(100).height(100).backgroundColor(0xAFEEEE).margin({bottom:10}) + .translate({ x: 100, y: 10 }) // x轴方向平移100,y轴方向平移10 + .width(100).height(100).backgroundColor(0xAFEEEE).margin({ bottom: 10 }) - Text('scale').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(30) + Text('scale').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(14) Row() .scale({ x: 2, y: 0.5 }) // 高度缩小一倍,宽度放大一倍,z轴在2D下无效果 .width(100).height(100).backgroundColor(0xAFEEEE) - Text('Matrix4').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(30) + Text('Matrix4').width('90%').fontColor(0xCCCCCC).padding(15).fontSize(14) Row() .width(100).height(100).backgroundColor(0xAFEEEE) - .transform(Matrix4.identity().translate({ x: 100, y: 100, z: 30 })) + .transform(matrix4.identity().translate({ x: 50, y: 50 }).scale({ x: 1.5, y: 1 }).rotate({ + x: 0, + y: 0, + z: 1, + angle: 60 + })) }.width('100%').margin({ top: 5 }) } } ``` -![zh-cn_image_0000001219864137](figures/zh-cn_image_0000001219864137.png) +![transform](figures/transform.PNG) \ No newline at end of file diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-drag-drop.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-drag-drop.md index 137610753611d3a732559979a46d274c3d8a2d9a..09c1d74aa7bb7ca2ee484ab339996a88825c94fd 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-drag-drop.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-drag-drop.md @@ -50,12 +50,12 @@ @Entry @Component struct DragExample { - @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six']; - @State text: string = ''; - @State bool: boolean = false; - @State appleVisible: Visibility = Visibility.Visible; - @State orangeVisible: Visibility = Visibility.Visible; - @State bananaVisible: Visibility = Visibility.Visible; + @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six'] + @State text: string = '' + @State bool: boolean = false + @State appleVisible: Visibility = Visibility.Visible + @State orangeVisible: Visibility = Visibility.Visible + @State bananaVisible: Visibility = Visibility.Visible // 自定义拖拽过程中显示的内容 @Builder pixelMapBuilder() { @@ -87,10 +87,10 @@ struct DragExample { .backgroundColor(0xAFEEEE) .visibility(this.appleVisible) .onDragStart(() => { - this.bool = true; - this.text = 'apple'; - this.appleVisible = Visibility.None; - return this.pixelMapBuilder; + this.bool = true + this.text = 'apple' + this.appleVisible = Visibility.None + return this.pixelMapBuilder }) Text('orange') .width('25%') @@ -100,10 +100,10 @@ struct DragExample { .backgroundColor(0xAFEEEE) .visibility(this.orangeVisible) .onDragStart(() => { - this.bool = true; - this.text = 'orange'; - this.orangeVisible = Visibility.None; - return this.pixelMapBuilder; + this.bool = true + this.text = 'orange' + this.orangeVisible = Visibility.None + return this.pixelMapBuilder }) Text('banana') .width('25%') @@ -113,11 +113,11 @@ struct DragExample { .backgroundColor(0xAFEEEE) .visibility(this.bananaVisible) .onDragStart((event: DragEvent, extraParams: string) => { - console.log('Text onDragStart, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()); - this.bool = true; - this.text = 'banana'; - this.bananaVisible = Visibility.None; - return this.pixelMapBuilder; + console.log('Text onDragStart, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) + this.bool = true + this.text = 'banana' + this.bananaVisible = Visibility.None + return this.pixelMapBuilder }) }.padding({ top: 10, bottom: 10 }).margin(10) @@ -147,20 +147,20 @@ struct DragExample { .padding(15) .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) .onDragEnter((event: DragEvent, extraParams: string) => { - console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()); + console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDragMove((event: DragEvent, extraParams: string) => { - console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()); + console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDragLeave((event: DragEvent, extraParams: string) => { - console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()); + console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) }) .onDrop((event: DragEvent, extraParams: string) => { var jsonString = JSON.parse(extraParams); if (this.bool) { // 通过splice方法插入元素 - this.numbers.splice(jsonString.insertIndex, 0, this.text); - this.bool = false; + this.numbers.splice(jsonString.insertIndex, 0, this.text) + this.bool = false } }) }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 }) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-key.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-key.md index 2caa55742494f1bcbc26afd7a90ac4b6c98b500e..9d5189505861443501e4bb079ae2526f5c3c3624 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-key.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-key.md @@ -36,20 +36,20 @@ @Entry @Component struct KeyEventExample { - @State text: string = ''; - @State eventType: string = ''; + @State text: string = '' + @State eventType: string = '' build() { Column() { Button('KeyEvent') .onKeyEvent((event: KeyEvent) => { if (event.type === KeyType.Down) { - this.eventType = 'Down'; + this.eventType = 'Down' } if (event.type === KeyType.Up) { - this.eventType = 'Up'; + this.eventType = 'Up' } - this.text = 'KeyType:' + this.eventType + '\nkeyCode:' + event.keyCode + '\nkeyText:' + event.keyText; + this.text = 'KeyType:' + this.eventType + '\nkeyCode:' + event.keyCode + '\nkeyText:' + event.keyText }) Text(this.text).padding(15) }.height(300).width('100%').padding(35) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md index d3ff6dc98d86fb800a524ade36c90514e9540a07..f2a9dc6bf283788e6facda74f53f3f208cce2ebf 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md @@ -19,32 +19,32 @@ ```ts // xxx.ets -import prompt from '@ohos.prompt'; +import prompt from '@ohos.prompt' @Entry @Component struct AppearExample { - @State isShow: boolean = true; - @State changeAppear: string = 'Hide Text'; - private myText: string = 'Text for onAppear'; + @State isShow: boolean = true + @State changeAppear: string = 'Hide Text' + private myText: string = 'Text for onAppear' build() { Column() { Button(this.changeAppear) .onClick(() => { - this.isShow = !this.isShow; + this.isShow = !this.isShow }).margin(15) if (this.isShow) { Text(this.myText).fontSize(26).fontWeight(FontWeight.Bold) .onAppear(() => { - this.changeAppear = 'Hide Text'; + this.changeAppear = 'Hide Text' prompt.showToast({ message: 'The text is shown', duration: 2000 }) }) .onDisAppear(() => { - this.changeAppear = 'Show Text'; + this.changeAppear = 'Show Text' prompt.showToast({ message: 'The text is hidden', duration: 2000 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-touch.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-touch.md index f24bb33026d8b5a126b960bfb387be2a506b8423..5534089ecbe6ea7df5323922809d4e9ab1dca920 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-touch.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-events-touch.md @@ -45,42 +45,42 @@ @Entry @Component struct TouchExample { - @State text: string = ''; - @State eventType: string = ''; + @State text: string = '' + @State eventType: string = '' build() { Column() { Button('Touch').height(40).width(100) .onTouch((event: TouchEvent) => { if (event.type === TouchType.Down) { - this.eventType = 'Down'; + this.eventType = 'Down' } if (event.type === TouchType.Up) { - this.eventType = 'Up'; + this.eventType = 'Up' } if (event.type === TouchType.Move) { - this.eventType = 'Move'; + this.eventType = 'Move' } this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: ' + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:(' + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:' - + event.target.area.width + '\nheight:' + event.target.area.height; + + event.target.area.width + '\nheight:' + event.target.area.height }) Button('Touch').height(50).width(200).margin(20) .onTouch((event: TouchEvent) => { if (event.type === TouchType.Down) { - this.eventType = 'Down'; + this.eventType = 'Down' } if (event.type === TouchType.Up) { - this.eventType = 'Up'; + this.eventType = 'Up' } if (event.type === TouchType.Move) { - this.eventType = 'Move'; + this.eventType = 'Move' } this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: ' + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:(' + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:' - + event.target.area.width + '\nheight:' + event.target.area.height; + + event.target.area.width + '\nheight:' + event.target.area.height }) Text(this.text) }.width('100%').padding(30) diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-focus-event.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-focus-event.md index 3f9aa271b4b137b384542758d11a5815086e1c34..8da2d801d8da08ef4d43be199eca9e23301a665a 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-focus-event.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-focus-event.md @@ -24,9 +24,9 @@ @Entry @Component struct FocusEventExample { - @State oneButtonColor: string = '#FFC0CB'; - @State twoButtonColor: string = '#87CEFA'; - @State threeButtonColor: string = '#90EE90'; + @State oneButtonColor: string = '#FFC0CB' + @State twoButtonColor: string = '#87CEFA' + @State threeButtonColor: string = '#90EE90' build() { Column({ space: 20 }) { @@ -38,10 +38,10 @@ struct FocusEventExample { .fontColor(Color.Black) .focusable(true) .onFocus(() => { - this.oneButtonColor = '#FF0000'; + this.oneButtonColor = '#FF0000' }) .onBlur(() => { - this.oneButtonColor = '#FFC0CB'; + this.oneButtonColor = '#FFC0CB' }) Button('Second Button') .backgroundColor(this.twoButtonColor) @@ -50,10 +50,10 @@ struct FocusEventExample { .fontColor(Color.Black) .focusable(true) .onFocus(() => { - this.twoButtonColor = '#FF0000'; + this.twoButtonColor = '#FF0000' }) .onBlur(() => { - this.twoButtonColor = '#87CEFA'; + this.twoButtonColor = '#87CEFA' }) Button('Third Button') .backgroundColor(this.threeButtonColor) @@ -62,10 +62,10 @@ struct FocusEventExample { .fontColor(Color.Black) .focusable(true) .onFocus(() => { - this.threeButtonColor = '#FF0000'; + this.threeButtonColor = '#FF0000' }) .onBlur(() => { - this.threeButtonColor = '#90EE90'; + this.threeButtonColor = '#90EE90' }) }.width('100%').margin({ top: 20 }) } diff --git a/zh-cn/application-dev/reference/errorcodes/errcode-DistributedSchedule.md b/zh-cn/application-dev/reference/errorcodes/errcode-DistributedSchedule.md index 01e19e15adf51882c02d5e484291087bac7c8cbf..49ef0e73a0ec747d6160e18c7885029dbb5f975a 100644 --- a/zh-cn/application-dev/reference/errorcodes/errcode-DistributedSchedule.md +++ b/zh-cn/application-dev/reference/errorcodes/errcode-DistributedSchedule.md @@ -1,345 +1,375 @@ # DistributedSchedule错误码 -## 201 权限校验失败 - -### 错误信息 -Permission denied. - -### 错误描述 - -当调用流转管理和迁移等接口时,若缺少ohos.permission.MANAGER_MISSIONS或ohos.permission.DISTRIBUTED_DATASYNC,会报此错误码。 - -### 可能原因 -该错误码表示权限校验失败,可能原因是未配置对应权限。 - -### 处理步骤 -配置权限ohos.permission.MANAGER_MISSIONS或ohos.permission.DISTRIBUTED_DATASYNC。 - -## 401 参数检查错误 - -### 错误信息 -The parameter check failed. - -### 错误描述 - -当调用接口提供的入参出现类型、个数、数组大小以及合法性等错误时,会报此错误码。 - -### 可能原因 -该错误码表示入参检查错误,可能原因是callback入参检查错误。 - -### 处理步骤 -检查入参callback是否为合法值。 - ## 16600001 系统服务工作异常 -### 错误信息 -The system ability work abnormally. +**错误信息** + +The system ability works abnormally. -### 错误描述 +**错误描述** 当系统服务工作异常时,会报此错误码。 -### 可能原因 +**可能原因** + 该错误码表示系统服务工作异常,可能原因如下。 1. DMS服务没有正常启动。 2. DMS的binder对象无法正常获取。 3. 流转依赖的其他服务没有正常启动或者binder对象无法获取。 -### 处理步骤 +**处理步骤** + 系统服务内部工作异常,请稍后重试,或者重启设备尝试。 ## 16600002 指定的token或callback未注册 -### 错误描述 +**错误描述** 当调用continuationManager相关的接口时传入的token或callback未提前注册,会报此错误码。 -### 错误信息 -The specified token or callback has not registered. +**错误信息** + +The specified token or callback is not registered. + +**可能原因** -### 可能原因 该错误码可能原因是指定的token或callback未注册。 -### 处理步骤 +**处理步骤** + 请先注册token或callback。 ## 16600003 应用注册token已达到最大次数限制 -### 错误描述 +**错误描述** 当调用continuationManager.registerContinuation接口时次数过多超出限制,会报此错误码。 -### 错误信息 +**错误信息** + The number of token registration times has reached the upper limit. -### 可能原因 +**可能原因** + 该错误码可能原因是应用注册token已达到最大次数限制。 -### 处理步骤 +**处理步骤** + 请勿频繁注册,请使用已注册的token。 ## 16600004 指定的callback已注册 -### 错误描述 +**错误描述** 当使用相同的callback调用continuationManager的on接口时,会报此错误码。 -### 错误信息 +**错误信息** + The specified callback has been registered. -### 可能原因 +**可能原因** + 该错误码表示指定的callback已注册,可能原因是使用相同的callback重复注册。 -### 处理步骤 +**处理步骤** + 请勿使用相同的callback重复注册。 ## 16300501 系统服务工作异常 -### 错误描述 +**错误描述** 当系统服务工作异常时,会报此错误码。 -### 错误信息 -The system ability work abnormally. +**错误信息** + +The system ability works abnormally. + +**可能原因** -### 可能原因 该错误码表示系统服务工作异常,可能原因如下。 1. DMS服务没有正常启动。 2. DMS的binder对象无法正常获取。 3. 流转依赖的其他服务没有正常启动或者binder对象无法获取。 -### 处理步骤 +**处理步骤** + 系统服务内部工作异常,请稍后重试,或者重启设备尝试。 ## 16300502 获取指定的missionId的missionInfo失败 -### 错误描述 +**错误描述** 当调用distributedMissionManager.continueMission接口获取指定missionId的missionInfo失败时,会报此错误码。 -### 错误信息 +**错误信息** + Failed to get the missionInfo of the specified missionId. -### 可能原因 +**可能原因** + 该错误码表示获取指定的missionId的missionInfo失败,可能原因如下。 1. missionId输入错误。 2. missionId对应的missionInfo确实不存在。 -### 处理步骤 +**处理步骤** + 请检查输入的missionId是否正确。 ## 16300503 远端未安装应用且不支持免安装 -### 错误描述 +**错误描述** 当调用distributedMissionManager.continueMission接口使用迁移功能时,若远端未安装应用且不支持免安装,会报此错误码。 -### 错误信息 +**错误信息** + The application is not installed on the remote end and installation-free is not supported. -### 可能原因 +**可能原因** + 该错误码可能原因是远端未安装迁移应用并且不支持免安装。 -### 处理步骤 +**处理步骤** + 1. 请检查远端是否已安装需要迁移的应用。 2. 请检查远端是否支持免安装。 ## 16300504 远端未安装应用但支持免安装,需使用免安装标识重试 -### 错误描述 +**错误描述** 当调用distributedMissionManager.continueMission接口使用迁移功能时,若远端未安装应用但支持免安装,会报此错误码。 -### 错误信息 -The application is not installed on the remote end but installation-free is supported, try again with freeInstall flag. +**错误信息** + +The application is not installed on the remote end and installation-free is supported. Try again with the freeInstall flag. + +**可能原因** -### 可能原因 该错误码可能原因是远端未安装应用但支持免安装,使用时未使用免安装的标识。 -### 处理步骤 +**处理步骤** + 请使用免安装的标识重试。 ## 16300505 操作设备必须是迁移的应用所在的设备或需迁移到的目标设备 -### 错误描述 +**错误描述** 当调用distributedMissionManager.continueMission接口使用迁移功能时,若操作设备不是迁移的应用所在的设备或需迁移到的目标设备,会报此错误码。 -### 错误信息 -The operation device must be the device where the application to be continued is located or the target device to be continued. +**错误信息** + +The operation device must be the device where the application to be continued is currently located or the target device. + +**可能原因** -### 可能原因 该错误码可能原因是操作设备不是迁移的应用所在的设备或需迁移到的目标设备。 -### 处理步骤 +**处理步骤** + 请检查操作设备是否是迁移的应用所在的设备或需迁移到的目标设备。 ## 16300506 本地迁移任务已在进行中 -### 错误描述 +**错误描述** 当调用distributedMissionManager.continueMission接口使用迁移功能时,若本地迁移任务已在进行中,会报此错误码。 -### 错误信息 +**错误信息** + The local continuation task is already in progress. -### 可能原因 +**可能原因** + 该错误码表示本地迁移任务已在进行中,可能原因是已经发起了迁移任务还未结束。 -### 处理步骤 +**处理步骤** + 请检查是否已经发起了迁移并未结束。 ## 3 序列化对象失败 -### 错误描述 +**错误描述** 当调用continuationManager相关接口时,若系统参数DMS_PROXY_INTERFACE_TOKEN序列化写失败,会报此错误码。 -### 错误信息 +**错误信息** + Failed to flatten the object. -### 可能原因 +**可能原因** + 该错误码表示对象序列化过程中出现错误,可能原因是系统参数DMS_PROXY_INTERFACE_TOKEN序列化写失败。 -### 处理步骤 +**处理步骤** + 请检查系统功能是否正常或者重启。 ## 7 空对象 -### 错误信息 +**错误信息** + The object is null. -### 错误描述 +**错误描述** 当调用流转和迁移相关接口时,若出现dms以及其他对象为空或序列化读失败,会报此错误码。 -### 可能原因 +**可能原因** + 该错误码表示接口依赖的服务对象或参数对象为空,可能原因如下。 1. 入参序列化读失败。 2. DMS服务没有正常启动或binder对象无法正常获取。 3. DMS依赖的其他服务没有正常启动或者binder对象无法获取。 -### 处理步骤 +**处理步骤** + 1. 检查入参是否为有效合法值。 2. 检查DMS服务是否正常启动,重新启动服务或重启设备。 3. 检查DMS依赖的其他服务是否正常启动,重新启动服务或重启设备。 ## 29360207 注册超出最大次数 -### 错误描述 +**错误描述** 当调用continuationManager.register接口时次数过多超出限制,会报此错误码。 -### 错误信息 -The maximum number of registrations exceeded. +**错误信息** + +The number of registrations has reached the upper limit. + +**可能原因** -### 可能原因 该错误码可能原因是设备频繁注册,次数超出最大次数限制。 -### 处理步骤 +**处理步骤** + 重启服务并且避免频繁注册。 ## 29360208 token未注册 -### 错误描述 +**错误描述** 当调用continuationManager相关接口时使用未注册的token,会报此错误码。 -### 错误信息 -The token has not registered. +**错误信息** + +The token is not registered. + +**可能原因** -### 可能原因 该错误码可能原因是未注册token。 -### 处理步骤 +**处理步骤** + 注册token并使用已注册的token。 ## 29360209 callback已注册 -### 错误描述 +**错误描述** 当使用相同的callback重复调用continuationManager.on接口时,会报此错误码。 -### 错误信息 -Callback has been registered. +**错误信息** + +The callback has been registered. + +**可能原因** -### 可能原因 该错误码能原因是指定的callback已经注册过。 -### 处理步骤 +**处理步骤** + 请勿使用相同的callback重复注册。 ## 29360210 callback未注册 -### 错误描述 +**错误描述** 当调用continuationManager的off、updateConnectStatus和startDeviceManager等接口时,若未提前调用on接口注册callback,会报此错误码。 -### 错误信息 -Callback has not been registered. +**错误信息** + +The callback is not registered. + +**可能原因** -### 可能原因 该错误码可能原因是指定的callback未注册。 -### 处理步骤 +**处理步骤** + 注册callback并使用已注册的callback。 ## 29360211 连接ability失败 -### 错误描述 +**错误描述** 当调用continuationManager的startDeviceManager接口时,若连接相应Ability失败时,会报此错误码。 -### 错误信息 -Failed to connect ability. +**错误信息** + +Failed to connect to the ability. + +**可能原因** -### 可能原因 该错误码可能原因是指定token连接ability失败。 -### 处理步骤 +**处理步骤** + 检查token是否有效以及相应ability是否正常服务,重新启动服务或重启设备。 ## 29360214 callback类型错误 -### 错误描述 +**错误描述** 当调用continuationManager的on和off接口时,若参数callback类型错误时,会报此错误码。 -### 错误信息 +**错误信息** + The type of callback is not supported. -### 可能原因 +**可能原因** + 该错误码表示callback类型错误,可能原因是不支持传入的callback类型。 -### 处理步骤 +**处理步骤** + 请使用系统支持的callback类型并传入。 ## 29360215 无效的连接状态 -### 错误描述 +**错误描述** 当调用continuationManager的updateConnectStatus接口时,若参数status为无效值时,会报此错误码。 -### 错误信息 -Invalid connect state. +**错误信息** + +Invalid connection state. + +**可能原因** -### 可能原因 该错误码表示无效的连接状态,可能原因是入参DeviceConnectState为非指定值。 -### 处理步骤 +**处理步骤** + 设置指定合法的DeviceConnectState值。 ## 29360216 无效的流转模式 -### 错误描述 +**错误信息** + +Invalid continuation mode. + +**错误描述** 当调用continuationManager的register和startDeviceManager接口时,若参数ContinuationExtraParams.continuationMode为无效值时,会报此错误码。 -### 错误信息 -Invalid continuation mode. +**可能原因** -### 可能原因 该错误码可能原因是入参ContinuationExtraParams.continuationMode为非指定值。 -### 处理步骤 +**处理步骤** + 设置指定合法的ContinuationExtraParams.continuationMode值。 diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-audio.md b/zh-cn/application-dev/reference/errorcodes/errorcode-audio.md new file mode 100644 index 0000000000000000000000000000000000000000..96e986813706ea59bcb629891e821f561fe2a72a --- /dev/null +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-audio.md @@ -0,0 +1,132 @@ +# Audio错误码 + +## 6800101 无效入参 + +**错误信息** + +invalid parameter. + +**错误描述** + +调用接口时,传入的参数无效。 + +**可能原因** + +参数无效,比如值不在边界范围内,没有使用指定的枚举范围等。 + +**处理步骤** + +根据接口文档,传入正确的入参。 + +## 6800102 分配内存失败 + +**错误信息** + +allocate memory failed. + +**错误描述** + +调用接口时,分配内存失败或者出现空指针。 + +**可能原因** + +1. 系统内存压力大,没有足够的内存用来映射。 +2. 对于失效的实例,没有及时销毁释放内存。 + +**处理步骤** + +1. 销毁当前实例。 +2. 重新创建实例,如果重新创建失败,则停止相关操作。 + +## 6800103 状态不支持 + +**错误信息** + +Operation not permit at current state. + +**错误描述** + +当前状态不支持此操作。 + +**可能原因** + +当前状态机不支持操作。比如未启动流就播放数据等。 + +**处理步骤** + +1. 确认当前状态是否支持当前操作。 +2. 把实例切换到正确的状态进行正确的操作。 + +## 6800104 参数选项不支持 + +**错误信息** + +unsupported operation. + +**错误描述** + +参数选项不支持。 + +**可能原因** + +入参选值不在系统支持规格范围内。 + +**处理步骤** + +1. 确认当前api支持的枚举或其他入参。 +2. 改用支持的参数选项。 + +## 6800105 处理超时 + +**错误信息** + +time out. + +**错误描述** + +等待处理超时。 + +**可能原因** + +等待外部处理超时,比如等待应用填写音频数据超时。 + +**处理步骤** + +控制数据填写的时间,例如增加延迟处理。 + +## 6800201 音频流数量达到极限 + +**错误信息** + +stream number limited. + +**错误描述** + +达到系统可支持的最大数量。 + +**可能原因** + +无效的音频流没有及时释放。 + +**处理步骤** + +释放其他不再使用的音频流资源。 + +## 6800301 系统处理异常 + +**错误信息** + +system error. + +**错误描述** + +系统处理异常。 + +**可能原因** + +系统处理异常,比如系统服务重启、跨进程调用异常等。 + +**处理步骤** + +系统内部通用错误,出现的情况不明确,建议尝试重新创建业务。 + diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-geoLocationManager.md b/zh-cn/application-dev/reference/errorcodes/errorcode-geoLocationManager.md new file mode 100644 index 0000000000000000000000000000000000000000..59e55fbac0939b26f787555c7d46be6bb9158b03 --- /dev/null +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-geoLocationManager.md @@ -0,0 +1,157 @@ +# 位置服务子系统错误码 + +## 3301000 位置服务不可用 + +**错误信息** + +Location service is unavailable. + +**错误描述** + +位置服务不可用,位置服务相关的接口无法调用. + +**可能原因** + +1.位置服务启动异常,导致应用和位置服务子系统通信失败,导致位置服务不可用. + +2.GNSS芯片初始化失败导致GNSS定位功能失效. + +3.网络定位服务异常,导致网络定位功能失效. + +**处理步骤** + +请停止调用该接口. + +## 3301100 位置功能的开关未开启导致功能失败 + +**错误信息** + +The location switch is off. + +**错误描述** + +位置功能的开关未开启导致功能失败. + +**可能原因** + +位置功能的开关未开启,导致持续定位,单次定位等基本功能不可用. + +**处理步骤** + +请提示用户开启位置功能的开关. + +## 3301200 定位失败,未获取到定位结果 + +**错误信息** + +Failed to obtain the geographical location. + +**错误描述** + +定位失败,未获取到定位结果. + +**可能原因** + +1.GNSS信号弱,导致定位超时. + +2.网络定位异常导致定位超时. + +**处理步骤** + +请重新发起定位请求. + +## 3301300 逆地理编码查询失败 + +**错误信息** + +Reverse geocoding query failed. + +**错误描述** + +逆地理编码查询失败. + +**可能原因** + +数据网络比较卡顿,导致端侧的请求发送失败或者云端的结果未返回到端侧. + +**处理步骤** + +请重试逆地理编码查询. + +## 3301400 地理编码查询失败 + +**错误信息** + +Geocoding query failed. + +**错误描述** + +地理编码查询失败. + +**可能原因** + +数据网络比较卡顿,导致端侧的请求发送失败或者云端的结果未返回到端侧. + +**处理步骤** + +请重试地理编码查询. + +## 3301500 区域信息(包含国家码)查询失败 + +**错误信息** + +Failed to query the area information. + +**错误描述** + +区域信息(包含国家码)查询失败. + +**可能原因** + +未查询到正确的区域信息. + +**处理步骤** + +请停止调用查询区域码的接口. + +## 3301600 地理围栏操作失败 + +**错误信息** + +Failed to operate the geofence. + +**错误描述** + +地理围栏操作失败,包含添加,删除,暂停和恢复等操作. + +**可能原因** + +1.GNSS芯片不支持地理围栏功能. + +2.底层业务逻辑异常导致操作地理围栏失败. + +**处理步骤** + +请停止调用地理围栏操作接口. + +## 3301700 请求无响应 + +**错误信息** + +No response to the request. + +**错误描述** + +某些异步请求需要用户点击按钮确认,或者需要GNSS芯片和网络服务器响应,这些场景下未收到响应导致业务失败. + +**可能原因** + +1.用户未点击按钮确认. + +2.GNSS芯片未响应. + +3.网络服务器未响应. + +**处理步骤** + +请停止调用相关接口. \ No newline at end of file diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-nfc.md b/zh-cn/application-dev/reference/errorcodes/errorcode-nfc.md new file mode 100644 index 0000000000000000000000000000000000000000..d6763eebdda0b57f0090abfd2da966f7d31dc40e --- /dev/null +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-nfc.md @@ -0,0 +1,44 @@ +# NFC错误码 + +## 3100101 + +**错误信息** + +NFC opening or closing state is abnormal in service. + +**错误描述** + +NFC服务内部执行NFC打开或关闭异常。 + +**可能原因** + +和NFC服务建立通信异常。 + +**处理步骤** + +重新执行打开或关闭NFC。 + +## 3100201 + +**错误信息** + +Tag running state is abnormal in service. + +**错误描述** + +NFC服务执行Tag业务逻辑遇到错误。 + +**可能原因** +1. Tag参数值和实际调用函数要求不匹配。 +2. Tag操作时,NFC状态是关闭的。 +3. Tag操作前,已经处在断开状态。 +4. Tag芯片返回错误状态或响应超时。 +5. 和NFC服务没有建立绑定关系,无法调用接口。 + +**处理步骤** +1. 检查NFC参数是否和所调用接口匹配。 +2. 打开设备NFC。 +3. 先调用连接,再执行读写操作。 +4. 重新触碰读取卡片。 +5. 退出应用后,重新读取卡片。 + diff --git a/zh-cn/application-dev/security/cryptoFramework-guidelines.md b/zh-cn/application-dev/security/cryptoFramework-guidelines.md index 734dcf92c03846e7755e29005c5fd9914d5a3195..a282c7b7c6113719ca57af818846887e20ce5f19 100644 --- a/zh-cn/application-dev/security/cryptoFramework-guidelines.md +++ b/zh-cn/application-dev/security/cryptoFramework-guidelines.md @@ -100,21 +100,17 @@ function testGenerateAesKey() { 示例3:根据指定的RSA非对称密钥二进制数据,生成KeyPair对象(场景2) -1. 获取RSA二进制密钥数据封装成DataBlob对象,按keysize(32位的密钥位数) 、nsize(32位,值为keysize/8)、 esize(32位的大数e的实际长度,单位Byte)、dsize(32位,值位keysize/8)、nval(大数n的二进制数据)、eval(大数e的二进制数据)和dval(大数d的二进制数据)拼接形成。 -2. 调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。 +1. 获取RSA公钥或私钥二进制数据,公钥需满足ASN.1语法、X.509规范、DER编码格式,私钥需满足ASN.1语法、PKCS#8规范、DER编码格式。 +2. 创建AsyKeyGenerator对象,调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。 ```javascript import cryptoFramework from '@ohos.security.cryptoFramework'; function convertAsyKey() { - let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024"); - // 公钥二进制数据 - let pkval = new Uint8Array([0,4,0,0,128,0,0,0,3,0,0,0,0,0,0,0,182,22,137,81,111,129,17,47,33,97,67,85,251,53,127,42,130,150,93,144,129,104,14,73,110,189,138,82,53,74,114,86,24,186,143,65,87,110,237,69,206,207,5,81,24,32,41,160,209,125,162,92,0,148,49,241,235,0,71,198,1,28,136,106,152,22,25,249,77,241,57,149,154,44,200,6,0,83,246,63,162,106,242,131,80,227,143,162,210,28,127,136,123,172,26,247,2,194,16,1,100,122,180,251,57,22,69,133,232,145,107,66,80,201,151,46,114,175,116,57,45,170,188,77,86,230,111,45,1,0,1]); - // 封装成DataBlob对象 + let rsaGenerator = cfm.createAsyKeyGenerator("RSA1024"); + let pkval = new Uint8Array([48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,174,203,113,83,113,3,143,213,194,79,91,9,51,142,87,45,97,65,136,24,166,35,5,179,42,47,212,79,111,74,134,120,73,67,21,19,235,80,46,152,209,133,232,87,192,140,18,206,27,106,106,169,106,46,135,111,118,32,129,27,89,255,183,116,247,38,12,7,238,77,151,167,6,102,153,126,66,28,253,253,216,64,20,138,117,72,15,216,178,37,208,179,63,204,39,94,244,170,48,190,21,11,73,169,156,104,193,3,17,100,28,60,50,92,235,218,57,73,119,19,101,164,192,161,197,106,105,73,2,3,1,0,1]); let pkBlob = {data : pkval}; - // 调用密钥转换函数 - let convertKeyPromise = rsaGenerator.convertKey(pkBlob, null); - convertKeyPromise.then( keyPair => { + rsaGenerator.convertKey(pkBlob, null, function(err, keyPair) { if (keyPair == null) { AlertDialog.show({message : "Convert keypair fail"}); } @@ -125,10 +121,7 @@ function convertAsyKey() { **说明** -1. nsize和dsize为密钥位数/8,esize为具体的实际长度。 -2. 私钥材料需要包含keysize,nsize,esize,dsize,nval,eval,dval的全部数据,公钥材料中dsize设置为为0,缺省dval的数据。 -3. 公钥和私钥二进制数据为可选项,可单独传入公钥或私钥的数据,生成对应只包含公钥或私钥的KeyPair对象。 -4. keysize、nsize、esize和dsize为32位二进制数据,数据的大小端格式请按设备CPU默认格式,密钥材料(nval、eval、dval)统一为大端格式。 + 当前convertKey操作,公钥只支持转换满足X.509规范的DER格式,私钥只支持PKCS#8规范的DER格式; 示例4:根据指定的ECC非对称密钥二进制数据,生成KeyPair对象(场景2、3) @@ -545,6 +538,12 @@ function encryptMessageCallback() { } ``` +**说明** + +1. 使用RSA加解密时,Cipher对象不可重复调用init方法初始化,在创建了一个加密Cipher对象后,如果要进行解密,则需要重新创建另一个Cipher对象执行解密操作。 +2. RSA加密有长度限制,允许加密明文的最大长度见[加解密算法库框架概述](cryptoFramework-overview.md)中的基本概念章节。 +3. RSA解密每次允许解密的密文长度为,RSA密钥的位数/8。 + ## 使用签名验签操作 **场景说明** diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-routes.md b/zh-cn/application-dev/ui/ui-js-building-ui-routes.md index c3746e228c5869e14179969fbb4801c3425fa79f..0c1f7da4095e6caaf12416a2aaac76aa03a7fbb8 100644 --- a/zh-cn/application-dev/ui/ui-js-building-ui-routes.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-routes.md @@ -6,7 +6,7 @@ 页面路由router根据页面的uri找到目标页面,从而实现跳转。以最基础的两个页面之间的跳转为例,具体实现步骤如下: -1. 在“Project“窗口,打开entry > src > mainjsdefault,右键点击pages文件夹,选择NewJS Page,创建一个详情页。 +1. 在“Project“窗口,打开src > main >js >MainAbility,右键点击pages文件夹,选择NewJS Page,创建一个详情页。 2. 调用router.push()路由到详情页。 @@ -42,6 +42,8 @@ index和detail这两个页面均包含一个text组件和button组件:text组 /* index.css */ /* detail.css */ .container { + width: 100%; + height: 100%; flex-direction: column; justify-content: center; align-items: center; @@ -60,11 +62,11 @@ index和detail这两个页面均包含一个text组件和button组件:text组 ```js // index.js -import router from '@system.router'; +import router from '@ohos.router'; export default { launch() { router.push ({ - uri: 'pages/detail/detail', + url: 'pages/detail/detail', }); }, } @@ -72,7 +74,7 @@ export default { ```js // detail.js -import router from '@system.router'; +import router from '@ohos.router'; export default { launch() { router.back(); diff --git a/zh-cn/contribute/prebuilts-readme-template.md b/zh-cn/contribute/prebuilts-readme-template.md new file mode 100644 index 0000000000000000000000000000000000000000..0e30f1a9788b6311c774c298bc29bf9f1185a336 --- /dev/null +++ b/zh-cn/contribute/prebuilts-readme-template.md @@ -0,0 +1,28 @@ +OpenHarmony中的Clang/LLVM-based预编译工具 说明 +==================================================== + +1. 获取最新版本的说明文档,请参考如下: +[基于Clang/LLVM-based OpenHarmony工具说明文档](https://gitee.com/openharmony/third_party_llvm-project/blob/master/llvm-build/README.md) + +2. 构建指导 +------------------ + +``` +# 获取代码 +repo init -u https://gitee.com/openharmony/manifest.git -b llvm_toolchain-dev +repo sync -c +repo forall -c 'git lfs pull' +cp -r toolchain/llvm-project/llvm-build toolchain + +# 编译基于Clang/LLVM的 prebuilts工具 +./toolchain/llvm-project/llvm-build/env_prepare.sh +python3 ./toolchain/llvm-build/build.py +``` + +3. 更新预编译工具 +---------------- +在OpenHarmony项目中运行脚本: + +``` +$ ./build/prebuilts_download.sh +``` diff --git "a/zh-cn/contribute/\347\254\254\344\270\211\346\226\271\345\274\200\346\272\220\350\275\257\344\273\266\345\274\225\345\205\245\346\214\207\345\257\274.md" "b/zh-cn/contribute/\347\254\254\344\270\211\346\226\271\345\274\200\346\272\220\350\275\257\344\273\266\345\274\225\345\205\245\346\214\207\345\257\274.md" index 32cc3b647502e1862a928f76b02847f8b0a2b620..8092b528d1960f5a83df17416cded1c565b37c32 100755 --- "a/zh-cn/contribute/\347\254\254\344\270\211\346\226\271\345\274\200\346\272\220\350\275\257\344\273\266\345\274\225\345\205\245\346\214\207\345\257\274.md" +++ "b/zh-cn/contribute/\347\254\254\344\270\211\346\226\271\345\274\200\346\272\220\350\275\257\344\273\266\345\274\225\345\205\245\346\214\207\345\257\274.md" @@ -40,6 +40,22 @@ OpenHarmony遵从 [Open Source Definition](https://opensource.org/docs/osd) , 12. 引入新的开源软件存在依赖其他开源软件时,不允许将被动依赖软件嵌套在引入的新的开源软件子目录中,必须剥离所有依赖软件项,并将其分别放置到单独的代码仓,命名统一为third_party_依赖软件名称,原因是嵌套放置依赖软件可能导致多同一款软件多版本、旧版本安全漏洞无法及时修复、开源义务履行合规的风险问题。 - 依赖软件在编译构建部件命名,将新引入的主软件名作为依赖软件部件前缀命名,例如 part_name = "新引入主软件名_依赖软件名" - 新引入软件和依赖软件分别独立构建,通过external_deps来解决部件间依赖。 +13. OpenHarmony对引入三方开源软件的归档目录要求: + - 原则上如果您没有真正充分的理由将其存储在其他地方,且满足OpenHarmony许可证引入要求三方开源软件,统一归属于third_party根目录下; + - 针对开发板引入且无法纳入OpenHarmony系统平台的三方开源软件,可以申请在以下位置存档,要求以上游开源软件名创建目录,并在对应目录下归档README.OpenSource说明文档;采取BUILD.gn方式独立构建,支撑开源义务声明信息的自动收集。 + + ``` + device/soc/$(SOC_COMPANY)/third_party + device/board/$(BOARD_COMPANY)/third_party + vendor/$(PRODUCT_COMPANY)/third_party + ``` + +14. OpenHarmony平台版本或版本构建中用到的预编译二进制或工具链,需提供如下信息: + - 预编译二进制或工具链对应的源码,需要在OpenHarmony社区托管对应的源代码,并提供对应的构建指导,开源义务履行遵从指导; + - 预编译二进制或工具链中引入的开源三方软件,需要遵从原则1~13; + - [预编译二进制或工具链的说明文档](./prebuilts-readme-template.md):包括源码获取地址、构建指导、更新方法,随OpenHarmony版本或工具链归档到对应模块的根目录中; + - 预编译的二进制或工具链对应的根目录需要提供完整开源义务履行声明文档; + - 如果预编译文件来源于上游社区托管平台的二进制(譬如npm包等)。我们需要在归档二进制的地方提供以下信息,首先我们需要提供一个命名为**README**概要性描述文件,内容包括引入的背景描述和其官方托管地址;其次我们需要提供一个命名为**NOTICE**的开源义务履行声明的描述文件,内容包括其中涉及的没一个开源软件名称、版本号、以及对应的开源许可协议。 ### 软件引入流程 @@ -47,7 +63,7 @@ OpenHarmony遵从 [Open Source Definition](https://opensource.org/docs/osd) , | 检查项 | 说明 | | :----- | :----- | -| 归一化 | 1、检查该软件在OpenHarmony中是否已存在,原则上一款软件只在OpenHarmony中引入一次。 | +| 归一化 | 1、检查该软件在OpenHarmony中是否已存在,原则上一款软件只在OpenHarmony中引入一次。| | 来源可靠 | 1、应该从开源软件官网获取或官网指定的代码托管地址获取。 | | 社区活跃 | 1、软件来自知名社区或组织,社区或组织通过发布公告、修改软件仓库状态、将仓库放到特定目录下等方式告知停止维护的,不建议引入。
2、软件来自个人、小型社区或组织,两年内未发布版本(含正式版本与测试版本),无明确版本计划,社区提交了有效的Bug或PR,但是半年以上未响应的,不建议引入。
3、社区运营状态不明确,通过Issue 或者邮件等方式询问社区是否继续维护,半年以上未响应或者答复停止维护的,不建议引入。| | 安全漏洞 | 1、检索业界已知公开的安全漏洞,如有高危漏洞需要有应对方案。| @@ -61,13 +77,13 @@ OpenHarmony遵从 [Open Source Definition](https://opensource.org/docs/osd) , 1、自检表 -| 检查项 | 填写指导 | 自检结果示例 | +| 检查项 | 填写指导 | 自检结果示例 | | :----- | :----- | :----- | | 软件名 | 描述该软件官方名称以及引入后的仓名,仓名统一为**third_party**_**加上官方软件名称** | third_party_**softwarename** | -| 软件官网地址 | 描述该软件官方网站链接地址 | https://softwaresite | +| 软件官网地址 | 描述该软件官方网站链接地址 | | | 软件版本号 | 描述该软件要引入的版本号,版本号为其社区正式发布的版本号,不要随意修改;未正式发布的版本不建议引入 | 1.0.0 | | 软件版本发布日期 | 描述该软件要引入的版本的社区发布日期 | 2021.01.01 | -| 软件版本地址 | 描述该版本的官方下载链接地址,注意该地址必须为能定位到该具体版本发布包的下载URL | https://gitee.com/softwarecodesite/v1.0.0.zip | +| 软件版本地址 | 描述该版本的官方下载链接地址,注意该地址必须为能定位到该具体版本发布包的下载URL | | | 软件许可证 | 描述该版本的官方许可证名称及许可证文件的相对路径,如果是多许可证要完整描述,并说明各许可证的关系,如是And还是Or,或者是不同目录对应不同许可证 | Apache-2.0 | | 软件生命周期 | 描述该软件是否有LTS版本,多长时间发布一个版本,最近一年社区代码提交及Issue解决情况,是否有告知停止维护或演进 | 无LTS版本,6个月发布一个版本,近6个月有10次代码提交 | | 软件安全漏洞 | 描述该软件存在的业界公开的安全漏洞列表,包括漏洞号、级别、漏洞链接地址、是否已有补丁或解决方案 | 无业界公开漏洞 | @@ -78,7 +94,7 @@ OpenHarmony遵从 [Open Source Definition](https://opensource.org/docs/osd) , 说明: -- OAT工具的使用方式请参考 https://gitee.com/openharmony-sig/tools_oat ,如对工具有改进建议请直接在社区提交ISSUE,也可Fork下来完善工具并提交PR。 +- OAT工具的使用方式请参考 ,如对工具有改进建议请直接在社区提交ISSUE,也可Fork下来完善工具并提交PR。 - OAT报告原则上应当是清零,格式如下: ``` @@ -100,7 +116,7 @@ third_party_abcde/doc/ LICENSEFILE LICENSE Apache-2.0 2、OAT.xml文件 -请参考 https://gitee.com/openharmony-sig/tools_oat/blob/master/README_zh.md ,完成OAT扫描问题确认及OAT.xml文件配置,申请中附上此文件内容(如果无任何需确认问题则无需配置)。 +请参考 ,完成OAT扫描问题确认及OAT.xml文件配置,申请中附上此文件内容(如果无任何需确认问题则无需配置)。 3、该仓的README.OpenSource文件内容,格式如下: @@ -121,9 +137,9 @@ third_party_abcde/doc/ LICENSEFILE LICENSE Apache-2.0 ] ``` -#### PMC评审 +#### 新增三方开源软件评审 -参考[SIG管理章程](https://gitee.com/openharmony/community/tree/master/sig),PMC会根据收到的PR统一安排SIG申请评审以及建仓。 +参考[SIG-Architecture](https://gitee.com/openharmony/community/blob/master/sig/sig-architecture/sig-architecture_cn.md),SIG-Architecture会统一安排建仓评审。 ### 第三方开源软件许可证要求 @@ -131,66 +147,66 @@ third_party_abcde/doc/ LICENSEFILE LICENSE Apache-2.0 2. 第三方开源软件许可证必须与使用该开源软件的代码仓许可证兼容。 3. 如下类型许可证可以引入到OpenHarmony项目中: -* Apache License 2.0 -* Mulan Permissive Software License, Version 2 -* BSD 2-clause -* BSD 3-clause -* DOM4J License -* PostgreSQL License -* Eclipse Distribution License 1.0 -* MIT -* ISC -* ICU -* University of Illinois/NCSA -* W3C Software License -* zlib/libpng -* Academic Free License 3.0 -* Python Software Foundation License -* Python Imaging Library Software License -* Boost Software License Version 1.0 -* WTF Public License -* UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE -* Zope Public License 2.0 +- Apache License 2.0 +- Mulan Permissive Software License, Version 2 +- BSD 2-clause +- BSD 3-clause +- DOM4J License +- PostgreSQL License +- Eclipse Distribution License 1.0 +- MIT +- ISC +- ICU +- University of Illinois/NCSA +- W3C Software License +- zlib/libpng +- Academic Free License 3.0 +- Python Software Foundation License +- Python Imaging Library Software License +- Boost Software License Version 1.0 +- WTF Public License +- UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +- Zope Public License 2.0 4. 如下类型许可证不建议引入到OpenHarmony项目中: -* GNU GPL 1, 2, 3 -* GNU Affero GPL 3 -* GNU LGPL 2, 2.1, 3 -* QPL -* Sleepycat License -* Server Side Public License (SSPL) version 1 -* Code Project Open License (CPOL) -* BSD-4-Clause/BSD-4-Clause (University of California-Specific) -* Facebook BSD+Patents license -* NPL 1.0/NPL 1.1 -* The Solipsistic Eclipse Public License -* The "Don't Be A Dick" Public License -* JSON License -* Binary Code License (BCL) -* Intel Simplified Software License -* JSR-275 License -* Microsoft Limited Public License -* Amazon Software License (ASL) -* Java SDK for Satori RTM license -* Redis Source Available License (RSAL) -* Booz Allen Public License -* Creative Commons Non-Commercial -* Sun Community Source License 3.0 -* Common Development and Distribution Licenses: CDDL 1.0 and CDDL 1.1 -* Common Public License: CPL 1.0 -* Eclipse Public License: EPL 1.0 -* IBM Public License: IPL 1.0 -* Mozilla Public Licenses: MPL 1.0, MPL 1.1, and MPL 2.0 -* Sun Public License: SPL 1.0 -* Open Software License 3.0 -* Erlang Public License -* UnRAR License -* SIL Open Font License -* Ubuntu Font License Version 1.0 -* IPA Font License Agreement v1.0 -* Ruby License -* Eclipse Public License 2.0: EPL 2.0 +- GNU GPL 1, 2, 3 +- GNU Affero GPL 3 +- GNU LGPL 2, 2.1, 3 +- QPL +- Sleepycat License +- Server Side Public License (SSPL) version 1 +- Code Project Open License (CPOL) +- BSD-4-Clause/BSD-4-Clause (University of California-Specific) +- Facebook BSD+Patents license +- NPL 1.0/NPL 1.1 +- The Solipsistic Eclipse Public License +- The "Don't Be A Dick" Public License +- JSON License +- Binary Code License (BCL) +- Intel Simplified Software License +- JSR-275 License +- Microsoft Limited Public License +- Amazon Software License (ASL) +- Java SDK for Satori RTM license +- Redis Source Available License (RSAL) +- Booz Allen Public License +- Creative Commons Non-Commercial +- Sun Community Source License 3.0 +- Common Development and Distribution Licenses: CDDL 1.0 and CDDL 1.1 +- Common Public License: CPL 1.0 +- Eclipse Public License: EPL 1.0 +- IBM Public License: IPL 1.0 +- Mozilla Public Licenses: MPL 1.0, MPL 1.1, and MPL 2.0 +- Sun Public License: SPL 1.0 +- Open Software License 3.0 +- Erlang Public License +- UnRAR License +- SIL Open Font License +- Ubuntu Font License Version 1.0 +- IPA Font License Agreement v1.0 +- Ruby License +- Eclipse Public License 2.0: EPL 2.0 如要引入其它类型License或上述(4)所列License,请联系邮箱:oh-legal@openatom.io。 @@ -219,4 +235,4 @@ third_party_abcde/doc/ LICENSEFILE LICENSE Apache-2.0 如果软件符合以上任何一条退出条件,PMC与相应SIG首先分析该软件在当前OpenHarmony社区中被依赖、被使用的情况。 1. 如果OpenHarmony中存在依赖关系,且短时间内不能解除,我们建议SIG新建分支代码仓,并主动进行社区维护动作。 -2. 如果OpenHarmony中不存在依赖关系,或者短时间内可以解除,则责任SIG将软件从OpenHarmony正式发行中移出,并在相应的Release Notes中说明移除的原因及影响。 \ No newline at end of file +2. 如果OpenHarmony中不存在依赖关系,或者短时间内可以解除,则责任SIG将软件从OpenHarmony正式发行中移出,并在相应的Release Notes中说明移除的原因及影响。 diff --git a/zh-cn/device-dev/driver/driver-peripherals-camera-des.md b/zh-cn/device-dev/driver/driver-peripherals-camera-des.md index 94704359fc2492e9ddc456669e3827b4ca0f3d19..8fddafeda91cdbea167912c57ad3a991b1d6b980 100755 --- a/zh-cn/device-dev/driver/driver-peripherals-camera-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-camera-des.md @@ -18,9 +18,9 @@ Camera模块主要包含服务、设备的初始化,数据通路的搭建,         ![](figures/Camera模块驱动模型.png) -1. 系统启动时创建camera_host进程。进程创建后,首先枚举底层设备,创建(也可以通过配置表创建)管理设备树的DeviceManager类及其内部各个底层设备的对象,创建对应的CameraHost类实例并且将其注册到UHDF服务中,方便相机服务层通过UHDF服务获取底层CameraDeviceHost的服务,从而操作硬件设备。 +1. 系统启动时创建camera_host进程。进程创建后,首先枚举底层设备,创建(也可以通过配置表创建)管理设备树的DeviceManager类及其内部各个底层设备的对象,创建对应的CameraHost类实例并且将其注册到UHDF(用户态HDF驱动框架)服务中,方便相机服务层通过UHDF服务获取底层CameraDeviceHost的服务,从而操作硬件设备。 -2. Service通过CameraDeviceHost服务获取CameraHost实例,CameraHost可以获取底层的Camera能力,打开手电筒、调用Open接口打开Camera创建连接、创建DeviceManager(负责底层硬件模块上电)、创建CameraDevice(向上提供设备控制接口)。创建CameraDevice时会实例化PipelineCore的各个子模块,其中StreamPipelineCore负责创建Pipeline,MetaQueueManager负责上报metaData。 +2. Service通过CameraDeviceHost服务获取CameraHost实例,CameraHost可以获取底层的Camera能力,开启闪光灯、调用Open接口打开Camera创建连接、创建DeviceManager(负责底层硬件模块上电)、创建CameraDevice(向上提供设备控制接口)。创建CameraDevice时会实例化PipelineCore的各个子模块,其中StreamPipelineCore负责创建Pipeline,MetaQueueManager负责上报metaData。 3. Service通过CameraDevice模块配置流、创建Stream类。StreamPipelineStrategy模块通过上层下发的模式和查询配置表创建对应流的Node连接方式,StreamPipelineBuilder模块创建Node实例并且连接返回该Pipeline给StreamPipelineDispatcher。StreamPipelineDispatcher提供统一的Pipeline调用管理。 @@ -43,86 +43,88 @@ Camera模块主要包含服务、设备的初始化,数据通路的搭建, ### 场景介绍 -Camera模块主要用以相机预览、拍照、视频流等场景下对相机操作封装,使开发者更易操作相机硬件,提高开发效率。 +Camera模块主要针对相机预览、拍照、视频流等场景,对这些场景下的相机操作进行封装,使开发者更易操作相机硬件,提高开发效率。 ### 接口说明 +注:以下接口列举的为IDL接口描述生成的对应C++语言函数接口,接口声明见idl文件(/drivers/interface/camera/v1_0/)。 - icamera_device.h | 功能描述 | 接口名称 | | ---------------------------- | ------------------------------------------------------------ | - | 获取流控制器 | CamRetCode GetStreamOperator(
const OHOS::sptr &callback,
OHOS::sptr &streamOperator) | - | 更新设备控制参数 | CamRetCode UpdateSettings(const std::shared_ptr &settings) | - | 设置Result回调模式和回调函数 | CamRetCode SetResultMode(const ResultCallbackMode &mode) | - | 获取使能的ResultMeta | CamRetCode GetEnabledResults(std::vector &results) | - | 使能具体的ResultMeta | CamRetCode EnableResult(const std::vector &results) | - | 禁止具体的ResultMeta | CamRetCode DisableResult(const std::vector &results) | - | 关闭Camera设备 | void Close() | + | 获取流控制器 | int32_t GetStreamOperator(const sptr& callbackObj,
sptr& streamOperator) | + | 更新设备控制参数 | int32_t UpdateSettings(const std::vector& settings) | + | 设置Result回调模式和回调函数 | int32_t SetResultMode(ResultCallbackMode mode) | + | 获取使能的ResultMeta | int32_t GetEnabledResults(std::vector& results) | + | 使能具体的ResultMeta | int32_t EnableResult(const std::vector& results) | + | 禁止具体的ResultMeta | int32_t DisableResult(const std::vector& results) | + | 关闭Camera设备 | int32_t Close() | - icamera_device_callback.h | 功能描述 | 接口名称 | | ---------------------------------------------------------- | ------------------------------------------------------------ | - | 设备发生错误时调用,由调用者实现,用于返回错误信息给调用者 | void OnError(ErrorType type, int32_t errorCode) | - | 上报camera设备相关的metadata的回调 | void OnResult(uint64_t timestamp, const std::shared_ptr &result) | + | 设备发生错误时调用,由调用者实现,用于返回错误信息给调用者 | int32_t OnError(ErrorType type, int32_t errorCode) | + | 上报camera设备相关的metadata的回调 | int32_t OnResult(uint64_t timestamp, const std::vector& result) | - icamera_host.h | 功能描述 | 接口名称 | | ------------------------------ | ------------------------------------------------------------ | - | 设置ICameraHost回调接口 | CamRetCode SetCallback(const OHOS::sptr &callback) | - | 获取当前可用的Camera设备ID列表 | CamRetCode GetCameraIds(std::vector\ &cameraIds) | - | 获取Camera设备能力集合 | CamRetCode GetCameraAbility(const std::string &cameraId, std::shared_ptr &ability) | - | 打开Camera设备 | CamRetCode OpenCamera(const std::string &cameraId,
const OHOS::sptr &callback,
OHOS::sptr &device) | - | 打开或关闭闪光灯 | CamRetCode SetFlashlight(const std::string &cameraId, bool &isEnable) | + | 设置ICameraHost回调接口 | int32_t SetCallback(const sptr& callbackObj) | + | 获取当前可用的Camera设备ID列表 | int32_t GetCameraIds(std::vector& cameraIds) | + | 获取Camera设备能力集合 | int32_t GetCameraAbility(const std::string& cameraId, std::vector& cameraAbility) | + | 打开Camera设备 | int32_t OpenCamera(const std::string& cameraId, const sptr& callbackObj,
sptr& device) | + | 打开或关闭闪光灯 | int32_t SetFlashlight(const std::string& cameraId, bool isEnable) | - icamera_host_callback.h | 功能描述 | 接口名称 | | ---------------------- | ------------------------------------------------------------ | - | Camera设备状态变化上报 | void OnCameraStatus(const std::string &cameraId, CameraStatus status) | - | 闪光灯状态变化回调 | void OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status) | + | Camera设备状态变化上报 | int32_t OnCameraStatus(const std::string& cameraId, CameraStatus status) | + | 闪光灯状态变化回调 | int32_t OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status) | + | Camera事件回调 | int32_t OnCameraEvent(const std::string& cameraId, CameraEvent event) | - ioffline_stream_operator.h | 功能描述 | 接口名称 | | -------------- | ------------------------------------------------------------ | - | 取消捕获请求 | CamRetCode CancelCapture(int captureId) | - | 释放流 | CamRetCode ReleaseStreams(const std::vector &streamIds) | - | 释放所有离线流 | CamRetCode Release() | + | 取消捕获请求 | int32_t CancelCapture(int32_t captureId) | + | 释放流 | int32_t ReleaseStreams(const std::vector& streamIds) | + | 释放所有离线流 | int32_t Release() | - istream_operator.h | 功能描述 | 接口名称 | | -------------------------------- | ------------------------------------------------------------ | - | 查询是否支持添加参数对应的流 | CamRetCode IsStreamsSupported(
OperationMode mode,
const std::shared_ptr\ &modeSetting,
const std::vector<std::shared_ptr<StreamInfo>> &info,
StreamSupportType &type) | - | 创建流 | CamRetCode CreateStreams(const std::vector> &streamInfos) | - | 释放流 | CamRetCode ReleaseStreams(const std::vector &streamIds) | - | 配置流 | CamRetCode CommitStreams(OperationMode mode, const std::shared_ptr &modeSetting) | - | 获取流的属性 | CamRetCode GetStreamAttributes(std::vector> &attributes) | - | 绑定生产者句柄和指定流 | CamRetCode AttachBufferQueue(int streamId, const OHOS::sptr\ &producer) | - | 解除生产者句柄和指定流的绑定关系 | CamRetCode DetachBufferQueue(int streamId) | - | 捕获图像 | CamRetCode Capture(int captureId, const std::shared_ptr &info, bool isStreaming) | - | 取消捕获 | CamRetCode CancelCapture(int captureId) | - | 将指定流转换成离线流 | CamRetCode ChangeToOfflineStream(const std::vector &streamIds,
OHOS::sptr &callback,
OHOS::sptr &offlineOperator) | + | 查询是否支持添加参数对应的流 | int32_t IsStreamsSupported(
OperationMode mode,
const std::vector& modeSetting,
const std::vector& infos,
StreamSupportType& type) | + | 创建流 | int32_t CreateStreams(const std::vector& streamInfos) | + | 释放流 | int32_t ReleaseStreams(const std::vector& streamIds) | + | 配置流 | int32_t CommitStreams(OperationMode mode, const std::vector& modeSetting) | + | 获取流的属性 | int32_t GetStreamAttributes(std::vector& attributes) | + | 绑定生产者句柄和指定流 | int32_t AttachBufferQueue(int32_t streamId, const sptr& bufferProducer) | + | 解除生产者句柄和指定流的绑定关系 | int32_t DetachBufferQueue(int32_t streamId) | + | 捕获图像 | int32_t Capture(int32_t captureId, const CaptureInfo& info, bool isStreaming) | + | 取消捕获 | int32_t CancelCapture(int32_t captureId) | + | 将指定流转换成离线流 | int32_t ChangeToOfflineStream(const std::vector& streamIds,
const sptr& callbackObj,
sptr& offlineOperator) | - istream_operator_callback.h | 功能描述 | 接口名称 | | ---------------------------------------- | ------------------------------------------------------------ | - | 捕获开始回调,在捕获开始时调用 | void OnCaptureStarted(int32_t captureId, const std::vector &streamIds) | - | 捕获结束回调,在捕获结束时调用 | void OnCaptureEnded(int32_t captureId, const std::vector> &infos) | - | 捕获错误回调,在捕获过程中发生错误时调用 | void OnCaptureError(int32_t captureId, const std::vector> &infos) | - | 帧捕获回调 | void OnFrameShutter(int32_t captureId,
const std::vector &streamIds, uint64_t timestamp) | + | 捕获开始回调,在捕获开始时调用 | int32_t OnCaptureStarted(int32_t captureId, const std::vector& streamIds) | + | 捕获结束回调,在捕获结束时调用 | int32_t OnCaptureEnded(int32_t captureId, const std::vector& infos) | + | 捕获错误回调,在捕获过程中发生错误时调用 | int32_t OnCaptureError(int32_t captureId, const std::vector& infos) | + | 帧捕获回调 | int32_t OnFrameShutter(int32_t captureId, const std::vector& streamIds, uint64_t timestamp) | ### 开发步骤 Camera驱动的开发过程主要包含以下步骤: 1. 注册CameraHost - 定义Camera的HdfDriverEntry结构体,该结构体中定义了CameraHost初始化的方法。 - ``` + 定义Camera的HdfDriverEntry结构体,该结构体中定义了CameraHost初始化的方法(代码目录drivers/peripheral/camera/interfaces/hdi_ipc/camera_host_driver.cpp)。 + ```c++ struct HdfDriverEntry g_cameraHostDriverEntry = { .moduleVersion = 1, .moduleName = "camera_service", @@ -135,33 +137,46 @@ Camera驱动的开发过程主要包含以下步骤: 2. 初始化Host服务 - 步骤1中提到的HdfCameraHostDriverBind接口提供了CameraServiceDispatch和CameraHostStubInstance的注册。这两个接口一个是远端调用CameraHost的方法,如OpenCamera(),SetFlashlight()等,另外一个是Camera设备的初始化,在开机时被调用。 + 步骤1中提到的HdfCameraHostDriverBind接口提供了CameraServiceDispatch和CameraHostStubInstance的注册。CameraServiceDispatch接口是远端调用CameraHost的方法,如OpenCamera(),SetFlashlight()等,CameraHostStubInstance接口是Camera设备的初始化,在开机时被调用。 - ``` - int HdfCameraHostDriverBind(HdfDeviceObject *deviceObject) + ```c++ + static int HdfCameraHostDriverBind(struct HdfDeviceObject *deviceObject) { - HDF_LOGI("HdfCameraHostDriverBind enter!"); - if (deviceObject == nullptr) { - HDF_LOGE("HdfCameraHostDriverBind: HdfDeviceObject is NULL!"); + HDF_LOGI("HdfCameraHostDriverBind enter"); + + auto *hdfCameraHostHost = new (std::nothrow) HdfCameraHostHost; + if (hdfCameraHostHost == nullptr) { + HDF_LOGE("%{public}s: failed to create HdfCameraHostHost object", __func__); return HDF_FAILURE; } - HdfCameraService *hdfCameraService = reinterpret_cast(OsalMemAlloc(sizeof(HdfCameraService))); - if (hdfCameraService == nullptr) { - HDF_LOGE("HdfCameraHostDriverBind OsalMemAlloc HdfCameraService failed!"); + + hdfCameraHostHost->ioService.Dispatch = CameraHostDriverDispatch; // 提供远端CameraHost调用方法 + hdfCameraHostHost->ioService.Open = NULL; + hdfCameraHostHost->ioService.Release = NULL; + + auto serviceImpl = ICameraHost::Get(true); + if (serviceImpl == nullptr) { + HDF_LOGE("%{public}s: failed to get of implement service", __func__); + delete hdfCameraHostHost; + return HDF_FAILURE; + } + + hdfCameraHostHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, + ICameraHost::GetDescriptor()); // 初始化Camera设备 + if (hdfCameraHostHost->stub == nullptr) { + HDF_LOGE("%{public}s: failed to get stub object", __func__); + delete hdfCameraHostHost; return HDF_FAILURE; } - hdfCameraService->ioservice.Dispatch = CameraServiceDispatch; // 提供远端CameraHost调用方法 - hdfCameraService->ioservice.Open = nullptr; - hdfCameraService->ioservice.Release = nullptr; - hdfCameraService->instance = CameraHostStubInstance(); // 初始化Camera设备 - deviceObject->service = &hdfCameraService->ioservice; + + deviceObject->service = &hdfCameraHostHost->ioService; return HDF_SUCCESS; } ``` 下面的函数是远端CameraHost调用的方法: - ``` + ```c++ int32_t CameraHostStub::CameraHostServiceStubOnRemoteRequest(int cmdId, MessageParcel &data, MessageParcel &reply, MessageOption &option) { @@ -196,7 +211,7 @@ Camera驱动的开发过程主要包含以下步骤: 调用Get()接口从远端CameraService中获取CameraHost对象。get()方法如下: - ``` + ```c++ sptr ICameraHost::Get(const char *serviceName) { do { @@ -223,46 +238,74 @@ Camera驱动的开发过程主要包含以下步骤: CameraHostProxy对象中有五个方法,分别是SetCallback、GetCameraIds、GetCameraAbility、OpenCamera和SetFlashlight。下面着重描述OpenCamera接口。 CameraHostProxy的OpenCamera()接口通过CMD_CAMERA_HOST_OPEN_CAMERA调用远端CameraHostStubOpenCamera()接口并获取ICameraDevice对象。 - ``` - CamRetCode CameraHostProxy::OpenCamera(const std::string &cameraId, const OHOS::sptr &callback, OHOS::sptr &pDevice) + ```c++ + int32_t CameraHostProxy::OpenCamera(const std::string& cameraId, const sptr& callbackObj, + sptr& device) { - int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_OPEN_CAMERA, data, reply, option); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%{public}s: SendRequest failed, error code is %{public}d", __func__, ret); - return INVALID_ARGUMENT; + MessageParcel cameraHostData; + MessageParcel cameraHostReply; + MessageOption cameraHostOption(MessageOption::TF_SYNC); + + if (!cameraHostData.WriteInterfaceToken(ICameraHost::GetDescriptor())) { + HDF_LOGE("%{public}s: failed to write interface descriptor!", __func__); + return HDF_ERR_INVALID_PARAM; } - CamRetCode retCode = static_cast(reply.ReadInt32()); - bool flag = reply.ReadBool(); - if (flag) { - sptr remoteCameraDevice = reply.ReadRemoteObject(); - if (remoteCameraDevice == nullptr) { - HDF_LOGE("%{public}s: CameraHostProxy remoteCameraDevice is null", __func__); - } - pDevice = OHOS::iface_cast(remoteCameraDevice); + + if (!cameraHostData.WriteCString(cameraId.c_str())) { + HDF_LOGE("%{public}s: write cameraId failed!", __func__); + return HDF_ERR_INVALID_PARAM; + } + + if (!cameraHostData.WriteRemoteObject(OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(callbackObj, + ICameraDeviceCallback::GetDescriptor()))) { + HDF_LOGE("%{public}s: write callbackObj failed!", __func__); + return HDF_ERR_INVALID_PARAM; + } + + int32_t cameraHostRet = Remote()->SendRequest(CMD_CAMERA_HOST_OPEN_CAMERA, cameraHostData, cameraHostReply, cameraHostOption); + if (cameraHostRet != HDF_SUCCESS) { + HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, cameraHostRet); + return cameraHostRet; } - return retCode; + + device = hdi_facecast(cameraHostReply.ReadRemoteObject()); + + return cameraHostRet; } ``` Remote()->SendRequest调用上文提到的CameraHostServiceStubOnRemoteRequest(),根据cmdId进入CameraHostStubOpenCamera()接口,最终调用CameraHostImpl::OpenCamera(),该接口获取了CameraDevice并对硬件进行上电等操作。 - ``` - CamRetCode CameraHostImpl::OpenCamera(const std::string &cameraId, const OHOS::sptr &callback, OHOS::sptr &device) + ```c++ + int32_t CameraHostImpl::OpenCamera(const std::string& cameraId, const sptr& callbackObj, + sptr& device) { - std::shared_ptr cameraDevice = std::static_pointer_cast(itr->second); + CAMERA_LOGD("OpenCamera entry"); + DFX_LOCAL_HITRACE_BEGIN; + if (CameraIdInvalid(cameraId) != RC_OK || callbackObj == nullptr) { + CAMERA_LOGW("open camera id is empty or callback is null."); + return INVALID_ARGUMENT; + } + + auto itr = cameraDeviceMap_.find(cameraId); + if (itr == cameraDeviceMap_.end()) { + CAMERA_LOGE("camera device not found."); + return INSUFFICIENT_RESOURCES; + } + CAMERA_LOGD("OpenCamera cameraId find success."); + + std::shared_ptr cameraDevice = itr->second; if (cameraDevice == nullptr) { CAMERA_LOGE("camera device is null."); return INSUFFICIENT_RESOURCES; } - CamRetCode ret = cameraDevice->SetCallback(callback); - if (ret != NO_ERROR) { - CAMERA_LOGW("set camera device callback failed."); - return ret; - } + + CamRetCode ret = cameraDevice->SetCallback(callbackObj); + CHECK_IF_NOT_EQUAL_RETURN_VALUE(ret, HDI::Camera::V1_0::NO_ERROR, ret); + CameraHostConfig *config = CameraHostConfig::GetInstance(); - if (config == nullptr) { - return INVALID_ARGUMENT; - } + CHECK_IF_PTR_NULL_RETURN_VALUE(config, INVALID_ARGUMENT); + std::vector phyCameraIds; RetCode rc = config->GetPhysicCameraIds(cameraId, phyCameraIds); if (rc != RC_OK) { @@ -274,14 +317,20 @@ Camera驱动的开发过程主要包含以下步骤: CameraPowerDown(phyCameraIds); return DEVICE_ERROR; } - + auto sptrDevice = deviceBackup_.find(cameraId); if (sptrDevice == deviceBackup_.end()) { + #ifdef CAMERA_BUILT_ON_OHOS_LITE + deviceBackup_[cameraId] = cameraDevice; + #else deviceBackup_[cameraId] = cameraDevice.get(); + #endif } device = deviceBackup_[cameraId]; cameraDevice->SetStatus(true); - return NO_ERROR; + CAMERA_LOGD("open camera success."); + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; } ``` @@ -289,29 +338,42 @@ Camera驱动的开发过程主要包含以下步骤: CameraDeviceImpl定义了GetStreamOperator、UpdateSettings、SetResultMode和GetEnabledResult等方法,获取流操作方法如下: - ``` - CamRetCode CameraDeviceImpl::GetStreamOperator(const OHOS::sptr &callback, - OHOS::sptr &streamOperator) + ```c++ + int32_t CameraDeviceImpl::GetStreamOperator(const sptr& callbackObj, + sptr& streamOperator) { - if (callback == nullptr) { + HDI_DEVICE_PLACE_A_WATCHDOG; + DFX_LOCAL_HITRACE_BEGIN; + if (callbackObj == nullptr) { CAMERA_LOGW("input callback is null."); return INVALID_ARGUMENT; } - spCameraDeviceCallback_ = callback; + + spCameraDeciceCallback_ = callbackObj; if (spStreamOperator_ == nullptr) { - // 这里新建一个spStreamOperator对象传递给调用者,以便对stream进行各种操作。 - spStreamOperator_ = new(std::nothrow) StreamOperatorImpl(spCameraDeviceCallback_, shared_from_this()); + #ifdef CAMERA_BUILT_ON_OHOS_LITE + // 这里创建一个spStreamOperator_ 对象传递给调用者,以便对stream进行各种操作 + spStreamOperator_ = std::make_shared(spCameraDeciceCallback_, shared_from_this()); + #else + spStreamOperator_ = new(std::nothrow) StreamOperator(spCameraDeciceCallback_, shared_from_this()); + #endif if (spStreamOperator_ == nullptr) { CAMERA_LOGW("create stream operator failed."); return DEVICE_ERROR; } + spStreamOperator_->Init(); ismOperator_ = spStreamOperator_; } streamOperator = ismOperator_; - - spStreamOperator_->SetRequestCallback([this](){ - spCameraDeviceCallback_->OnError(REQUEST_TIMEOUT, 0); + #ifndef CAMERA_BUILT_ON_OHOS_LITE + CAMERA_LOGI("CameraDeviceImpl %{public}s: line: %{public}d", __FUNCTION__, __LINE__); + pipelineCore_->GetStreamPipelineCore()->SetCallback( + [this](const std::shared_ptr &metadata) { + OnMetadataChanged(metadata); }); + #endif + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; } ``` @@ -319,7 +381,7 @@ Camera驱动的开发过程主要包含以下步骤: 调用CreateStreams创建流前需要填充StreamInfo结构体,具体内容如下: - ``` + ```c++ using StreamInfo = struct _StreamInfo { int streamId_; int width_; // 数据流宽 @@ -328,141 +390,239 @@ Camera驱动的开发过程主要包含以下步骤: int dataSpace_; StreamIntent intent_; // StreamIntent 如PREVIEW bool tunneledMode_; - OHOS::sptr bufferQueue_; // 数据流bufferQueue可用streamCustomer->CreateProducer()接口创建 + BufferProducerSequenceable bufferQueue_; // 数据流bufferQueue可用streamCustomer->CreateProducer()接口创建 int minFrameDuration_; EncodeType encodeType_; }; ``` - CreateStreams()接口是StreamOperatorImpl类中的方法,该接口的主要作用是创建一个StreamBase对象,通过StreamBase的Init方法初始化CreateBufferPool等操作。 + CreateStreams()接口是StreamOperator(StreamOperatorImpl类是StreamOperator的基类)类中的方法,该接口的主要作用是创建一个StreamBase对象,通过StreamBase的Init方法初始化CreateBufferPool等操作。 - ``` - RetCode StreamOperatorImpl::CreateStream(const std::shared_ptr& streamInfo) + ```c++ + int32_t StreamOperator::CreateStreams(const std::vector& streamInfos) { - static std::map typeMap = { - {PREVIEW, "PREVIEW"}, - {VIDEO, "VIDEO"}, - {STILL_CAPTURE, "STILL_CAPTURE"}, - {POST_VIEW, "POST_VIEW"}, {ANALYZE, "ANALYZE"}, - {CUSTOM, "CUSTOM"} - }; - - auto itr = typeMap.find(streamInfo->intent_); - if (itr == typeMap.end()) { - CAMERA_LOGE("do not support stream type. [type = %{public}d]", streamInfo->intent_); - return RC_ERROR; + PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_); + DFX_LOCAL_HITRACE_BEGIN; + for (const auto& it : streamInfos) { + CHECK_IF_NOT_EQUAL_RETURN_VALUE(CheckStreamInfo(it), true, INVALID_ARGUMENT); + CAMERA_LOGI("streamId:%{public}d and format:%{public}d and width:%{public}d and height:%{public}d", + it.streamId_, it.format_, it.width_, it.height_); + if (streamMap_.count(it.streamId_) > 0) { + CAMERA_LOGE("stream [id = %{public}d] has already been created.", it.streamId_); + return INVALID_ARGUMENT; + } + std::shared_ptr stream = StreamFactory::Instance().CreateShared( // 创建Stream实例 + IStream::g_availableStreamType[it.intent_], it.streamId_, it.intent_, pipelineCore_, messenger_); + if (stream == nullptr) { + CAMERA_LOGE("create stream [id = %{public}d] failed.", it.streamId_); + return INSUFFICIENT_RESOURCES; + } + StreamConfiguration scg; + StreamInfoToStreamConfiguration(scg, it); + RetCode rc = stream->ConfigStream(scg); + if (rc != RC_OK) { + CAMERA_LOGE("configure stream %{public}d failed", it.streamId_); + return INVALID_ARGUMENT; + } + if (!scg.tunnelMode && (it.bufferQueue_)->producer_ != nullptr) { + CAMERA_LOGE("stream [id:%{public}d] is not tunnel mode, can't bind a buffer producer", it.streamId_); + return INVALID_ARGUMENT; + } + if ((it.bufferQueue_)->producer_ != nullptr) { + auto tunnel = std::make_shared(); + CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel, INSUFFICIENT_RESOURCES); + rc = tunnel->AttachBufferQueue((it.bufferQueue_)->producer_); + CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, INVALID_ARGUMENT); + if (stream->AttachStreamTunnel(tunnel) != RC_OK) { + CAMERA_LOGE("attach buffer queue to stream [id = %{public}d] failed", it.streamId_); + return INVALID_ARGUMENT; + } + } + { + std::lock_guard l(streamLock_); + streamMap_[stream->GetStreamId()] = stream; + } + CAMERA_LOGI("create stream success [id:%{public}d] [type:%{public}s]", stream->GetStreamId(), + IStream::g_availableStreamType[it.intent_].c_str()); } - std::shared_ptr stream = StreamFactory::Instance().CreateShared(itr->second); // 创建StreamBase实例 - RetCode rc = stream->Init(streamInfo); - return RC_OK; - } + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; + } ``` -7. **配置流** +7. 配置流 CommitStreams()是配置流的接口,必须在创建流之后调用,其主要作用是初始化Pipeline和创建Pipeline。 - ``` - CamRetCode StreamOperatorImpl::CommitStreams(OperationMode mode, const std::shared_ptr& modeSetting) + ```c++ + int32_t StreamOperator::CommitStreams(OperationMode mode, const std::vector& modeSetting) { - auto cameraDevice = cameraDevice_.lock(); - if (cameraDevice == nullptr) { - CAMERA_LOGE("camera device closed."); - return CAMERA_CLOSED; - } - std::shared_ptr PipelineCore = - std::static_pointer_cast(cameraDevice)->GetPipelineCore(); - if (PipelineCore == nullptr) { - CAMERA_LOGE("get pipeline core failed."); - return CAMERA_CLOSED; + CAMERA_LOGV("enter"); + CHECK_IF_PTR_NULL_RETURN_VALUE(streamPipeline_, DEVICE_ERROR); + PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_); + if (modeSetting.empty()) { + CAMERA_LOGE("input vector is empty"); + return INVALID_ARGUMENT; } + DFX_LOCAL_HITRACE_BEGIN; - streamPipeCore_ = PipelineCore->GetStreamPipelineCore(); - if (streamPipeCore_ == nullptr) { - CAMERA_LOGE("get stream pipeline core failed."); - return DEVICE_ERROR; + std::vector configs = {}; + { + std::lock_guard l(streamLock_); + std::transform(streamMap_.begin(), streamMap_.end(), std::back_inserter(configs), + [](auto &iter) { return iter.second->GetStreamAttribute(); }); } - - RetCode rc = streamPipeCore_->Init(); // 对pipelinecore的初始化 + + std::shared_ptr setting; + MetadataUtils::ConvertVecToMetadata(modeSetting, setting); + DynamicStreamSwitchMode method = streamPipeline_->CheckStreamsSupported(mode, setting, configs); + if (method == DYNAMIC_STREAM_SWITCH_NOT_SUPPORT) { + return INVALID_ARGUMENT; + } + if (method == DYNAMIC_STREAM_SWITCH_NEED_INNER_RESTART) { + std::lock_guard l(streamLock_); + for (auto it : streamMap_) { + it.second->StopStream(); + } + } + { + std::lock_guard l(streamLock_); + for (auto it : streamMap_) { + if (it.second->CommitStream() != RC_OK) { + CAMERA_LOGE("commit stream [id = %{public}d] failed.", it.first); + return DEVICE_ERROR; + } + } + } + RetCode rc = streamPipeline_->PreConfig(setting); // 设备流配置 if (rc != RC_OK) { - CAMERA_LOGE("stream pipeline core init failed."); + CAMERA_LOGE("prepare mode settings failed"); return DEVICE_ERROR; } - rc = streamPipeCore_->CreatePipeline(mode); // 创建一个pipeline + rc = streamPipeline_->CreatePipeline(mode); // 创建一个pipeline if (rc != RC_OK) { CAMERA_LOGE("create pipeline failed."); return INVALID_ARGUMENT; } - return NO_ERROR; + + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; } ``` -8. **捕获图像** +8. 捕获图像 在调用Capture()接口前需要先填充CaptureInfo结构体,具体内容如下: - ``` + ```c++ using CaptureInfo = struct _CaptureInfo { - std::vector streamIds_; //需要Capture的streamIds - std::shared_ptr captureSetting_; // 这里填充camera ability 可通过CameraHost 的GetCameraAbility()接口获取 - bool enableShutterCallback_; + int[] streamIds_; // 需要Capture的streamIds + unsigned char[] captureSetting_; // 这里填充camera ability 可通过CameraHost 的GetCameraAbility()接口获取 + bool enableShutterCallback_; }; ``` - StreamOperatorImpl中的Capture方法主要调用CreateCapture()接口去捕获数据流: + StreamOperator中的Capture方法主要是捕获数据流: - ``` - CamRetCode StreamOperatorImpl::Capture(int captureId, const std::shared_ptr& captureInfo, bool isStreaming) + ```c++ + int32_t StreamOperator::Capture(int32_t captureId, const CaptureInfo& info, bool isStreaming) { - if (!ValidCaptureInfo(captureId, captureInfo)) { - CAMERA_LOGE("capture streamIds is empty. [captureId = %d]", captureId); - return INVALID_ARGUMENT; - } - std::shared_ptr cameraCapture = nullptr; - RetCode rc = CreateCapture(captureId, captureInfo, isStreaming, cameraCapture); - if (rc != RC_OK) { - CAMERA_LOGE("create capture is failed."); - return DEVICE_ERROR; + CHECK_IF_EQUAL_RETURN_VALUE(captureId < 0, true, INVALID_ARGUMENT); + PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_); + DFX_LOCAL_HITRACE_BEGIN; + + for (auto id : info.streamIds_) { + std::lock_guard l(streamLock_); + auto it = streamMap_.find(id); + if (it == streamMap_.end()) { + return INVALID_ARGUMENT; + } } - + { - std::unique_lock lock(captureMutex_); - camerCaptureMap_.insert(std::make_pair(captureId, cameraCapture)); + std::lock_guard l(requestLock_); + auto itr = requestMap_.find(captureId); + if (itr != requestMap_.end()) { + return INVALID_ARGUMENT; + } } - - rc = StartThread(); - if (rc != RC_OK) { - CAMERA_LOGE("preview start failed."); - return DEVICE_ERROR; + + std::shared_ptr captureSetting; + MetadataUtils::ConvertVecToMetadata(info.captureSetting_, captureSetting); + CaptureSetting setting = captureSetting; + auto request = + std::make_shared(captureId, info.streamIds_.size(), setting, + info.enableShutterCallback_, isStreaming); + for (auto id : info.streamIds_) { + RetCode rc = streamMap_[id]->AddRequest(request); + if (rc != RC_OK) { + return DEVICE_ERROR; + } + } + + { + std::lock_guard l(requestLock_); + requestMap_[captureId] = request; } - return NO_ERROR; + return HDI::Camera::V1_0::NO_ERROR; } ``` 9. 取消捕获和释放离线流 - StreamOperatorImpl类中的CancelCapture()接口的主要作用是根据captureId取消数据流的捕获。 + StreamOperator类中的CancelCapture()接口的主要作用是根据captureId取消数据流的捕获。 - ``` - CamRetCode StreamOperatorImpl::CancelCapture(int captureId) + ```c++ + int32_t StreamOperator::CancelCapture(int32_t captureId) { - auto itr = camerCaptureMap_.find(captureId); // 根据captureId 在Map中查找对应的CameraCapture对象 - RetCode rc = itr->second->Cancel(); // 调用CameraCapture中Cancel方法结束数据捕获 - std::unique_lock lock(captureMutex_); - camerCaptureMap_.erase(itr); // 擦除该CameraCapture对象 - return NO_ERROR; + CHECK_IF_EQUAL_RETURN_VALUE(captureId < 0, true, INVALID_ARGUMENT); + PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_); + DFX_LOCAL_HITRACE_BEGIN; + + std::lock_guard l(requestLock_); + auto itr = requestMap_.find(captureId); // 根据captureId 在Map中查找对应的CameraCapture对象 + if (itr == requestMap_.end()) { + CAMERA_LOGE("can't cancel capture [id = %{public}d], this capture doesn't exist", captureId); + return INVALID_ARGUMENT; + } + + RetCode rc = itr->second->Cancel(); // 调用CameraCapture中Cancel方法结束数据捕获 + if (rc != RC_OK) { + return DEVICE_ERROR; + } + requestMap_.erase(itr); // 擦除该CameraCapture对象 + + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; } ``` - StreamOperatorImpl类中的ReleaseStreams接口的主要作用是释放之前通过CreateStream()和CommitStreams()接口创建的流,并销毁Pipeline。 + StreamOperator类中的ReleaseStreams接口的主要作用是释放之前通过CreateStream()和CommitStreams()接口创建的流,并销毁Pipeline。 - ``` - CamRetCode StreamOperatorImpl::ReleaseStreams(const std::vector& streamIds) + ```c++ + int32_t StreamOperator::ReleaseStreams(const std::vector& streamIds) { - RetCode rc = DestroyStreamPipeline(streamIds); // 销毁该streamIds 的pipeline - rc = DestroyHostStreamMgr(streamIds); - rc = DestroyStreams(streamIds); // 销毁该streamIds 的 Stream - return NO_ERROR; + PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_); + DFX_LOCAL_HITRACE_BEGIN; + for (auto id : streamIds) { + std::lock_guard l(streamLock_); + auto it = streamMap_.find(id); + if (it == streamMap_.end()) { + continue; + } + if (it->second->IsRunning()) { + it->second->StopStream(); + } + it->second->DumpStatsInfo(); + streamMap_.erase(it); + } + + for (auto id : streamIds) { + CHECK_IF_EQUAL_RETURN_VALUE(id < 0, true, INVALID_ARGUMENT); + } + + DFX_LOCAL_HITRACE_END; + return HDI::Camera::V1_0::NO_ERROR; } ``` @@ -472,11 +632,11 @@ Camera驱动的开发过程主要包含以下步骤: ### 开发实例 -在/drivers/peripheral/camera/hal/init目录下有一个关于Camera的demo,开机后会在/vendor/bin下生成可执行文件ohos_camera_demo,该demo可以完成Camera的预览,拍照等基础功能。下面我们就以此demo为例讲述怎样用HDI接口去编写预览PreviewOn()和拍照CaptureON()的用例,可参考[ohos_camera_demo](https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/hal/init)。 +在/drivers/peripheral/camera/hal/init目录下有一个关于Camera的demo,开机后会在/vendor/bin下生成可执行文件ohos_camera_demo,该demo可以完成Camera的预览,拍照等基础功能。下面我们就以此demo为例讲述怎样用HDI接口去编写预览PreviewOn()和拍照CaptureON()的用例,可参考[ohos_camera_demo](https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/hal/init)。 1. 在main函数中构造一个CameraDemo 对象,该对象中有对Camera初始化、启停流、释放等控制的方法。下面mainDemo->InitSensors()函数为初始化CameraHost,mainDemo->InitCameraDevice()函数为初始化CameraDevice。 - ``` + ```c++ int main(int argc, char** argv) { RetCode rc = RC_OK; @@ -507,157 +667,271 @@ Camera驱动的开发过程主要包含以下步骤: 初始化CameraHost函数实现如下,这里调用了HDI接口ICameraHost::Get()去获取demoCameraHost,并对其设置回调函数。 - ``` - RetCode CameraDemo::InitSensors() + ```c++ + RetCode OhosCameraDemo::InitSensors() { - demoCameraHost_ = ICameraHost::Get(DEMO_SERVICE_NAME); + int rc = 0; + + CAMERA_LOGD("demo test: InitSensors enter"); + + if (demoCameraHost_ != nullptr) { + return RC_OK; + } + #ifdef CAMERA_BUILT_ON_OHOS_LITE + demoCameraHost_ = OHOS::Camera::CameraHost::CreateCameraHost(); + #else + constexpr const char *DEMO_SERVICE_NAME = "camera_service"; + demoCameraHost_ = ICameraHost::Get(DEMO_SERVICE_NAME, false); + #endif if (demoCameraHost_ == nullptr) { CAMERA_LOGE("demo test: ICameraHost::Get error"); return RC_ERROR; } - - hostCallback_ = new CameraHostCallback(); + + #ifdef CAMERA_BUILT_ON_OHOS_LITE + hostCallback_ = std::make_shared(); + #else + hostCallback_ = new DemoCameraHostCallback(); + #endif rc = demoCameraHost_->SetCallback(hostCallback_); + if (rc != HDI::Camera::V1_0::NO_ERROR) { + CAMERA_LOGE("demo test: demoCameraHost_->SetCallback(hostCallback_) error"); + return RC_ERROR; + } + + CAMERA_LOGD("demo test: InitSensors exit"); + return RC_OK; } ``` 初始化CameraDevice函数实现如下,这里调用了GetCameraIds(cameraIds_),GetCameraAbility(cameraId, ability_),OpenCamera(cameraIds_.front(), callback, demoCameraDevice_)等接口实现了demoCameraHost的获取。 - ``` - RetCode CameraDemo::InitCameraDevice() + ```c++ + RetCode OhosCameraDemo::InitCameraDevice() { + int rc = 0; + + CAMERA_LOGD("demo test: InitCameraDevice enter"); + + if (demoCameraHost_ == nullptr) { + CAMERA_LOGE("demo test: InitCameraDevice demoCameraHost_ == nullptr"); + return RC_ERROR; + } + (void)demoCameraHost_->GetCameraIds(cameraIds_); + if (cameraIds_.empty()) { + return RC_ERROR; + } const std::string cameraId = cameraIds_.front(); - demoCameraHost_->GetCameraAbility(cameraId, ability_); - - sptr callback = new CameraDeviceCallback(); + demoCameraHost_->GetCameraAbility(cameraId, cameraAbility_); + + MetadataUtils::ConvertVecToMetadata(cameraAbility_, ability_); + + GetFaceDetectMode(ability_); + GetFocalLength(ability_); + GetAvailableFocusModes(ability_); + GetAvailableExposureModes(ability_); + GetExposureCompensationRange(ability_); + GetExposureCompensationSteps(ability_); + GetAvailableMeterModes(ability_); + GetAvailableFlashModes(ability_); + GetMirrorSupported(ability_); + GetStreamBasicConfigurations(ability_); + GetFpsRange(ability_); + GetCameraPosition(ability_); + GetCameraType(ability_); + GetCameraConnectionType(ability_); + GetFaceDetectMaxNum(ability_); + + #ifdef CAMERA_BUILT_ON_OHOS_LITE + std::shared_ptr callback = std::make_shared(); + #else + sptr callback = new DemoCameraDeviceCallback(); + #endif rc = demoCameraHost_->OpenCamera(cameraIds_.front(), callback, demoCameraDevice_); + if (rc != HDI::Camera::V1_0::NO_ERROR || demoCameraDevice_ == nullptr) { + CAMERA_LOGE("demo test: InitCameraDevice OpenCamera failed"); + return RC_ERROR; + } + + CAMERA_LOGD("demo test: InitCameraDevice exit"); + return RC_OK; } ``` 2. PreviewOn()接口包含配置流、开启预览流和启动Capture动作。该接口执行完成后Camera预览通路已经开始运转并开启了两路流,一路流是preview,另外一路流是capture或者video,两路流中仅对preview流进行capture动作。 - ``` - static RetCode PreviewOn(int mode, const std::shared_ptr& mainDemo) + ```c++ + static RetCode PreviewOn(int mode, const std::shared_ptr& mainDemo) { - rc = mainDemo->StartPreviewStream(); // 配置preview流 - if (mode == 0) { + RetCode rc = RC_OK; + CAMERA_LOGD("main test: PreviewOn enter"); + + rc = mainDemo->StartPreviewStream(); // 配置preview流 + if (rc != RC_OK) { + CAMERA_LOGE("main test: PreviewOn StartPreviewStream error"); + return RC_ERROR; + } + + if (mode == 0) { rc = mainDemo->StartCaptureStream(); // 配置capture流 - } else { + if (rc != RC_OK) { + CAMERA_LOGE("main test: PreviewOn StartCaptureStream error"); + return RC_ERROR; + } + } else { rc = mainDemo->StartVideoStream(); // 配置video流 - } - - rc = mainDemo->CaptureON(STREAM_ID_PREVIEW, CAPTURE_ID_PREVIEW, CAPTURE_PREVIEW); // 将preview流capture + if (rc != RC_OK) { + CAMERA_LOGE("main test: PreviewOn StartVideoStream error"); + return RC_ERROR; + } + } + + rc = mainDemo->CaptureON(STREAM_ID_PREVIEW, CAPTURE_ID_PREVIEW, CAPTURE_PREVIEW); + if (rc != RC_OK) { + CAMERA_LOGE("main test: PreviewOn mainDemo->CaptureON() preview error"); + return RC_ERROR; + } + + CAMERA_LOGD("main test: PreviewOn exit"); return RC_OK; } ``` StartCaptureStream()、StartVideoStream()和StartPreviewStream()接口都会调用CreateStream()接口,只是传入的参数不同。 - ``` - RetCode CameraDemo::StartVideoStream() - { - RetCode rc = RC_OK; - if (isVideoOn_ == 0) { - isVideoOn_ = 1; - rc = CreateStream(STREAM_ID_VIDEO, streamCustomerVideo_, VIDEO); // 如需启preview或者capture流更改该接口参数即可。 - } - return RC_OK; - } - ``` - CreateStream()方法调用HDI接口去配置和创建流,首先调用HDI接口去获取StreamOperation对象,然后创建一个StreamInfo。调用CreateStreams()和CommitStreams()实际创建流并配置流。 - ``` - RetCode CameraDemo::CreateStreams(const int streamIdSecond, StreamIntent intent) + ```c++ + RetCode OhosCameraDemo::CreateStream(const int streamId, std::shared_ptr &streamCustomer, + StreamIntent intent) { - std::vector> streamInfos; - std::vector>().swap(streamInfos); + int rc = 0; + CAMERA_LOGD("demo test: CreateStream enter"); + GetStreamOpt(); // 获取StreamOperator对象 - std::shared_ptr previewStreamInfo = std::make_shared(); - SetStreamInfo(previewStreamInfo, streamCustomerPreview_, STREAM_ID_PREVIEW, PREVIEW); // 填充StreamInfo - if (previewStreamInfo->bufferQueue_ == nullptr) { - CAMERA_LOGE("demo test: CreateStream CreateProducer(); is nullptr\n"); + if (streamOperator_ == nullptr) { + CAMERA_LOGE("demo test: CreateStream GetStreamOpt() is nullptr\n"); return RC_ERROR; } - streamInfos.push_back(previewStreamInfo); - - std::shared_ptr secondStreamInfo = std::make_shared(); - if (streamIdSecond == STREAM_ID_CAPTURE) { - SetStreamInfo(secondStreamInfo, streamCustomerCapture_, STREAM_ID_CAPTURE, intent); - } else { - SetStreamInfo(secondStreamInfo, streamCustomerVideo_, STREAM_ID_VIDEO, intent); - } - - if (secondStreamInfo->bufferQueue_ == nullptr) { - CAMERA_LOGE("demo test: CreateStreams CreateProducer() secondStreamInfo is nullptr\n"); + + StreamInfo streamInfo = {0}; + + SetStreamInfo(streamInfo, streamCustomer, streamId, intent); // 填充StreamInfo流 + if (streamInfo.bufferQueue_->producer_ == nullptr) { + CAMERA_LOGE("demo test: CreateStream CreateProducer(); is nullptr\n"); return RC_ERROR; } - streamInfos.push_back(secondStreamInfo); - + + std::vector streamInfos; + streamInfos.push_back(streamInfo); + rc = streamOperator_->CreateStreams(streamInfos); // 创建流 - if (rc != Camera::NO_ERROR) { + if (rc != HDI::Camera::V1_0::NO_ERROR) { CAMERA_LOGE("demo test: CreateStream CreateStreams error\n"); return RC_ERROR; } - - rc = streamOperator_->CommitStreams(Camera::NORMAL, ability_); - if (rc != Camera::NO_ERROR) { + + rc = streamOperator_->CommitStreams(NORMAL, cameraAbility_); + if (rc != HDI::Camera::V1_0::NO_ERROR) { CAMERA_LOGE("demo test: CreateStream CommitStreams error\n"); - std::vector streamIds = {STREAM_ID_PREVIEW, streamIdSecond}; + std::vector streamIds; + streamIds.push_back(streamId); streamOperator_->ReleaseStreams(streamIds); return RC_ERROR; } + + CAMERA_LOGD("demo test: CreateStream exit"); + return RC_OK; } ``` CaptureON()接口调用streamOperator的Capture()方法获取Camera数据并轮转buffer,拉起一个线程接收相应类型的数据。 - ``` - RetCode CameraDemo::CaptureON(const int streamId, const int captureId, CaptureMode mode) + ```c++ + RetCode OhosCameraDemo::CaptureON(const int streamId, + const int captureId, CaptureMode mode) { - std::shared_ptr captureInfo = std::make_shared(); // 创建并填充CaptureInfo - captureInfo->streamIds_ = {streamId}; - captureInfo->captureSetting_ = ability_; - captureInfo->enableShutterCallback_ = false; - - int rc = streamOperator_->Capture(captureId, captureInfo, true); // 实际capture开始,buffer轮转开始 + CAMERA_LOGI("demo test: CaptureON enter streamId == %{public}d and captureId == %{public}d and mode == %{public}d", + streamId, captureId, mode); + std::lock_guard l(metaDatalock_); + if (mode == CAPTURE_SNAPSHOT) { + constexpr double latitude = 27.987500; // dummy data: Qomolangma latitde + constexpr double longitude = 86.927500; // dummy data: Qomolangma longituude + constexpr double altitude = 8848.86; // dummy data: Qomolangma altitude + constexpr size_t entryCapacity = 100; + constexpr size_t dataCapacity = 2000; + captureSetting_ = std::make_shared(entryCapacity, dataCapacity); + captureQuality_ = OHOS_CAMERA_JPEG_LEVEL_HIGH; + captureOrientation_ = OHOS_CAMERA_JPEG_ROTATION_270; + mirrorSwitch_ = OHOS_CAMERA_MIRROR_ON; + gps_.push_back(latitude); + gps_.push_back(longitude); + gps_.push_back(altitude); + captureSetting_->addEntry(OHOS_JPEG_QUALITY, static_cast(&captureQuality_), + sizeof(captureQuality_)); + captureSetting_->addEntry(OHOS_JPEG_ORIENTATION, static_cast(&captureOrientation_), + sizeof(captureOrientation_)); + captureSetting_->addEntry(OHOS_CONTROL_CAPTURE_MIRROR, static_cast(&mirrorSwitch_), + sizeof(mirrorSwitch_)); + captureSetting_->addEntry(OHOS_JPEG_GPS_COORDINATES, gps_.data(), gps_.size()); + } + + std::vector setting; + MetadataUtils::ConvertMetadataToVec(captureSetting_, setting); + captureInfo_.streamIds_ = {streamId}; + if (mode == CAPTURE_SNAPSHOT) { + captureInfo_.captureSetting_ = setting; + } else { + captureInfo_.captureSetting_ = cameraAbility_; + } + captureInfo_.enableShutterCallback_ = false; + + int rc = streamOperator_->Capture(captureId, captureInfo_, true); // 实际capture开始,buffer轮转开始 + if (rc != HDI::Camera::V1_0::NO_ERROR) { + CAMERA_LOGE("demo test: CaptureStart Capture error\n"); + streamOperator_->ReleaseStreams(captureInfo_.streamIds_); + return RC_ERROR; + } + if (mode == CAPTURE_PREVIEW) { - streamCustomerPreview_->ReceiveFrameOn(nullptr); // 创建预览线程接收递上来的buffer + streamCustomerPreview_->ReceiveFrameOn(nullptr); // 创建预览线程接收传递上来的buffer } else if (mode == CAPTURE_SNAPSHOT) { - streamCustomerCapture_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // 创建capture线程通过StoreImage回调接收递上来的buffer + streamCustomerCapture_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // 创建capture线程通过StoreImage回调接收传递上来的buffer StoreImage(addr, size); }); } else if (mode == CAPTURE_VIDEO) { OpenVideoFile(); - streamCustomerVideo_->ReceiveFrameOn([this](void* addr, const uint32_t size) {// 创建Video线程通过StoreVideo回调接收递上来的buffer + + streamCustomerVideo_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // 创建video线程通过StoreImage回调接收传递上来的buffer StoreVideo(addr, size); }); } + CAMERA_LOGD("demo test: CaptureON exit"); + return RC_OK; } ``` 3. ManuList()函数从控制台通过fgets()接口获取字符,不同字符所对应demo支持的功能不同,并打印出该demo所支持功能的菜单。 - ``` - static void ManuList(const std::shared_ptr& mainDemo, + ```c++ + static void ManuList(const std::shared_ptr& mainDemo, const int argc, char** argv) { int idx, c; - int awb = 1; - constexpr char shortOptions[] = "h:cwvaqof:"; - c = getopt_long(argc, argv, shortOptions, longOptions, &idx); - while(1) { + bool isAwb = true; + const char *shortOptions = "h:cwvaeqof:"; + c = getopt_long(argc, argv, shortOptions, LONG_OPTIONS, &idx); + while (1) { switch (c) { case 'h': c = PutMenuAndGetChr(); // 打印菜单 break; - - case 'f': + case 'f': FlashLightTest(mainDemo); // 手电筒功能测试 c = PutMenuAndGetChr(); break; @@ -670,27 +944,30 @@ Camera驱动的开发过程主要包含以下步骤: c = PutMenuAndGetChr(); break; case 'w': // AWB功能测试 - if (awb) { + if (isAwb) { mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_INCANDESCENT); } else { mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_OFF); } - awb = !awb; + isAwb = !isAwb; c = PutMenuAndGetChr(); break; case 'a': // AE功能测试 mainDemo->SetAeExpo(); c = PutMenuAndGetChr(); break; - case 'v': // Video功能测试 + case 'e': // Metadata测试 + mainDemo->SetMetadata(); + c = PutMenuAndGetChr(); + break; + case 'v': // VIDEO功能测试 VideoTest(mainDemo); c = PutMenuAndGetChr(); break; case 'q': // 退出demo PreviewOff(mainDemo); mainDemo->QuitDemo(); - exit(EXIT_SUCCESS); - + return; default: CAMERA_LOGE("main test: command error please retry input command"); c = PutMenuAndGetChr(); @@ -702,7 +979,7 @@ Camera驱动的开发过程主要包含以下步骤: PutMenuAndGetChr()接口打印了demo程序的菜单,并调用fgets()等待从控制台输入命令,内容如下: - ``` + ```c++ static int PutMenuAndGetChr(void) { constexpr uint32_t inputCount = 50; @@ -724,7 +1001,7 @@ Camera驱动的开发过程主要包含以下步骤: 控制台输出菜单详情如下: - ``` + ```c++ "Options:\n" "-h | --help Print this message\n" "-o | --offline stream offline test\n" @@ -732,8 +1009,24 @@ Camera驱动的开发过程主要包含以下步骤: "-w | --set WB Set white balance Cloudy\n" "-v | --video capture Video of 10s\n" "-a | --Set AE Set Auto exposure\n" + "-e | --Set Metadeta Set Metadata\n" "-f | --Set Flashlight Set flashlight ON 5s OFF\n" "-q | --quit stop preview and quit this app\n"); ``` - +4. 编译用例 + 在drivers/peripheral/camera/hal/BUILD.gn文件中的deps中添加“init:ohos_camera_demo”,示例代码如下: + ``` + deps = [ + "buffer_manager:camera_buffer_manager", + "device_manager:camera_device_manager", + "hdi_impl:camera_host_service_1.0", + "pipeline_core:camera_pipeline_core", + "utils:camera_utils", + "init:ohos_camera_demo", + ] + ``` + + 以RK3568为例: + 1. 执行全量编译命令./build.sh --product-name rk3568 --ccache,生成可执行二进制文件ohos_camera_demo,路径为:out/rk3568/packages/phone/vendor/bin/。 + 2. 将可执行文件ohos_camera_demo导入开发板,修改权限直接运行即可。 diff --git a/zh-cn/device-dev/driver/driver-peripherals-usb-des.md b/zh-cn/device-dev/driver/driver-peripherals-usb-des.md index c7dc8513b9e69d1dc158868e95350200c7952c6c..110197acf4352730f2df6e079b7e1c3cde344a6b 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-usb-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-usb-des.md @@ -1,90 +1,120 @@ # USB +## 概述 -## 概述 +### 功能简介 -USB Host部分,主要包括协议封装、设备管理、驱动安装与卸载等。 +USB(Universal Serial Bus)通用串行总线,包含了主机端(Host)和设备端(Device)。主机端负责USB总线中的数据传输及端口管理,设备端则可以连接各种外设,所以USB驱动开发又分为主机端驱动开发和设备端驱动开发。 -USB Device部分,支持USB功能设备的开发,提供USB设备相关功能,主要包括设备管理、配置管理、IO管理,实现USB功能设备创建、配置、数据通信等。 +OpenHarmony系统USB模块支持USB业务的开发,提供USB相关的功能,提供用户态第三方功能驱动的USB设备数据读写接口,以及提供创建和删除USB设备,接口的事件获取、打开和关闭等,管道同步异步读写通信,设置USB自定义属性等。 - USB Host和Device驱动模型如下图所示: +USB DDK(USB DriverDevelop Kit)是HDF驱动框架为开发者提供的USB驱动程序开发套件,包括USB Host DDK及USB Device DDK两部分,支持基于用户态开发USB设备驱动的同时,还提供了丰富的USB驱动开发能力,让广大开发者能精准且高效的开发USB驱动程序。 + +### 基本概念 + +- 管道 + + 管道(Pipe)是主机端和设备端点之间数据传输的模型。任何USB设备一旦上电就存在一个信息管道,即默认的控制管道,USB主机通过该管道来获取设备的描述、配置、状态,并对设备进行配置;管道和端点关联,两者有相同的属性,如支持的传输类型、最大包长度、传输方向等。 + +- 端点 + + 端点(Endpoint)是USB设备中的可以进行数据收发的最小单元,支持单向或者双向的数据传输。一个USB设备可以包括若干个端点,不同的端点以端点编号和方向区分。不同端点可以支持不同的传输类型、访问间隔以及最大数据包大小。除端点0外,所有的端点只支持一个方向的数据传输。端点0是一个特殊的端点,它支持双向的控制传输。 + +- 接口 + + 应用软件通过和设备之间的数据交换来完成设备的控制和数据传输。由于同一管道只支持一种类型的数据传输,因此这个过程中通常需要多个管道来完成数据交换。像这样用在一起来对设备进行控制的若干管道的集合称为接口。 + +- 描述符 + + 描述符(Descriptor)是用于描述设备属性(Attributes)的数据结构,第一个字节表示描述符的大小(字节数),第二个字节表示描述符的类型(Type)。 + +### 运作机制 + +#### USB Host DDK + +USB Host DDK为开发者提供了主机端USB驱动开发能力,按照功能分为三大类,分别是DDK初始化类、interface对象操作类及request对象操作类。 **图1** USB Host驱动模型图 ![image](figures/USB-Host驱动模型图.png "USB-Host驱动模型图") - +- USB Interface Pool负责USB Interface管理。提供USB Interface接口对象的申请和回收,USB Interface接口对象用来记录设备端口信息以及资源。USB Interface Pool按照USB Port对USB Interface进行分类管理。同时,此模块还提供了USB DDK API,方便开发者进行USB数据读写操作。 + +- USB Protocol Layer提供USB协议封装,根据USB协议对设备IO/控制命令进行翻译和解析”,同时负责设备描述符的管理,根据USB Device上报的枚举信息,匹配对应的描述符;构建对应的USB Interface接口对象,并将其加入到USB Interface Pool中管理。 + +- Device IO Manager负责USB IO请求管理,提供了同步IO和异步IO管理机制,对于异步IO,IO Manager负责将该请求记录下来,然后通过Raw API Library提供的接口依次处理待发送的IO请求;当收到USB控制器应答的处理结果后,IO接收线程负责解析并上报处理结果给上层调用者。 + +- Raw API Library抽象了底层OS能力,定义了统一的OS能力接口,对外提供了USB RAW API,方便开发者实现更加复杂的驱动功能。 + +- OS Adapter用于封装与平台(Linux和LiteOS)相关的操作,根据不同平台配置编译对应平台的封装接口。在Linux平台上,访问USB FS的操作,全部都封装在这个模块中;而在LiteOS平台上,基于FreeBSD USB框架的设备访问操作,也都全部封装在这个模块中。 + +- PNP Notify用于动态监测USB状态变化,当有新设备添加/移除时,变化设备信息。同时将所有USB设备信息都通过KHDF上报给UHDF侧的PNP Notify Manager模块来完成加载/卸载第三方功能驱动。 + +#### USB Device DDK + +USB Device DDK向开发者提供了设备端USB驱动开发能力。例如,USB端口动态注册和去注册能力,开发者可以基于能力实现USB端口的动态添加和组合;动态实例化能力,支持根据动态下发设备、配置、接口及端点描述符创建设备实例及传输通道;用户态的数据发送及接收能力,支持用户态下发送及接收数据;复合设备能力,支持一个物理设备上多个逻辑设备,实现多个逻辑设备间隔离,并支持不同逻辑设备同时被不同的应用进程访问。 + **图2** USB Device驱动模型图 ![image](figures/USB-Device驱动模型图.png "USB-Device驱动模型图") -USB驱动模型对外开放的API接口能力如下: +- SDK IF负责将USB设备按照设备、接口、管道进行逻辑划分,对配置管理、设备管理、IO管理进行封装。此模块还向开发者提供了设备创建、获取接口、接收Event事件、收发数据等设备测驱动开发的能力接口。 + +- Configuration Manager负责解析HCS文件描述的USB描述符信息,得到的USB描述符信息用于设备创建,同时模块还提供了自定义属性的读取、创建、删除、修改等操作。 + +- Device Manager负责根据配置模块解析USB描述符,并根据USB描述符创建设备。同时还负责获取设备、删除设备、获取设备状态,获取设备上面接口信息。 + +- IO Manager负责数据的读写,包括Events事件、数据读写完成后事件的接收,支持同步和异步模式数据读写。 + +- Adapter IF主要是对复合设备配置驱动及通用功能驱动设备节点操作进行封装,为上层提供统一的设备管理接口。 + +- Adapter该模块由复合设备配置驱动及通用功能驱动提供。 + +## 开发指导 -- USB Host DDK提供给用户态可直接调用的驱动能力接口,按照功能分类三大类:DDK初始化类、对interface对象操作类、对request对象操作类,可以提供DDK初始化、interface绑定和释放,打开和关闭操作,request的申请和释放,同步和异步传输等。 +由于内核态开发USB驱动较复杂,需要开发者对USB协议要有较深的了解才能很好的使用,对开发者的要求相对较高。USB DDK的引入是为了让开发者能在用户态更方便的开发USB驱动。 -- USB Device DDK提供设备管理、IO管理、配置管理,主要功能有:创建和删除设备、获取和打开接口、同步和异步传输等。 +### 场景介绍 +USB Host DDK为开发者提供了普通模式和专家模式,普通模式下,开发者可通过USB DDK API直接完成相关USB数据读写操作,不需要过多关注底层的传输细节。专家模式下,开发者通过USB RAW API直接访问OS平台中USB通道的接口,自定义实现更加复杂的功能。USB Device DDk为开发者提供了管理USB设备、接口定义及USB数据请求等功能。下文将介绍相关API。 ### 接口说明 -USB驱动模型Host侧开放的API接口功能,参考USB Host驱动模型图。 +USB主机端驱动程序开发相关接口(普通模式)如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/host/usb_ddk_interface.h)。 - **表1** usb_ddk_interface.h + **表1** USB主机端驱动程序开发相关接口(普通模式) | 接口名称 | 功能描述 | | -------- | -------- | | int32_t UsbInitHostSdk(struct UsbSession \*\*session); | USB主机端驱动开发工具包初始化 | -| int32_t UsbExitHostSdk(const struct UsbSession
\*session); | USB主机端驱动开发工具包退出 | | const struct UsbInterface \*UsbClaimInterface(const
struct UsbSession \*session, uint8_t busNum, uint8_t
usbAddr, uint8_t interfaceIndex); | 获取USB接口对象 | -| int32_t UsbReleaseInterface(const struct UsbInterface
\*interfaceObj); | 释放USB接口对象 | -| int32_t UsbAddOrRemoveInterface(const struct UsbSession
\*session, uint8_t busNum, uint8_t usbAddr, uint8_t
interfaceIndex, UsbInterfaceStatus status); | 增加移除接口 | | UsbInterfaceHandle \*UsbOpenInterface(const struct
UsbInterface \*interfaceObj); | 打开USB对象接口 | -| int32_t UsbCloseInterface(const UsbInterfaceHandle
\*interfaceHandle); | 关闭USB接口对象 | -| int32_t UsbSelectInterfaceSetting(const
UsbInterfaceHandle \*interfaceHandle, uint8_t
settingIndex, struct UsbInterface \*\*interfaceObj); | 设置可选配置 | | int32_t UsbGetPipeInfo(const UsbInterfaceHandle
\*interfaceHandle, uint8_t settingIndex, uint8_t pipeId,
struct UsbPipeInfo \*pipeInfo); | 获取指定可选设置的管道信息 | -| int32_t UsbClearInterfaceHalt(const
UsbInterfaceHandle \*interfaceHandle, uint8_t
pipeAddress); | 清除指定索引的管道状态 | | struct UsbRequest \*UsbAllocRequest(const
UsbInterfaceHandle \*interfaceHandle, int32_t isoPackets
, int32_t length); | 分配请求对象 | -| int32_t UsbFreeRequest(const struct UsbRequest
\*request); | 释放请求对象 | -| int32_t UsbSubmitRequestAsync(const struct UsbRequest
\*request); | 发送异步请求 | | int32_t UsbFillRequest(const struct UsbRequest
\*request, const UsbInterfaceHandle \*interfaceHandle,
const struct UsbRequestParams \*params); | 填充请求 | -| int32_t UsbCancelRequest(const struct UsbRequest
\*request); | 取消异步请求 | | int32_t UsbSubmitRequestSync(const struct UsbRequest
\*request); | 发送同步请求 | - **表2** usb_raw_api.h +USB主机端驱动程序开发相关接口(专家模式)如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/host/usb_raw_api.h)。 + + **表2** USB主机端驱动程序开发相关接口(专家模式) | 接口名称 | 功能描述 | | -------- | -------- | | int32_t UsbRawInit(struct UsbSession \*\*session); | USB驱动开发工具包专家模式初始化 | -| int32_t UsbRawExit(const struct UsbSession \*session); | USB驱动开发工具包专家模式退出 | | UsbRawHandle \*UsbRawOpenDevice(const struct
UsbSession \*session, uint8_t busNum, uint8_t
usbAddr); | 打开USB设备对象 | -| int32_t UsbRawCloseDevice(const UsbRawHandle
\*devHandle); | 关闭USB设备对象 | | int32_t UsbRawSendControlRequest(const struct
UsbRawRequest \*request, const UsbRawHandle
\*devHandle, const struct UsbControlRequestData
\*requestData); | 执行同步控制传输 | | int32_t UsbRawSendBulkRequest(const struct
UsbRawRequest \*request, const UsbRawHandle
\*devHandle, const struct UsbRequestData
\*requestData); | 执行同步批量传输 | | int32_t UsbRawSendInterruptRequest(const struct
UsbRawRequest \*request, const UsbRawHandle
\*devHandle, const struct UsbRequestData
\*requestData); | 执行同步中断传输 | | int32_t UsbRawGetConfigDescriptor(const UsbRawDevice
\*rawDev, uint8_t configIndex, struct
UsbRawConfigDescriptor \*\*config); | 获取给定设备指定ID的设备配置描述符 | -| void UsbRawFreeConfigDescriptor(const struct
UsbRawConfigDescriptor \*config); | 释放配置描述符内存空间 | -| int32_t UsbRawGetConfiguration(const UsbRawHandle
\*devHandle, int32_t \*config); | 获取当前激活配置 | -| int32_t UsbRawSetConfiguration(const UsbRawHandle
\*devHandle, int32_t config); | 设置当前激活配置 | -| int32_t UsbRawGetDescriptor(const struct UsbRawRequest
\*request, const UsbRawHandle \*devHandle, const struct
UsbRawDescriptorParam \*param, const unsigned char
\*data); | 获取描述符信息 | -| UsbRawDevice \*UsbRawGetDevice(const UsbRawHandle
\*devHandle); | 由设备句柄获取设备指针 | -| int32_t UsbRawGetDeviceDescriptor(const UsbRawDevice
\*rawDev, struct
UsbDeviceDescriptor \*desc); | 获取给定设备的USB设备描述符 | -| int32_t UsbRawClaimInterface(const UsbRawHandle
\*devHandle, int32_t
interfaceNumber); | 声明给定设备句柄上的接口 | -| int32_t UsbRawReleaseInterface(const UsbRawHandle
\*devHandle, in
t interfaceNumber); | 释放之前声明的接口 | -| int32_t UsbRawResetDevice(const UsbRawHandle
\*devHandle); | 复位设备 | -| struct UsbRawRequest \*UsbRawAllocRequest(const
UsbRawHandle
\*devHandle, int32_t isoPackets, int32_t length); | 分配一个带有指定数量的同步包描述符的传输请求 | -| int32_t UsbRawFreeRequest(const struct UsbRawRequest
\*request); | 释放之前分配的传输请求 | -| int32_t UsbRawFillBulkRequest(const struct UsbRawRequest
\*request, const UsbRawHandle \*devHandle, const struct
UsbRawFillRequestData \*fillData); | 填充批量传输请求所需信息 | -| int32_t UsbRawFillControlSetup(const unsigned char \*setup,
const struct UsbControlRequestData \*requestData); | 填充控制传输设置包所需信息 | -| int32_t UsbRawFillControlRequest(const struct UsbRawRequest
\*request, const UsbRawHandle \*devHandle, const struct
UsbRawFillRequestData \*fillData); | 填充控制传输请求所需信息 | | int32_t UsbRawFillInterruptRequest(const struct UsbRawRequest
\*request, const UsbRawHandle \*devHandle, const struct
UsbRawFillRequestData \*fillData); | 填充中断传输请求所需信息 | | int32_t UsbRawFillIsoRequest(const struct UsbRawRequest
\*request, const UsbRawHandle \*devHandle, const struct
UsbRawFillRequestData \*fillData); | 填充同步传输(Isochronous Transfers)请求所需信息 | | int32_t UsbRawSubmitRequest(const struct UsbRawRequest
\*request); | 提交一个传输请求 | | int32_t UsbRawCancelRequest(const struct UsbRawRequest
\*request); | 取消一个传输请求 | | int32_t UsbRawHandleRequests(const UsbRawHandle
\*devHandle); | 传输请求事件完成处理 | -USB驱动模型Device侧开放的API接口功能,参考USB Device驱动模型图。 +USB设备端用于管理USB设备的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_device.h)。 - **表3** usbfn_device.h + **表3** USB设备端用于管理USB设备的相关接口 | 接口名称 | 功能描述 | | -------- | -------- | @@ -92,7 +122,9 @@ USB驱动模型Device侧开放的API接口功能,参考USB Device驱动模型 | int32_t UsbFnRemoveDevice(struct UsbFnDevice
\*fnDevice); | 删除USB设备 | | const struct UsbFnDevice \*UsbFnGetDevice(const char
\*udcName); | 获取USB设备 | - **表4** usbfn_interface.h +USB设备端用于USB接口定义的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_interface.h)。 + + **表4** USB设备端用于USB接口定义的相关接口 | 接口名称 | 功能描述 | | -------- | -------- | @@ -103,7 +135,9 @@ USB驱动模型Device侧开放的API接口功能,参考USB Device驱动模型 | int32_t UsbFnGetInterfacePipeInfo(struct UsbFnInterface
\*interface, uint8_t pipeId, struct UsbFnPipeInfo \*info); | 获取管道信息 | | int32_t UsbFnSetInterfaceProp(const struct UsbFnInterface
\*interface, const char \*name, const char \*value); | 设置自定义属性 | - **表5** usbfn_request.h +USB设备端用于管理USB数据请求的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_request.h)。 + + **表5** USB设备端用于管理USB数据请求的相关接口 | 接口名称 | 功能描述 | | -------- | -------- | @@ -115,113 +149,304 @@ USB驱动模型Device侧开放的API接口功能,参考USB Device驱动模型 | int32_t UsbFnCancelRequest(struct UsbFnRequest \*req); | 取消请求 | -## 开发步骤 - -USB驱动是基于HDF框架、PLATFORM和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同USB器件提供统一的驱动模型。本篇开发指导以串口为例,分别介绍USB Host和USB Device驱动开发。 - +### 开发步骤 + +USB驱动基于HDF框架、Platform和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同USB器件提供统一的驱动模型。此处以串口为例,分别介绍USB Host和USB Device驱动开发的详细过程。 + +#### Host DDK API驱动开发 + +1. 在设备私有数据HCS中配置,完成主机端驱动总体信息的配置,具体如下: + + ```cpp + root { + module = "usb_pnp_device"; + usb_pnp_config { + match_attr = "usb_pnp_match"; + usb_pnp_device_id = "UsbPnpDeviceId"; + UsbPnpDeviceId { + idTableList = [ + "host_acm_table" + ]; + host_acm_table { + // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致 + moduleName = "usbhost_acm"; + // 驱动对外发布服务的名称,必须唯一 + serviceName = "usbhost_acm_pnp_service"; + // 驱动私有数据匹配关键字 + deviceMatchAttr = "usbhost_acm_pnp_matchAttr"; + // 从该字段开始(包含该字段)之后数据长度,以byte为单位 + length = 21; + // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber + matchFlag = 0x0303; + // 厂商编号 + vendorId = 0x12D1; + // 产品编号 + productId = 0x5000; + // 设备出厂编号,低16位 + bcdDeviceLow = 0x0000; + // 设备出厂编号,高16位 + bcdDeviceHigh = 0x0000; + // USB分配的设备类代码 + deviceClass = 0; + // USB分配的子类代码 + deviceSubClass = 0; + // USB分配的设备协议代码 + deviceProtocol = 0; + // 接口类型,根据实际需要可填写多个 + interfaceClass = [0]; + // 接口子类型,根据实际需要可填写多个 + interfaceSubClass = [2, 0]; + // 接口所遵循的协议,根据实际需要可填写多个 + interfaceProtocol = [1, 2]; + // 接口的编号,根据实际需要可填写多个 + interfaceNumber = [2, 3]; + } + } + } + } + ``` -### Host DDK API驱动开发步骤 +2. USB主机端驱动开发工具包初始化。 -1. 驱动匹配表配置。 + ```cpp + int32_t UsbInitHostSdk(struct UsbSession **session); + ``` -2. 初始化Host DDK。 +3. 步骤2初始化完后获取UsbInterface对象。 -3. 待步骤2初始化完后获取UsbInterface接口对象。 + ```cpp + const struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr, uint8_t interfaceIndex); + ``` 4. 打开步骤3获取到的UsbInterface接口对象,获取相应接口的UsbInterfaceHandle对象。 + ```cpp + UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj); + ``` + 5. 根据步骤4获取到的UsbInterfaceHandle对象,获取指定索引为pipeIndex的pipeInfo信息。 + ```cpp + int32_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex, uint8_t pipeId, struct UsbPipeInfo *pipeInfo); + ``` + 6. 为步骤4获取到的UsbInterfaceHandle预先分配待发送的IO Request对象。 + ```cpp + struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets, int32_t length); + ``` + 7. 根据输入参数params填充步骤6预先分配的IO Request。 + ```cpp + int32_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params); + ``` + 8. 提交IO Request对象,可以选择同步或异步两种模式。 + ```cpp + int32_t UsbSubmitRequestSync(const struct UsbRequest *request); //发送同步IO请求 + int32_t UsbSubmitRequestAsync(const struct UsbRequest *request); //发送异步IO请求 + ``` -### Host RAW API驱动开发步骤 +#### Host RAW API驱动开发 -1. 驱动匹配表配置。 +1. 同Host DDK API的步骤1一样,在设备私有数据HCS中配置。 2. 初始化Host RAW,并打开USB设备,然后获取描述符,通过描述符获取接口、端点信息。 -3. 分配Request,并根据传输类型使用相应接口对Request进行填充。 - -4. 提交IO Request对象,可以选择同步或异步两种模式。 - - -### Device DDK API驱动开发步骤 - -1. 构造描述符。 - -2. 创建设备,使用步骤1构造的描述符实例化一个USB设备。 - -3. 根据创建的设备获取接口(UsbFnDeviceGetInterface),获取Pipe信息(UsbFnInterfaceGetPipeInfo),打开接口获取Handle(UsbFnInterfaceOpen),根据Handle和Pipe号获取Request(UsbFnRequestAlloc)。 + ```cpp + int32_t UsbRawInit(struct UsbSession **session); + ``` + +3. 待步骤2完成后打开USB设备。 + + ```cpp + UsbRawHandle *UsbRawOpenDevice(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr); + ``` + +4. 待步骤3完成后获取描述符,通过描述符获取接口、端点信息。 + + ```cpp + int32_t UsbRawGetConfigDescriptor(const UsbRawDevice *rawDev, uint8_t configIndex, struct UsbRawConfigDescriptor **config); + ``` + +5. 分配Request,并根据传输类型使用相应接口对Request进行填充。 + + ```cpp + int32_t UsbRawFillBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于批量传输的请求 + int32_t UsbRawFillControlSetup(const unsigned char *setup, const struct UsbControlRequestData *requestData); + int32_t UsbRawFillControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于控制传输的请求 + int32_t UsbRawFillInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于中断传输的请求 + int32_t UsbRawFillIsoRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于同步传输的请求 + ``` + +6. 提交IO Request对象,可以选择同步或异步两种模式。 + + ```cpp + int32_t UsbRawSendControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbControlRequestData *requestData); //发送同步USB控制传输请求 + int32_t UsbRawSendBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData); //发送同步USB批量传输请求 + int32_t UsbRawSendInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData); //发送同步执行USB中断传输请求 + int32_t UsbRawSubmitRequest(const struct UsbRawRequest *request); //提交异步IO请求 + ``` + +#### Device DDK API驱动开发 + +1. 在设备功能代码中构造描述符。 + + ```cpp + static struct UsbFnFunction g_acmFunction = { // 功能描述符 + .enable = true, + .funcName = "f_generic.a", + .strings = g_acmStrings, + .fsDescriptors = g_acmFsFunction, + .hsDescriptors = g_acmHsFunction, + .ssDescriptors = g_acmSsFunction, + .sspDescriptors = NULL, + }; + struct UsbFnFunction *g_functions[] = { + #ifdef CDC_ECM + &g_ecmFunction, + #endif + #ifdef CDC_ACM + &g_acmFunction, + #endif + NULL + }; + static struct UsbFnConfiguration g_masterConfig = { // 配置描述符 + .configurationValue = 1, + .iConfiguration = USB_FUNC_CONFIG_IDX, + .attributes = USB_CFG_BUS_POWERED, + .maxPower = POWER, + .functions = g_functions, + }; + static struct UsbFnConfiguration *g_configs[] = { + &g_masterConfig, + NULL, + }; + static struct UsbDeviceDescriptor g_cdcMasterDeviceDesc = { // 设备描述符 + .bLength = sizeof(g_cdcMasterDeviceDesc), + .bDescriptorType = USB_DDK_DT_DEVICE, + .bcdUSB = CpuToLe16(BCD_USB), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_MAX_PACKET_SIZE, + .idVendor = CpuToLe16(DEVICE_VENDOR_ID), + .idProduct = CpuToLe16(DEVICE_PRODUCT_ID), + .bcdDevice = CpuToLe16(DEVICE_VERSION), + .iManufacturer = USB_FUNC_MANUFACTURER_IDX, + .iProduct = USB_FUNC_PRODUCT_IDX, + .iSerialNumber = USB_FUNC_SERIAL_IDX, + .bNumConfigurations = 1, + }; + static struct UsbFnDeviceDesc g_masterFuncDevice = { // 描述符入口 + .deviceDesc = &g_cdcMasterDeviceDesc, + .deviceStrings = g_devStrings, + .configs = g_configs, + }; + ``` + +2. 创建设备。描述符构造完成后,使用UsbFnDeviceCreate函数创建一个USB设备,并传入UDC控制器和UsbFnDescriptorData结构体。 + + ```cpp + if (useHcs == 0) { // 使用代码编写的描述符 + descData.type = USBFN_DESC_DATA_TYPE_DESC; + descData.descriptor = &g_acmFuncDevice; + } else { // 使用hcs编写的描述符 + descData.type = USBFN_DESC_DATA_TYPE_PROP; + descData.property = acm->device->property; + } + // 创建设备 + fnDev = (struct UsbFnDevice *) UsbFnCreateDevice(acm->udcName, &descData); + ``` + +3. 设备创建后,使用UsbFnGetInterface函数获取UsbInterface接口对象,并通过UsbFnGetInterfacePipeInfo函数获取USB管道信息。 + + ```cpp + // 获取接口 + fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); + // 获取Pipe信息 + UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo); + // 获取Handle + handle = UsbFnOpenInterface(fnIface); + // 获取控制(EP0)Request + req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle, + sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); + // 获取Request + req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle, + sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); + ``` + +4. 通过UsbFnStartRecvInterfaceEvent函数接收Event事件,并通过UsbFnEventCallback回调函数对Event事件做出响应。 + + ```cpp + // 开始接收Event事件 + ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); + // Event处理回调函数 + static void UsbAcmEventCallback(struct UsbFnEvent *event) + { + struct UsbAcmDevice *acm = NULL; + if (event == NULL || event->context == NULL) { + HDF_LOGE("%s: event is null", __func__); + return; + } -4. 接收Event事件(UsbFnInterfaceStartRecvEvent)如Enable、Setup等事件,回调函数(UsbFnEventCallback)中对Event事件做出响应。 + acm = (struct UsbAcmDevice *)event->context; + switch (event->type) { + case USBFN_STATE_BIND: + HDF_LOGI("%s: receive bind event", __func__); + break; + case USBFN_STATE_UNBIND: + HDF_LOGI("%s: receive unbind event", __func__); + break; + case USBFN_STATE_ENABLE: + HDF_LOGI("%s: receive enable event", __func__); + AcmEnable(acm); + break; + case USBFN_STATE_DISABLE: + HDF_LOGI("%s: receive disable event", __func__); + AcmDisable(acm); + acm->enableEvtCnt = 0; + break; + case USBFN_STATE_SETUP: + HDF_LOGI("%s: receive setup event", __func__); + if (event->setup != NULL) { + AcmSetup(acm, event->setup); + } + break; + case USBFN_STATE_SUSPEND: + HDF_LOGI("%s: receive suspend event", __func__); + AcmSuspend(acm); + break; + case USBFN_STATE_RESUME: + HDF_LOGI("%s: receive resume event", __func__); + AcmResume(acm); + break; + default: + break; + } + } + ``` 5. 收发数据,可以选择同步异步发送模式。 + ```cpp + notify = (struct UsbCdcNotification *)req->buf; + ... + if (memcpy_s((void *)(notify + 1), length, data, length) != EOK) { + return HDF_FAILURE; + } + ret = UsbFnSubmitRequestAsync(req); // 异步发送 + ``` -## 开发实例 +### 开发实例 本实例提供USB串口驱动开发示例,并简要对具体关键点进行开发说明。 - -### Host DDK API驱动开发 - - -``` -root { - module = "usb_pnp_device"; - usb_pnp_config { - match_attr = "usb_pnp_match"; - usb_pnp_device_id = "UsbPnpDeviceId"; - UsbPnpDeviceId { - idTableList = [ - "host_acm_table" - ]; - host_acm_table { - // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致 - moduleName = "usbhost_acm"; - // 驱动对外发布服务的名称,必须唯一 - serviceName = "usbhost_acm_pnp_service"; - // 驱动私有数据匹配关键字 - deviceMatchAttr = "usbhost_acm_pnp_matchAttr"; - // 从该字段开始(包含该字段)之后数据长度,以byte为单位 - length = 21; - // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber - matchFlag = 0x0303; - // 厂商编号 - vendorId = 0x12D1; - // 产品编号 - productId = 0x5000; - // 设备出厂编号,低16位 - bcdDeviceLow = 0x0000; - // 设备出厂编号,高16位 - bcdDeviceHigh = 0x0000; - // USB分配的设备类代码 - deviceClass = 0; - // USB分配的子类代码 - deviceSubClass = 0; - // USB分配的设备协议代码 - deviceProtocol = 0; - // 接口类型,根据实际需要可填写多个 - interfaceClass = [0]; - // 接口子类型,根据实际需要可填写多个 - interfaceSubClass = [2, 0]; - // 接口所遵循的协议,根据实际需要可填写多个 - interfaceProtocol = [1, 2]; - // 接口的编号,根据实际需要可填写多个 - interfaceNumber = [2, 3]; - } - } - } -} -``` +#### Host DDK API驱动开发 ```cpp - #include "usb_serial.h" #include "hdf_base.h" #include "hdf_log.h" @@ -234,7 +459,7 @@ root { #define HDF_LOG_TAG USB_HOST_ACM #define STR_LEN 512 -static struct UsbRequest *g_syncRequest = NULL; +static struct UsbRequest *g_syncRequest = NULL; // 定义一个USB请求 static struct UsbRequest *g_ctrlCmdRequest = NULL; static bool g_acmReleaseFlag = false; static uint8_t *g_acmReadBuffer = NULL; @@ -245,42 +470,41 @@ static int32_t SerialCtrlMsg(struct AcmDevice *acm, uint8_t request, int32_t ret; uint16_t index = acm->intPipe->interfaceId; struct UsbControlParams controlParams; - struct UsbRequestParams params; + struct UsbRequestParams params; // 定义一个USB请求参数对象 if (acm == NULL || buf == NULL) { - HDF_LOGE("%s:invalid param", __func__); return HDF_ERR_IO; } if (acm->ctrlReq == NULL) { + // 为获取到的UsbInterfaceHandle预先分配待发送的IO Request对象 acm->ctrlReq = UsbAllocRequest(acm->ctrDevHandle, 0, len); if (acm->ctrlReq == NULL) { - HDF_LOGE("%s: UsbAllocRequest failed", __func__); return HDF_ERR_IO; } } controlParams.request = request; - controlParams.target = USB_REQUEST_TARGET_INTERFACE; - controlParams.reqType = USB_REQUEST_TYPE_CLASS; - controlParams.direction = USB_REQUEST_DIR_TO_DEVICE; + controlParams.target = USB_REQUEST_TARGET_INTERFACE; // 接口对象 + controlParams.reqType = USB_REQUEST_TYPE_CLASS; // 请求类型 + controlParams.direction = USB_REQUEST_DIR_TO_DEVICE; // 从主机到设备的数据传输 controlParams.value = value; controlParams.index = index; controlParams.data = buf; controlParams.size = len; - params.interfaceId = USB_CTRL_INTERFACE_ID; + params.interfaceId = USB_CTRL_INTERFACE_ID; // 定义USB控制接口的默认ID params.pipeAddress = acm->ctrPipe->pipeAddress; params.pipeId = acm->ctrPipe->pipeId; - params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE; - params.timeout = USB_CTRL_SET_TIMEOUT; + params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE; // 控制类型 + params.timeout = USB_CTRL_SET_TIMEOUT; // 设置超时时间 params.ctrlReq = UsbControlSetUp(&controlParams); + // 根据params填充预先分配的IO Request ret = UsbFillRequest(acm->ctrlReq, acm->ctrDevHandle, ¶ms); - if (HDF_SUCCESS != ret) { - HDF_LOGE("%s: failed, ret=%d ", __func__, ret); + if (ret != HDF_SUCCESS) { return ret; } - ret = UsbSubmitRequestSync(acm->ctrlReq); //发送同步IO Request - if (HDF_SUCCESS != ret) { - HDF_LOGE("UsbSubmitRequestSync failed, ret=%d ", ret); + // 发送同步IO Request + ret = UsbSubmitRequestSync(acm->ctrlReq); + if (ret != HDF_SUCCESS) { return ret; } if (!acm->ctrlReq->compInfo.status) { @@ -293,8 +517,8 @@ static struct UsbInterface *GetUsbInterfaceById(const struct AcmDevice *acm, uint8_t interfaceIndex) { struct UsbInterface *tmpIf = NULL; - tmpIf = (struct UsbInterface *)UsbClaimInterface(acm->session, acm->busNum, - acm->devAddr, interfaceIndex); // 获取UsbInterface接口对象 + // 获取UsbInterface接口对象 + tmpIf = (struct UsbInterface *)UsbClaimInterface(acm->session, acm->busNum, acm->devAddr, interfaceIndex); return tmpIf; } ... @@ -303,8 +527,8 @@ static struct UsbPipeInfo *EnumePipe(const struct AcmDevice *acm, { uint8_t i; int32_t ret; - struct UsbInterfaceInfo *info = NULL; - UsbInterfaceHandle *interfaceHandle = NULL; + struct UsbInterfaceInfo *info = NULL; // 定义一个USB接口信息对象 + UsbInterfaceHandle *interfaceHandle = NULL; // 定义一个USB接口操作句柄,就是void *类型 if (pipeType == USB_PIPE_TYPE_CONTROL) { info = &acm->ctrIface->info; @@ -313,19 +537,20 @@ static struct UsbPipeInfo *EnumePipe(const struct AcmDevice *acm, else { info = &acm->iface[interfaceIndex]->info; + // 根据interfaceIndex获取设备句柄 interfaceHandle = InterfaceIdToHandle(acm, info->interfaceIndex); } for (i = 0; i <= info->pipeNum; i++) { struct UsbPipeInfo p; - ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p);// 获取指定索引为i的pipeInfo信息 + // 获取指定索引为i的pipeInfo信息 + ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p); if (ret < 0) { continue; } if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) { - struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi)); + struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi)); // 开辟内存并初始化 if (pi == NULL) { - HDF_LOGE("%s: Alloc pipe failed", __func__); return NULL; } p.interfaceId = info->interfaceIndex; @@ -341,7 +566,6 @@ static struct UsbPipeInfo *GetPipe(const struct AcmDevice *acm, { uint8_t i; if (acm == NULL) { - HDF_LOGE("%s: invalid params", __func__); return NULL; } for (i = 0; i < acm->interfaceCnt; i++) { @@ -349,6 +573,7 @@ static struct UsbPipeInfo *GetPipe(const struct AcmDevice *acm, if (!acm->iface[i]) { continue; } + // 获取控制pipe的pipeInfo信息 p = EnumePipe(acm, i, pipeType, pipeDirection); if (p == NULL) { continue; @@ -365,40 +590,32 @@ static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) errno_t err; struct AcmDevice *acm = NULL; if (device == NULL) { - HDF_LOGE("%s: device is null", __func__); return HDF_ERR_INVALID_OBJECT; } acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); if (acm == NULL) { - HDF_LOGE("%s: Alloc usb serial device failed", __func__); return HDF_FAILURE; } + // 初始化互斥锁,&acm->lock表示指向互斥量的指针 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { - HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__); goto error; } info = (struct UsbPnpNotifyServiceInfo *)device->priv; if (info != NULL) { - HDF_LOGD("%s:%d busNum=%d,devAddr=%d,interfaceLength=%d", - __func__, __LINE__, info->busNum, info->devNum, info->interfaceLength); acm->busNum = info->busNum; acm->devAddr = info->devNum; acm->interfaceCnt = info->interfaceLength; err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void*)info->interfaceNumber, info->interfaceLength); if (err != EOK) { - HDF_LOGE("%s:%d memcpy_s failed err=%d", - __func__, __LINE__, err); goto lock_error; } } else { - HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__); goto lock_error; } acm->device = device; device->service = &(acm->service); acm->device->service->Dispatch = UsbSerialDeviceDispatch; - HDF_LOGD("UsbSerialDriverBind=========================OK"); return HDF_SUCCESS; lock_error: @@ -416,9 +633,9 @@ static int32_t AcmAllocReadRequests(struct AcmDevice *acm) int32_t ret; struct UsbRequestParams readParams; for (int32_t i = 0; i < ACM_NR; i++) { - acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize); // 分配待发送的readReq IO Request对象 + // 分配待发送的readReq IO Request对象 + acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize); if (!acm->readReq[i]) { - HDF_LOGE("readReq request failed"); goto error; } readParams.userData = (void *)acm; @@ -426,14 +643,14 @@ static int32_t AcmAllocReadRequests(struct AcmDevice *acm) readParams.pipeId = acm->dataInPipe->pipeId; readParams.interfaceId = acm->dataInPipe->interfaceId; readParams.callback = AcmReadBulk; - readParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE; + readParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE; /* Data type */ readParams.timeout = USB_CTRL_SET_TIMEOUT; readParams.dataReq.numIsoPackets = 0; readParams.dataReq.direction = (acm->dataInPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & 0x1; readParams.dataReq.length = acm->readSize; - ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParams); // 填充待发送的readReq对象 - if (HDF_SUCCESS != ret) { - HDF_LOGE("%s: UsbFillRequest failed, ret=%d n", __func__, ret); + // 根据readParams填充预先分配待发送的readReq IO Request对象 + ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParams); + if (ret != HDF_SUCCESS) { goto error; } } @@ -448,9 +665,9 @@ static int32_t AcmAllocNotifyRequest(struct AcmDevice *acm) { int32_t ret; struct UsbRequestParams intParams = {}; - acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize); // 分配待发送的中断IO Request对象 + // 分配待发送的中断IO Request对象 + acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize); if (!acm->notifyReq) { - HDF_LOGE("notifyReq request failed"); return HDF_ERR_MALLOC_FAIL; } intParams.userData = (void *)acm; @@ -463,9 +680,9 @@ static int32_t AcmAllocNotifyRequest(struct AcmDevice *acm) intParams.dataReq.numIsoPackets = 0; intParams.dataReq.direction = (acm->intPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & DIRECTION_MASK; intParams.dataReq.length = acm->intSize; - ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParams); // 填充预先分配的中断IO Request - if (HDF_SUCCESS != ret) { - HDF_LOGE("%s: UsbFillRequest failed, ret=%d n", __func__, ret); + // 填充预先分配的中断IO Request + ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParams); + if (ret != HDF_SUCCESS) { goto error; } return HDF_SUCCESS; @@ -479,6 +696,7 @@ static void AcmReleaseInterfaces(struct AcmDevice *acm) { for (int32_t i = 0; i < acm->interfaceCnt; i++) { if (acm->iface[i]) { + // 释放一个USB接口对象 UsbReleaseInterface(acm->iface[i]); acm->iface[i] = NULL; } @@ -492,22 +710,23 @@ static void AcmReleaseInterfaces(struct AcmDevice *acm) static int32_t AcmClaimInterfaces(struct AcmDevice *acm) { for (int32_t i = 0; i < acm->interfaceCnt; i++) { - acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]); // 获取UsbInterface接口对象 + // 获取UsbInterface接口对象 + acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]); if (acm->iface[i] == NULL) { - HDF_LOGE("%s: interface%d is null", __func__, acm->interfaceIndex[i]); goto error; } } - acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID); // 获取控制接口对应的UsbInterface接口对象 + // 获取控制接口对应的UsbInterface接口对象 + acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID); if (acm->ctrIface == NULL) { - HDF_LOGE("%s: GetUsbInterfaceById null", __func__); goto error; } return HDF_SUCCESS; error: + // 根据acm->interfaceCnt循环释放接口对象 AcmReleaseInterfaces(acm); return HDF_FAILURE; } @@ -516,6 +735,7 @@ static void AcmCloseInterfaces(struct AcmDevice *acm) { for (int32_t i = 0; i < acm->interfaceCnt; i++) { if (acm->devHandle[i]) { + // 关闭一个USB设备对象 UsbCloseInterface(acm->devHandle[i]); acm->devHandle[i] = NULL; } @@ -530,49 +750,49 @@ static int32_t AcmOpenInterfaces(struct AcmDevice *acm) { for (int32_t i = 0; i < acm->interfaceCnt; i++) { if (acm->iface[i]) { - acm->devHandle[i] = UsbOpenInterface(acm->iface[i]); // 打开获取到的UsbInterface接口对象 + // 打开获取到的UsbInterface接口对象 + acm->devHandle[i] = UsbOpenInterface(acm->iface[i]); if (acm->devHandle[i] == NULL) { - HDF_LOGE("%s: UsbOpenInterface null", __func__); goto error; } } } acm->ctrDevHandle = UsbOpenInterface(acm->ctrIface); if (acm->ctrDevHandle == NULL) { - HDF_LOGE("%s: ctrDevHandle UsbOpenInterface null", __func__); goto error; } return HDF_SUCCESS; error: + // 关闭所有UsbInterface接口对象 AcmCloseInterfaces(acm); return HDF_FAILURE; } static int32_t AcmGetPipes(struct AcmDevice *acm) { - acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN);// 获取dataInPipe的pipeInfo信息 + // 获取dataInPipe的pipeInfo信息 + acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN); if (acm->dataInPipe == NULL) { - HDF_LOGE("dataInPipe is NULL"); goto error; } - acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT);// 获取dataOutPipe的pipeInfo信息 + // 获取dataOutPipe的pipeInfo信息 + acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT); if (acm->dataOutPipe == NULL) { - HDF_LOGE("dataOutPipe is NULL"); goto error; } - acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT); // 获取控制pipe的pipeInfo信息 + // 获取控制pipe的pipeInfo信息 + acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT); if (acm->ctrPipe == NULL) { - HDF_LOGE("ctrPipe is NULL"); goto error; } - acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN);// 获取中断pipe的pipeInfo信息 + // 获取中断pipe的pipeInfo信息 + acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN); if (acm->intPipe == NULL) { - HDF_LOGE("intPipe is NULL"); goto error; } @@ -580,10 +800,10 @@ static int32_t AcmGetPipes(struct AcmDevice *acm) acm->writeSize = acm->dataOutPipe->maxPacketSize; acm->ctrlSize = acm->ctrPipe->maxPacketSize; acm->intSize = acm->intPipe->maxPacketSize; - return HDF_SUCCESS; error: + // 释放设备中所有的管道信息 AcmFreePipes(acm); return HDF_FAILURE; } @@ -605,29 +825,26 @@ static int32_t AcmAllocRequests(struct AcmDevice *acm) int32_t ret; if (AcmWriteBufAlloc(acm) < 0) { - HDF_LOGE("%s: AcmWriteBufAlloc failed", __func__); return HDF_ERR_MALLOC_FAIL; } for (int32_t i = 0; i < ACM_NW; i++) { struct AcmWb *snd = &(acm->wb[i]); - snd->request = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize); //分配待发送的IO Request对象 + // 分配待发送的IO Request对象 + snd->request = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize); snd->instance = acm; if (snd->request == NULL) { - HDF_LOGE("%s:%d snd request failed", __func__, __LINE__); goto error_alloc_write_req; } } - ret = AcmAllocNotifyRequest(acm); // 分配并填充中断IO Request对象 + ret = AcmAllocNotifyRequest(acm); // 分配并填充中断IO Request对象 if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:%d AcmAllocNotifyRequest failed", __func__, __LINE__); goto error_alloc_int_req; } - ret = AcmAllocReadRequests(acm); // 分配并填充readReq IO Request对象 + ret = AcmAllocReadRequests(acm); // 分配并填充readReq IO Request对象 if (ret) { - HDF_LOGE("%s:%d AcmAllocReadRequests failed", __func__, __LINE__); goto error_alloc_read_req; } @@ -648,57 +865,56 @@ static int32_t AcmInit(struct AcmDevice *acm) struct UsbSession *session = NULL; if (acm->initFlag == true) { - HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__); return HDF_SUCCESS; } - ret = UsbInitHostSdk(NULL); // 初始化Host DDK + // 初始化Host DDK + ret = UsbInitHostSdk(NULL); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: UsbInitHostSdk failed", __func__); return HDF_ERR_IO; } acm->session = session; + // 根据acm->interfaceIndex[i]分别获取UsbInterface接口对象 ret = AcmClaimInterfaces(acm); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: AcmClaimInterfaces failed", __func__); goto error_claim_interfaces; } + // 根据acm->iface[i]分别打开UsbInterface接口对象 ret = AcmOpenInterfaces(acm); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: AcmOpenInterfaces failed", __func__); goto error_open_interfaces; } + // 获取管道信息的指针 ret = AcmGetPipes(acm); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: AcmGetPipes failed", __func__); goto error_get_pipes; } ret = AcmAllocRequests(acm); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: AcmAllocRequests failed", __func__); goto error_alloc_reqs; } - acm->lineCoding.dwDTERate = CpuToLe32(DATARATE); - acm->lineCoding.bCharFormat = CHARFORMAT; + acm->lineCoding.dwDTERate = CpuToLe32(DATARATE); // 转换为小端数据 + acm->lineCoding.bCharFormat = CHARFORMAT; // 8 acm->lineCoding.bParityType = USB_CDC_NO_PARITY; acm->lineCoding.bDataBits = USB_CDC_1_STOP_BITS; acm->initFlag = true; - - HDF_LOGD("%s:%d========OK", __func__, __LINE__); return HDF_SUCCESS; error_alloc_reqs: AcmFreePipes(acm); error_get_pipes: + // 关闭所有UsbInterface接口对象 AcmCloseInterfaces(acm); error_open_interfaces: + // 释放所有UsbInterface接口对象 AcmReleaseInterfaces(acm); error_claim_interfaces: + // 在主机端退出USB DDK,acm->session代表指向会话上下文的指针 UsbExitHostSdk(acm->session); acm->session = NULL; return ret; @@ -707,7 +923,6 @@ error_claim_interfaces: static void AcmRelease(struct AcmDevice *acm) { if (acm->initFlag == false) { - HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__); return; } @@ -715,9 +930,9 @@ static void AcmRelease(struct AcmDevice *acm) AcmFreePipes(acm); AcmCloseInterfaces(acm); AcmReleaseInterfaces(acm); + // 在主机端退出USB DDK UsbExitHostSdk(acm->session); acm->session = NULL; - acm->initFlag = false; } @@ -727,15 +942,15 @@ static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) struct AcmDevice *acm = NULL; if (device == NULL) { - HDF_LOGE("%s: device is null", __func__); return HDF_ERR_INVALID_OBJECT; } acm = (struct AcmDevice *)device->service; + // 初始化互斥锁,&acm->readLock表示指向互斥量的指针 OsalMutexInit(&acm->readLock); OsalMutexInit(&acm->writeLock); - HDF_LOGD("%s:%d busNum=%d,devAddr=%d", - __func__, __LINE__, acm->busNum, acm->devAddr); + HDF_LOGD("%s:%d busNum=%d,devAddr=%d", __func__, __LINE__, acm->busNum, acm->devAddr); + // 给USB串口设备信息开辟空间并赋值 ret = UsbSerialDeviceAlloc(acm); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: Serial Device alloc failed", __func__); @@ -743,9 +958,6 @@ static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) acm->initFlag = false; g_acmReleaseFlag = false; - - HDF_LOGD("%s:%d init ok!", __func__, __LINE__); - return ret; } @@ -754,43 +966,40 @@ static void UsbSerialDriverRelease(struct HdfDeviceObject *device) struct AcmDevice *acm = NULL; if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); return; } acm = (struct AcmDevice *)device->service; if (acm == NULL) { - HDF_LOGE("%s: acm is null", __func__); return; } g_acmReleaseFlag = true; if (acm->initFlag == true) { - HDF_LOGE("%s:%d AcmRelease", __func__, __LINE__); AcmRelease(acm); } + // 释放usb串口设备信息 UsbSeriaDevicelFree(acm); + // 释放互斥锁 OsalMutexDestroy(&acm->writeLock); OsalMutexDestroy(&acm->readLock); OsalMutexDestroy(&acm->lock); OsalMemFree(acm); acm = NULL; - HDF_LOGD("%s:%d exit", __func__, __LINE__); } +// 驱动的Bind、Init、及Release操作 struct HdfDriverEntry g_usbSerialDriverEntry = { .moduleVersion = 1, - .moduleName = "usbhost_acm", // 驱动模块名称,必须与hcs文件中配置的名称一致 + .moduleName = "usbhost_acm", // 驱动模块名称,必须与hcs文件中配置的名称一致 .Bind = UsbSerialDriverBind, .Init = UsbSerialDriverInit, .Release = UsbSerialDriverRelease, }; -HDF_INIT(g_usbSerialDriverEntry); +HDF_INIT(g_usbSerialDriverEntry); // 驱动入口 ``` - -### Host RAW API驱动开发 - +#### Host RAW API驱动开发 ```cpp root { @@ -851,7 +1060,7 @@ root { #include "hdf_log.h" #include "hdf_usb_pnp_manage.h" -#define HDF_LOG_TAG USB_HOST_ACM_RAW_API +#define HDF_LOG_TAG USB_HOST_ACM_RAW_API // 日志中可查寻的标签 #define USB_CTRL_REQ_SIZE 64 #define USB_IO_THREAD_STACK_SIZE 8192 #define USB_RAW_IO_SLEEP_MS_TIME 100 @@ -870,32 +1079,27 @@ static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConf int32_t ret; if (devHandle == NULL) { - HDF_LOGE("%s:%d devHandle is NULL", - __func__, __LINE__); return HDF_ERR_INVALID_PARAM; } + // 获取主用设备配置 ret = UsbRawGetConfiguration(devHandle, &activeConfig); - if (ret) { - HDF_LOGE("%s:%d UsbRawGetConfiguration failed, ret=%d", - __func__, __LINE__, ret); + if (ret != HDF_SUCCESS) { return HDF_FAILURE; } - HDF_LOGE("%s:%d activeConfig=%d", __func__, __LINE__, activeConfig); + + // 根据指定的设备句柄获取设备指针 dev = UsbRawGetDevice(devHandle); if (dev == NULL) { - HDF_LOGE("%s:%d UsbRawGetDevice failed", - __func__, __LINE__); return HDF_FAILURE; } + // 根据指定的设备ID获取设备配置描述符 ret = UsbRawGetConfigDescriptor(dev, activeConfig, config); - if (ret) { - HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%dn", ret); - return HDF_FAILURE; + if (ret != HDF_SUCCESS) { + HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%d\n", ret); } - - return HDF_SUCCESS; + return ret; } ... static int32_t UsbAllocWriteRequests(struct AcmDevice *acm) @@ -904,10 +1108,10 @@ static int32_t UsbAllocWriteRequests(struct AcmDevice *acm) for (i = 0; i < ACM_NW; i++) { struct AcmWb *snd = &acm->wb[i]; + // 分配一个具有指定数目的同步传输分组描述符的传输请求 snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize); snd->instance = acm; if (snd->request == NULL) { - HDF_LOGE("%s: UsbRawAllocRequest failed", __func__); return HDF_ERR_MALLOC_FAIL; } } @@ -923,17 +1127,14 @@ static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) errno_t err; if (device == NULL) { - HDF_LOGE("%s: device is null", __func__); return HDF_ERR_INVALID_OBJECT; } acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); if (acm == NULL) { - HDF_LOGE("%s: Alloc usb serial device failed", __func__); return HDF_FAILURE; } if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { - HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__); goto error; } @@ -945,19 +1146,15 @@ static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void*)info->interfaceNumber, info->interfaceLength); if (err != EOK) { - HDF_LOGE("%s:%d memcpy_s failed err=%d", - __func__, __LINE__, err); goto lock_error; } } else { - HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__); goto lock_error; } device->service = &(acm->service); device->service->Dispatch = UsbSerialDeviceDispatch; acm->device = device; - HDF_LOGD("UsbSerialDriverBind=========================OK"); return HDF_SUCCESS; lock_error: @@ -977,9 +1174,9 @@ static int32_t UsbAllocReadRequests(struct AcmDevice *acm) int32_t ret; for (int32_t i = 0; i < ACM_NR; i++) { + // 分配一个具有指定数目的同步传输分组描述符的传输请求 acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size); if (!acm->readReq[i]) { - HDF_LOGE("readReq request failed"); return HDF_ERR_MALLOC_FAIL; } @@ -990,10 +1187,9 @@ static int32_t UsbAllocReadRequests(struct AcmDevice *acm) reqData.timeout = USB_CTRL_SET_TIMEOUT; reqData.length = size; + // 在批量传输请求中填写所需信息 ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData); - if (ret) { - HDF_LOGE("%s: FillBulkRequest failed, ret=%d n", - __func__, ret); + if (ret != HDF_SUCCESS) { return HDF_FAILURE; } } @@ -1007,9 +1203,9 @@ static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm) int32_t size = acm->notifyEp->maxPacketSize; int32_t ret; + // 分配一个具有指定数目的同步传输分组描述符的传输请求 acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size); if (!acm->notifyReq) { - HDF_LOGE("notifyReq request failed"); return HDF_ERR_MALLOC_FAIL; } @@ -1020,9 +1216,9 @@ static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm) fillRequestData.userData = (void *)acm; fillRequestData.timeout = USB_CTRL_SET_TIMEOUT; + // 在中断传输请求中填充所需的信息 ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData); - if (ret) { - HDF_LOGE("%s: FillInterruptRequest failed, ret=%d", __func__, ret); + if (ret != HDF_SUCCESS) { return HDF_FAILURE; } @@ -1036,62 +1232,55 @@ static int32_t UsbSerialInit(struct AcmDevice *acm) int32_t ret; if (acm->initFlag == true) { - HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__); return HDF_SUCCESS; } + // 以专家模式初始化USB DDK ret = UsbRawInit(NULL); - if (ret) { - HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__); + if (ret != HDF_SUCCESS) { return HDF_ERR_IO; } acm->session = session; + // 打开一个USB设备对象 devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr); if (devHandle == NULL) { - HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__); ret = HDF_FAILURE; goto err_open_device; } acm->devHandle = devHandle; + // 获取主用设备配置、设备指针及配置描述符 ret = UsbGetConfigDescriptor(devHandle, &acm->config); - if (ret) { - HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__); + if (ret != HDF_SUCCESS) { ret = HDF_FAILURE; goto err_get_desc; } ret = UsbParseConfigDescriptor(acm, acm->config); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__); ret = HDF_FAILURE; goto err_parse_desc; } ret = AcmWriteBufAlloc(acm); if (ret < 0) { - HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__); ret = HDF_FAILURE; goto err_alloc_write_buf; } ret = UsbAllocWriteRequests(acm); if (ret < 0) { - HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__); ret = HDF_FAILURE; goto err_alloc_write_reqs; } ret = UsbAllocNotifyRequest(acm); if (ret) { - HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__); goto err_alloc_notify_req; } ret = UsbAllocReadRequests(acm); if (ret) { - HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__); goto err_alloc_read_reqs; } ret = UsbStartIo(acm); if (ret) { - HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__); goto err_start_io; } @@ -1102,18 +1291,14 @@ static int32_t UsbSerialInit(struct AcmDevice *acm) ret = UsbRawSubmitRequest(acm->notifyReq); if (ret) { - HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__); goto err_submit_req; } acm->initFlag = true; - - HDF_LOGD("%s:%d=========================OK", __func__, __LINE__); - return HDF_SUCCESS; err_submit_req: - UsbStopIo(acm); + UsbStopIo(acm); // 停止IO线程并释放所有资源 err_start_io: UsbFreeReadRequests(acm); err_alloc_read_reqs: @@ -1128,9 +1313,9 @@ err_parse_desc: UsbRawFreeConfigDescriptor(acm->config); acm->config = NULL; err_get_desc: - (void)UsbRawCloseDevice(devHandle); + (void)UsbRawCloseDevice(devHandle); // 关闭USB设备对象 err_open_device: - UsbRawExit(acm->session); + UsbRawExit(acm->session); // 退出USB DDK的专家模式 return ret; } @@ -1138,7 +1323,6 @@ err_open_device: static void UsbSerialRelease(struct AcmDevice *acm) { if (acm->initFlag == false) { - HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__); return; } @@ -1156,6 +1340,7 @@ static void UsbSerialRelease(struct AcmDevice *acm) UsbReleaseInterfaces(acm); UsbRawFreeConfigDescriptor(acm->config); acm->config = NULL; + // 退出USB DDK的专家模式 UsbRawExit(acm->session); acm->initFlag = false; @@ -1167,7 +1352,6 @@ static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) int32_t ret; if (device == NULL) { - HDF_LOGE("%s:%d device is null", __func__, __LINE__); return HDF_ERR_INVALID_OBJECT; } acm = (struct AcmDevice *)device->service; @@ -1181,9 +1365,6 @@ static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) acm->initFlag = false; g_rawAcmReleaseFlag = false; - - HDF_LOGD("%s:%d init ok!", __func__, __LINE__); - return ret; } @@ -1191,20 +1372,17 @@ static void UsbSerialDriverRelease(struct HdfDeviceObject *device) { struct AcmDevice *acm = NULL; if (device == NULL) { - HDF_LOGE("%s: device is NULL", __func__); return; } acm = (struct AcmDevice *)device->service; if (acm == NULL) { - HDF_LOGE("%s: acm is null", __func__); return; } g_rawAcmReleaseFlag = true; if (acm->initFlag == true) { - HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__); UsbSerialRelease(acm); } UsbSeriaDevicelFree(acm); @@ -1213,12 +1391,11 @@ static void UsbSerialDriverRelease(struct HdfDeviceObject *device) OsalMutexDestroy(&acm->lock); OsalMemFree(acm); acm = NULL; - HDF_LOGD("%s:%d exit", __func__, __LINE__); } struct HdfDriverEntry g_usbSerialRawDriverEntry = { .moduleVersion = 1, - .moduleName = "usbhost_acm_rawapi", //驱动模块名称,必须与hcs文件中配置的名称一致 + .moduleName = "usbhost_acm_rawapi", // 驱动模块名称,必须与hcs文件中配置的名称一致 .Bind = UsbSerialDriverBind, .Init = UsbSerialDriverInit, .Release = UsbSerialDriverRelease, @@ -1226,108 +1403,134 @@ struct HdfDriverEntry g_usbSerialRawDriverEntry = { HDF_INIT(g_usbSerialRawDriverEntry); ``` - -### Device DDK API驱动开发 +#### Device DDK API驱动开发 USB ACM设备核心代码路径为drivers\peripheral\usb\gadget\function\acm\cdcacm.c。其使用示例如下所示,首先根据描述符创建设备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。 -1、创建设备 -```cpp -static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, - struct DeviceResourceIface *iface) -{ - struct UsbFnDevice *fnDev = NULL; -struct UsbFnDescriptorData descData; -uint8_t useHcs; - ... -if (useHcs == 0) { - descData.type = USBFN_DESC_DATA_TYPE_DESC; - descData.descriptor = &g_masterFuncDevice; -} else { - descData.type = USBFN_DESC_DATA_TYPE_PROP; - descData.property = device->property; -} -/* 创建设备 */ - fnDev = (struct UsbFnDevice *)UsbFnDeviceCreate(acm->udcName, &descData); - if (fnDev == NULL) { - HDF_LOGE("%s: create usb function device failed", __func__); - return HDF_FAILURE; - } - ... -} -``` -2、获取接口,打开接口,获取Pipe信息 -```cpp -static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface) -{ - ... - for (i = 0; i < fnIface->info.numPipes; i++) { - struct UsbFnPipeInfo pipeInfo; -/* 获取pipe信息 */ - ret = UsbFnInterfaceGetPipeInfo(fnIface, i, &pipeInfo); +1. 创建设备。 + + ```cpp + static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, struct DeviceResourceIface *iface) + { + struct UsbFnDevice *fnDev = NULL; + struct UsbFnDescriptorData descData; + uint8_t useHcs; + ... + if (useHcs == 0) { // 描述符来自于代码中编码 + descData.type = USBFN_DESC_DATA_TYPE_DESC; + descData.descriptor = &g_masterFuncDevice; + } else { // 描述符来自于解析hcs文件 + descData.type = USBFN_DESC_DATA_TYPE_PROP; + descData.property = device->property; + } + /* 创建设备 */ + fnDev = (struct UsbFnDevice *)UsbFnDeviceCreate(acm->udcName, &descData); + if (fnDev == NULL) { + return HDF_FAILURE; + } ... } - return HDF_SUCCESS; -} -/* 获取接口,打开接口获取handle */ -static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev) -{ - ... - for (i = 0; i < fnDev->numInterfaces; i++) { - /* 获取接口 */ - fnIface = (struct UsbFnInterface *)UsbFnDeviceGetInterface(fnDev, i); + ``` + +2. 获取接口,打开接口,获取Pipe信息 + + ```cpp + static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface) + { ... - /* 打开接口 */ - handle = UsbFnInterfaceOpen(fnIface); + for (i = 0; i < fnIface->info.numPipes; i++) { + struct UsbFnPipeInfo pipeInfo; + /* 获取pipe信息 */ + ret = UsbFnInterfaceGetPipeInfo(fnIface, i, &pipeInfo); + ... + } + return HDF_SUCCESS; + } + /* 获取接口,打开接口获取handle */ + static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev) + { ... + for (i = 0; i < fnDev->numInterfaces; i++) { + /* 获取接口 */ + fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); + ... + /* 打开接口 */ + handle = UsbFnInterfaceOpen(fnIface); + ... + } + return HDF_SUCCESS; } - return HDF_SUCCESS; -} -``` + ``` -3、接收Event事件 -```cpp -static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num) -{ - ... +3. 接收Event事件(EP0控制传输) + + ```cpp + static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num) + { + ... req = UsbFnCtrlRequestAlloc(acm->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); - ... -} -static int32_t AcmDriverInit(struct HdfDeviceObject *device) -{ -... -/* 开始接收Event */ - ret = UsbFnInterfaceStartRecvEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); - ... -} -``` -4、进行USB通信(读写等) -```cpp -static int32_t AcmSendNotifyRequest(struct UsbAcmDevice *acm, uint8_t type, - uint16_t value, void *data, uint32_t length) -{ -... -/* 异步发送 */ - ret = UsbFnRequestSubmitAsync(req); - ... -} -``` -5、关闭接口,停止Event接收,删除设备 -```cpp -static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm) -{ -int32_t ret; -/* 关闭接口 */ - (void)UsbFnInterfaceClose(acm->ctrlIface.handle); -(void)UsbFnInterfaceClose(acm->dataIface.handle); -/* 停止接收Event */ -(void)UsbFnInterfaceStopRecvEvent(acm->ctrlIface.fn); -/* 删除设备 */ - ret = UsbFnDeviceRemove(acm->fnDev); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: remove usb function device failed", __func__); + ... } - return ret; -} -``` + static int32_t AcmDriverInit(struct HdfDeviceObject *device) + { + ... + /* 开始接收Event */ + ret = UsbFnInterfaceStartRecvEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); + ... + } + ``` + +4. 进行USB通信(读写等) + + ```cpp + static int32_t AcmSendNotifyRequest(struct UsbAcmDevice *acm, uint8_t type, + uint16_t value, void *data, uint32_t length) + { + ... + /* 异步发送 */ + ret = UsbFnRequestSubmitAsync(req); + ... + } + ``` + +5. 关闭接口,停止Event接收,删除设备 + + ```cpp + static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm) + { + int32_t ret; + /* 关闭接口 */ + (void)UsbFnInterfaceClose(acm->ctrlIface.handle); + (void)UsbFnInterfaceClose(acm->dataIface.handle); + /* 停止接收Event EP0控制传输 */ + (void)UsbFnInterfaceStopRecvEvent(acm->ctrlIface.fn); + /* 删除设备 */ + ret = UsbFnDeviceRemove(acm->fnDev); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: remove usb function device failed", __func__); + } + return ret; + } + ``` + +## 参考 + +- 代码仓库如下: + + **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)** + + [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral) + + [drivers\_interface](https://gitee.com/openharmony/drivers_interface) + +- 代码路径如下: + + USB驱动模型liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/usb + + USB DDK驱动加载实现://drivers/hdf_core/framework/model/usb + + USB HDI服务端实现://drivers/peripheral/usb/hdi_service + + USB HDI对外接口://out/{product_name}/gen/drivers/interface/usb/v1_0 + diff --git a/zh-cn/device-dev/driver/driver-platform-gpio-des.md b/zh-cn/device-dev/driver/driver-platform-gpio-des.md index b3d99b7cf87f7a3e9f88f5ae77c6abde0baca7b0..b2d1db7482526a64656b2608848d2f599a10bcc0 100644 --- a/zh-cn/device-dev/driver/driver-platform-gpio-des.md +++ b/zh-cn/device-dev/driver/driver-platform-gpio-des.md @@ -1,256 +1,361 @@ # GPIO - ## 概述 +### 功能简介 + GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 GPIO接口定义了操作GPIO管脚的标准方法集合,包括: -- 设置管脚方向:方向可以是输入或者输出(暂不支持高阻态) +- 设置管脚方向:方向可以是输入或者输出(暂不支持高阻态)。 +- 读写管脚电平值:电平值可以是低电平或高电平。 +- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式。 +- 使能和禁止管脚中断:禁止或使能管脚中断。 + +### 基本概念 + +GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。可以通过软件来控制其输入和输出,即I/O控制。 + +- GPIO输入 -- 读写管脚电平值:电平值可以是低电平或高电平 + 输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。 -- 设置管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式 +- GPIO输出 -- 使能和禁止管脚中断:禁止或使能管脚中断 + 输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。 +### 运作机制 -## 接口说明 +在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。GPIO模块接口适配模式采用统一服务模式(如图1所示)。 - **表1** GPIO驱动API接口功能介绍 +在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。 -| 功能分类 | 接口描述 | -| -------- | -------- | -| GPIO读写 | - GpioRead:读管脚电平值
- GpioWrite:写管脚电平值 | -| GPIO配置 | - GpioSetDir:设置管脚方向
- GpioGetDir:获取管脚方向 | -| GPIO中断设置 | - GpioSetIrq:设置管脚对应的中断服务函数
- GpioUnsetIrq:取消管脚对应的中断服务函数
- GpioEnableIrq:使能管脚中断
- GpioDisableIrq:禁止管脚中断 | +GPIO模块各分层作用: -> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
-> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 +- 接口层提供操作GPIO管脚的标准方法。 +- 核心层主要提供GPIO管脚资源匹配,GPIO管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互,供芯片厂家快速接入HDF框架。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 +**图 1** GPIO统一服务模式结构图 + +![GPIO统一服务模式结构图](figures/统一服务模式结构图.png) ## 使用指导 +### 场景介绍 + +GPIO仅是一个软件层面的概念,主要工作是GPIO管脚资源管理。开发者可以使用提供的GPIO操作接口,实现对管脚控制。 + +### 接口说明 + +GPIO模块提供的主要接口如表1所示。 + +**表1** GPIO驱动API接口功能介绍 -### 使用流程 +| 接口名 | 描述 | +| ------------------------------------------------------------ | ------------------------------ | +| GpioGetByName(const char *gpioName) | 获取GPIO管脚ID | +| int32_t GpioRead(uint16_t gpio, uint16_t *val) | 读GPIO管脚电平值 | +| int32_t GpioWrite(uint16_t gpio, uint16_t val) | 写GPIO管脚电平值 | +| int32_t GpioGetDir(uint16_t gpio, uint16_t *dir) | 获取GPIO管脚方向 | +| int32_t GpioSetDir(uint16_t gpio, uint16_t dir) | 设置GPIO管脚方向 | +| int32_t GpioUnsetIrq(uint16_t gpio, void *arg); | 取消GPIO管脚对应的中断服务函数 | +| int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg) | 设置GPIO管脚对应的中断服务函数 | +| int32_t GpioEnableIrq(uint16_t gpio) | 使能GPIO管脚中断 | +| int32_t GpioDisableIrq(uint16_t gpio) | 禁止GPIO管脚中断 | + +>![](../public_sys-resources/icon-note.gif) **说明:**
+>本文涉及GPIO的所有接口,支持内核态及用户态使用。 + +### 开发步骤 GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如下图所示。 - **图1** GPIO使用流程图 +**图1** GPIO使用流程图 - ![image](figures/GPIO使用流程图.png "GPIO使用流程图") +![image](figures/GPIO使用流程图.png "GPIO使用流程图") +#### 确定GPIO管脚号 -### 确定GPIO管脚号 +两种方式获取管脚号:根据SOC芯片规则进行计算、通过管脚别名获取 -不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 +- 根据SOC芯片规则进行计算 -- Hi3516DV300 - 控制器管理12组GPIO管脚,每组8个。 + 不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。 - GPIO号 = GPIO组索引 (0~11) \* 每组GPIO管脚数(8) + 组内偏移 + - Hi3516DV300 - 举例:GPIO10_3的GPIO号 = 10 \* 8 + 3 = 83 + 控制器管理12组GPIO管脚,每组8个。 -- Hi3518EV300 - 控制器管理10组GPIO管脚,每组10个。 + GPIO号 = GPIO组索引 (0~11) \* 每组GPIO管脚数(8) + 组内偏移 - GPIO号 = GPIO组索引 (0~9) \* 每组GPIO管脚数(10) + 组内偏移 + 举例:GPIO10_3的GPIO号 = 10 \* 8 + 3 = 83 - 举例:GPIO7_3的GPIO管脚号 = 7 \* 10 + 3 = 73 + - Hi3518EV300 + 控制器管理10组GPIO管脚,每组10个。 -### 使用API操作GPIO管脚 + GPIO号 = GPIO组索引 (0~9) \* 每组GPIO管脚数(10) + 组内偏移 -- 设置GPIO管脚方向 - 在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: + 举例:GPIO7_3的GPIO管脚号 = 7 \* 10 + 3 = 73 - int32_t GpioSetDir(uint16_t gpio, uint16_t dir); +- 通过管脚别名获取 - **表2** GpioSetDir参数和返回值描述 - - | **参数**| **参数描述** | - | -------- | -------- | - | gpio | 待设置的GPIO管脚号 | - | dir | 待设置的方向值 | - | **返回值** | **返回值描述** | - | 0 | 设置成功 | - | 负数 | 设置失败 | + 调用接口GpioGetByName进行获取,入参是该管脚的别名,接口返回值是管脚的全局ID。 -- 读写GPIO管脚 + ```c + GpioGetByName(const char *gpioName); + ``` - 如果要读取一个GPIO管脚电平,通过以下函数完成: +#### 设置GPIO管脚方向 - int32_t GpioRead(uint16_t gpio, uint16_t \*val); +在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向: - **表3** GpioRead参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | 待读取的GPIO管脚号 | - | val | 接收读取电平值的指针 | - | **返回值** | **返回值描述** | - | 0 | 读取成功 | - | 负数 | 读取失败 | +```c +int32_t GpioSetDir(uint16_t gpio, uint16_t dir); +``` - 如果要向GPIO管脚写入电平值,通过以下函数完成: +**表2** GpioSetDir参数和返回值描述 - int32_t GpioWrite(uint16_t gpio, uint16_t val); +| **参数** | **参数描述** | +| ---------- | ------------------ | +| gpio | GPIO管脚号 | +| dir | 待设置的方向值 | +| **返回值** | **返回值描述** | +| 0 | 设置成功 | +| 负数 | 设置失败 | - **表4** GpioWrite参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | 待写入的GPIO管脚号 | - | val | 待写入的电平值 | - | **返回值** | **返回值描述** | - | 0 | 写入成功 | - | 负数 | 写入失败 | +假设需要将GPIO管脚3的方向配置为输出,其使用示例如下: - 示例代码: +```c +int32_t ret; - - ``` - int32_t ret; - uint16_t val; - /* 将3号GPIO管脚配置为输出 */ - ret = GpioSetDir(3, GPIO_DIR_OUT); - if (ret != 0) { - HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); - return; - } - /* 向3号GPIO管脚写入低电平GPIO_VAL_LOW */ - ret = GpioWrite(3, GPIO_VAL_LOW); - if (ret != 0) { - HDF_LOGE("GpioWrite: failed, ret %d\n", ret); - return; - } - /* 将6号GPIO管脚配置为输入 */ - ret = GpioSetDir(6, GPIO_DIR_IN); - if (ret != 0) { - HDF_LOGE("GpioSetDir: failed, ret %d\n", ret); - return; - } - /* 读取6号GPIO管脚的电平值 */ - ret = GpioRead(6, &val); - ``` +ret = GpioSetDir(3, GPIO_DIR_OUT); // 将3号GPIO管脚配置为输出 +if (ret != 0) { + HDF_LOGE("GpioSerDir: failed, ret %d\n", ret); + return ret; +} +``` -- 设置GPIO中断 +#### 获取GPIO管脚方向 - 如果要为一个GPIO管脚设置中断响应程序,使用如下函数: +可以通过如下函数获取GPIO管脚方向: - int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void \*arg); +```c +int32_t GpioGetDir(uint16_t gpio, uint16_t *dir); +``` - **表5** GpioSetIrq参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | GPIO管脚号 | - | mode | 中断触发模式 | - | func | 中断服务程序 | - | arg | 传递给中断服务程序的入参 | - | **返回值** | **返回值描述** | - | 0 | 设置成功 | - | 负数 | 设置失败 | +**表2** GpioGetDir参数和返回值描述 - > ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
- > 同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 +| **参数** | **参数描述** | +| ---------- | ------------------ | +| gpio | GPIO管脚号 | +| dir | 待获取的方向值 | +| **返回值** | **返回值描述** | +| 0 | 设置成功 | +| 负数 | 设置失败 | - 当不再需要响应中断服务函数时,使用如下函数取消中断设置: +假设需要将GPIO管脚3的方向配置为输出,其使用示例如下: - int32_t GpioUnsetIrq(uint16_t gpio, void \*arg); +```c +int32_t ret; +uin16_t dir; - **表6** GpioUnsetIrq参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | GPIO管脚号 | - | arg | GPIO中断数据 | - | **返回值** | **返回值描述** | - | 0 | 取消成功 | - | 负数 | 取消失败 | +ret = GpioGetDir(3, &dir); // 获取3号GPIO管脚方向 +if (ret != 0) { + HDF_LOGE("GpioGetDir: failed, ret %d\n", ret); + return ret; +} +``` - 在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: +#### 读取GPIO管脚电平值 - int32_t GpioEnableIrq(uint16_t gpio); +如果要读取一个GPIO管脚电平,通过以下函数完成: - **表7** GpioEnableIrq参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | GPIO管脚号 | - | **返回值** | **返回值描述** | - | 0 | 使能成功 | - | 负数 | 使能失败 | +```c +int32_t GpioRead(uint16_t gpio, uint16_t *val); +``` - > ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
- > 必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 +**表3** GpioRead参数和返回值描述 - 如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: +| **参数** | **参数描述** | +| ---------- | -------------------- | +| gpio | GPIO管脚号 | +| val | 接收读取电平值的指针 | +| **返回值** | **返回值描述** | +| 0 | 读取成功 | +| 负数 | 读取失败 | - int32_t GpioDisableIrq(uint16_t gpio); +假设需要读取GPIO管脚3的电平值,其使用示例如下: - **表8** GpioDisableIrq参数和返回值描述 - - | **参数** | **参数描述** | - | -------- | -------- | - | gpio | GPIO管脚号 | - | **返回值** | **返回值描述** | - | 0 | 禁止成功 | - | 负数 | 禁止失败 | +```c +int32_t ret; +uint16_t val; - 示例代码: +ret = GpioRead(3, &val); // 读取3号GPIO管脚电平值 +if (ret != 0) { + HDF_LOGE("GpioRead: failed, ret %d\n", ret); + return ret; +} +``` - - ``` - /* 中断服务函数*/ - int32_t MyCallBackFunc(uint16_t gpio, void *data) - { - HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data); - return 0; - } - - int32_t ret; - /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ - ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); - if (ret != 0) { - HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); - return; - } - - /* 使能3号GPIO管脚中断 */ - ret = GpioEnableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); - return; - } - - /* 禁止3号GPIO管脚中断 */ - ret = GpioDisableIrq(3); - if (ret != 0) { - HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); - return; - } - - /* 取消3号GPIO管脚中断服务程序 */ - ret = GpioUnsetIrq(3, NULL); - if (ret != 0) { - HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); - return; - } - ``` +#### 写入GPIO管脚电平值 + +如果要向GPIO管脚写入电平值,通过以下函数完成: + +```c +int32_t GpioWrite(uint16_t gpio, uint16_t val); +``` + +**表4** GpioWrite参数和返回值描述 + +| **参数** | **参数描述** | +| ---------- | ------------------ | +| gpio | GPIO管脚号 | +| val | 待写入的电平值 | +| **返回值** | **返回值描述** | +| 0 | 写入成功 | +| 负数 | 写入失败 | + +假设需要给GPIO管脚3写入低电平值,其使用示例如下: + +```c +int32_t ret; + +ret = GpioWrite(3, GPIO_VAL_LOW); // 给3号GPIO管脚写入低电平值 +if (ret != 0) { + HDF_LOGE("GpioRead: failed, ret %d\n", ret); + return ret; +} +``` + +#### 设置GPIO管脚中断 +如果要为一个GPIO管脚设置中断响应程序,使用如下函数: + +```c +int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg); +``` + +**表5** GpioSetIrq参数和返回值描述 + +| **参数** | **参数描述** | +| ---------- | ------------------------ | +| gpio | GPIO管脚号 | +| mode | 中断触发模式 | +| func | 中断服务程序 | +| arg | 传递给中断服务程序的入参 | +| **返回值** | **返回值描述** | +| 0 | 设置成功 | +| 负数 | 设置失败 | + +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
+> 同一时间,只能为某个GPIO管脚设置一个中断服务函数,如果重复调用GpioSetIrq函数,则之前设置的中断服务函数会被取代。 + +#### 取消GPIO管脚中断 + +当不再需要响应中断服务函数时,使用如下函数取消中断设置: + +```c +int32_t GpioUnsetIrq(uint16_t gpio, void *arg); +``` + +**表6** GpioUnsetIrq参数和返回值描述 + +| **参数** | **参数描述** | +| ---------- | -------------- | +| gpio | GPIO管脚号 | +| arg | GPIO中断数据 | +| **返回值** | **返回值描述** | +| 0 | 取消成功 | +| 负数 | 取消失败 | + +#### 使能GPIO管脚中断 + +在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断: + +```c +int32_t GpioEnableIrq(uint16_t gpio); +``` + +**表7** GpioEnableIrq参数和返回值描述 + +| **参数** | **参数描述** | +| ---------- | -------------- | +| gpio | GPIO管脚号 | +| **返回值** | **返回值描述** | +| 0 | 使能成功 | +| 负数 | 使能失败 | + +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
+> 必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。 + +#### 禁止GPIO管脚中断 + +如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断: + +```c +int32_t GpioDisableIrq(uint16_t gpio); +``` +**表8** GpioDisableIrq参数和返回值描述 + +| **参数** | **参数描述** | +| ---------- | -------------- | +| gpio | GPIO管脚号 | +| **返回值** | **返回值描述** | +| 0 | 禁止成功 | +| 负数 | 禁止失败 | + +中断相关操作示例: + +```c +/* 中断服务函数*/ +int32_t MyCallBackFunc(uint16_t gpio, void *data) +{ + HDF_LOGI("%s: gpio:%u interrupt service in data\n", __func__, gpio); + return 0; +} + +int32_t ret; +/* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */ +ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL); +if (ret != 0) { + HDF_LOGE("GpioSetIrq: failed, ret %d\n", ret); + return ret; +} + +/* 使能3号GPIO管脚中断 */ +ret = GpioEnableIrq(3); +if (ret != 0) { + HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret); + return ret; +} + +/* 禁止3号GPIO管脚中断 */ +ret = GpioDisableIrq(3); +if (ret != 0) { + HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret); + return ret; +} + +/* 取消3号GPIO管脚中断服务程序 */ +ret = GpioUnsetIrq(3, NULL); +if (ret != 0) { + HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret); + return ret; +} +``` ## 使用实例 本实例程序中,我们将测试一个GPIO管脚的中断触发:为管脚设置中断服务函数,触发方式为边沿触发,然后通过交替写高低电平到管脚,产生电平波动,制造触发条件,观察中断服务函数的执行。 -首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300某开发板,GPIO管脚选择GPIO10_3,换算成GPIO号为83。 +首先需要选取一个空闲的GPIO管脚,本例程基于Hi3516DV300开发板,GPIO管脚选择GPIO10_3,换算成GPIO号为83。 - 读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 - -``` +读者可以根据自己使用的开发板,参考其原理图,选择一个空闲的GPIO管脚即可。 + +```c #include "gpio_if.h" #include "hdf_log.h" #include "osal_irq.h" @@ -261,7 +366,7 @@ static uint32_t g_irqCnt; /* 中断服务函数*/ static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data) { - HDF_LOGE("%s: irq triggered! on gpio:%u, data=%p", __func__, gpio, data); + HDF_LOGE("%s: irq triggered! on gpio:%u, in data", __func__, gpio); g_irqCnt++; /* 如果中断服务函数触发执行,则将全局中断计数加1 */ return GpioDisableIrq(gpio); } @@ -319,4 +424,4 @@ static int32_t TestCaseGpioIrqEdge(void) (void)GpioUnsetIrq(gpio, NULL); return (g_irqCnt > 0) ? HDF_SUCCESS : HDF_FAILURE; } -``` +``` \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-gpio-develop.md b/zh-cn/device-dev/driver/driver-platform-gpio-develop.md index a9336743edacb5668f27205239f7b8f328bd3878..7b15fc2935bfbde69ee7622b11ab9ad88d6f54f2 100755 --- a/zh-cn/device-dev/driver/driver-platform-gpio-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-gpio-develop.md @@ -1,269 +1,386 @@ # GPIO - ## 概述 -GPIO(General-purpose input/output)即通用型输入输出,在HDF框架中,GPIO的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。 +### 功能简介 - **图1** GPIO无服务模式结构图 +GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。 - ![](figures/无服务模式结构图.png "GPIO无服务模式结构图") +### 基本概念 +GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。可以通过软件来控制其输入和输出,即I/O控制。 -## 接口说明 +- GPIO输入 -GpioMethod定义: + 输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。 - -``` -struct GpioMethod { - int32_t (*request)(struct GpioCntlr *cntlr, uint16_t local);// 【预留】 - int32_t (*release)(struct GpioCntlr *cntlr, uint16_t local);// 【预留】 - int32_t (*write)(struct GpioCntlr *cntlr, uint16_t local, uint16_t val); - int32_t (*read)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *val); - int32_t (*setDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t dir); - int32_t (*getDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *dir); - int32_t (*toIrq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *irq);// 【预留】 - int32_t (*setIrq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode, GpioIrqFunc func, void *arg); - int32_t (*unsetIrq)(struct GpioCntlr *cntlr, uint16_t local); - int32_t (*enableIrq)(struct GpioCntlr *cntlr, uint16_t local); - int32_t (*disableIrq)(struct GpioCntlr *cntlr, uint16_t local); -} -``` +- GPIO输出 - **表1** GpioMethod结构体成员的回调函数功能说明 + 输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。 -| 函数成员 | 入参 | 出参 | 返回值 | 功能 | -| -------- | -------- | -------- | -------- | -------- | -| write | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号
val:uint16_t,电平传入值 | 无 | HDF_STATUS相关状态 | GPIO引脚写入电平值 | -| read | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识 | val:uint16_t指针,用于传出电平值。 | HDF_STATUS相关状态 | GPIO引脚读取电平值 | -| setDir | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号
dir:uint16_t,管脚方向传入值 | 无 | HDF_STATUS相关状态 | 设置GPIO引脚输入/输出方向 | -| getDir | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号 | dir:uint16_t指针,用于传出管脚方向值 | HDF_STATUS相关状态 | 读GPIO引脚输入/输出方向 | -| setIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号
mode:uint16_t,表示触发模式(边沿或电平)
func:函数指针,中断服务程序;
arg:void指针,中断服务程序入参 | 无 | HDF_STATUS相关状态 | 将GPIO引脚设置为中断模式 | -| unsetIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 取消GPIO中断设置 | -| enableIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 使能GPIO管脚中断 | -| disableIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 禁止GPIO管脚中断 | +### 运作机制 +在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。GPIO模块接口适配模式采用统一服务模式(如图1所示)。 -## 开发步骤 +在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。 -GPIO模块适配的三个必选环节是配置属性文件,实例化驱动入口,以及实例化核心层接口函数。 +GPIO模块各分层作用: -GPIO控制器分组管理所有管脚,相关参数会在属性文件中有所体现;驱动入口和接口函数的实例化环节是厂商驱动接入HDF的核心环节。 +- 接口层提供操作GPIO管脚的标准方法。 +- 核心层主要提供GPIO管脚资源匹配,GPIO管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互,供芯片厂家快速接入HDF框架。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 -1. 实例化驱动入口 - - 实例化HdfDriverEntry结构体成员。 - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 +**图 1** GPIO统一服务模式结构图 -2. 配置属性文件 - - 在device_info.hcs文件中添加deviceNode描述。 - - 【可选】添加gpio_config.hcs器件属性文件。 +![GPIO统一服务模式结构图](figures/统一服务模式结构图.png) -3. 实例化GPIO控制器对象 - - 初始化GpioCntlr成员。 - - 实例化GpioCntlr成员GpioMethod。 - > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
- > 实例化GpioCntlr成员GpioMethod,详见[接口说明](#接口说明)。 +## 开发指导 -4. 驱动调试 +### 场景介绍 - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如GPIO控制状态,中断响应情况等。 +GPIO仅是一个软件层面的概念,主要工作是GPIO管脚资源管理。驱动开发者可以使用GPIO模块提供的操作接口,实现对管脚的控制。当驱动开发者需要将GPIO适配到OpenHarmony时,需要进行GPIO驱动适配。下文将介绍如何进行GPIO驱动适配。 +### 接口说明 -## 开发实例 +为了保证上层在调用GPIO接口时能够正确的操作GPIO管脚,核心层在//drivers/hdf_core/framework/support/platform/include/gpio/gpio_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 -下方将以gpio_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 +GpioMethod定义: -1. 驱动开发首先需要实例化驱动入口。 +```c +struct GpioMethod { + int32_t (*request)(struct GpioCntlr *cntlr, uint16_t local); // 【预留】 + int32_t (*release)(struct GpioCntlr *cntlr, uint16_t local); // 【预留】 + int32_t (*write)(struct GpioCntlr *cntlr, uint16_t local, uint16_t val); + int32_t (*read)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *val); + int32_t (*setDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t dir); + int32_t (*getDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *dir); + int32_t (*toIrq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *irq); // 【预留】 + int32_t (*setIrq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode, GpioIrqFunc func, void *arg); + int32_t (*unsetIrq)(struct GpioCntlr *cntlr, uint16_t local); + int32_t (*enableIrq)(struct GpioCntlr *cntlr, uint16_t local); + int32_t (*disableIrq)(struct GpioCntlr *cntlr, uint16_t local); +} +``` - 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 +**表1** GpioMethod结构体成员的钩子函数功能说明 + +| 函数成员 | 入参 | 出参 | 返回值 | 功能 | +| -------- | -------- | -------- | -------- | -------- | +| write | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号
val:uint16_t类型,电平传入值 | 无 | HDF_STATUS相关状态 | GPIO引脚写入电平值 | +| read | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识 | val:uint16_t类型指针,用于传出电平值。 | HDF_STATUS相关状态 | GPIO引脚读取电平值 | +| setDir | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号
dir:uint16_t类型,管脚方向传入值 | 无 | HDF_STATUS相关状态 | 设置GPIO引脚输入/输出方向 | +| getDir | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号 | dir:uint16_t类型指针,用于传出管脚方向值 | HDF_STATUS相关状态 | 读GPIO引脚输入/输出方向 | +| setIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号
mode:uint16_t类型,表示触发模式(边沿或电平)
func:函数指针,中断服务程序;
arg:void指针,中断服务程序入参 | 无 | HDF_STATUS相关状态 | 将GPIO引脚设置为中断模式 | +| unsetIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 取消GPIO中断设置 | +| enableIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 使能GPIO管脚中断 | +| disableIrq | cntlr:结构体指针,核心层GPIO控制器
local:uint16_t类型,GPIO端口标识号 | 无 | HDF_STATUS相关状态 | 禁止GPIO管脚中断 | + +### 开发步骤 + +GPIO模块适配包含以下四个步骤: +- 实例化驱动入口。 +- 配置属性文件。 +- 实例化GPIO控制器对象。 +- 驱动调试。 + +### 开发实例 + +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/gpio/gpio_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 + +1. 实例化驱动入口。 + + 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - GPIO 驱动入口参考: - - ``` + GPIO驱动入口开发参考: + + ```c struct HdfDriverEntry g_gpioDriverEntry = { - .moduleVersion = 1, - .Bind = Pl061GpioBind, // GPIO不需要实现Bind,本例是一个空实现,厂商可根据自身需要添加相关操作。 - .Init = Pl061GpioInit, // 见Init参考 - .Release = Pl061GpioRelease, // 见Release参考 - .moduleName = "hisi_pl061_driver",//【必要且需要与HCS文件中里面的moduleName匹配】 + .moduleVersion = 1, + .Bind = Pl061GpioBind, // GPIO不需要实现Bind,本例是一个空实现,驱动适配者可根据自身需要添加相关操作 + .Init = Pl061GpioInit, // 见Init参考 + .Release = Pl061GpioRelease, // 见Release参考 + .moduleName = "hisi_pl061_driver", // 【必要且需要与HCS文件中里面的moduleName匹配】 }; - // 调用HDF_INIT将驱动入口注册到HDF框架中 - HDF_INIT(g_gpioDriverEntry); + HDF_INIT(g_gpioDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 ``` -2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在gpio_config.hcs中配置器件属性。 +2. 配置属性文件。 - deviceNode信息与驱动入口注册相关,器件属性值与核心层GpioCntlr成员的默认值或限制范围有密切关系。 + 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以一个GPIO控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加deviceNode信息。器件属性值与核心层GpioCntlr成员的默认值或限制范围有密切关系,需要在gpio_config.hcs中配置器件属性。 - 本例只有一个GPIO控制器,如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在gpio_config文件中增加对应的器件属性。 + - device_info.hcs 配置参考: - - device_info.hcs配置参考 - - ``` + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c root { - device_info { - platform :: host { - hostName = "platform_host"; - priority = 50; - device_gpio :: device { - device0 :: deviceNode { - policy = 0; // 等于0,不需要发布服务。 - priority = 10; // 驱动启动优先级。 - permission = 0644; // 驱动创建设备节点权限。 - moduleName = "hisi_pl061_driver"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。 - deviceMatchAttr = "hisilicon_hi35xx_pl061"; //【必要】用于配置控制器私有数据,要与gpio_config.hcs中 - // 对应控制器保持一致,其他控制器信息也在文件中。 + device_info { + platform :: host { + hostName = "platform_host"; + priority = 50; + device_gpio :: device { + device0 :: deviceNode { + policy = 0; // 等于0,不需要发布服务 + priority = 10; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "hisi_pl061_driver"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致 + deviceMatchAttr = "hisilicon_hi35xx_pl061"; // 【必要】用于配置控制器私有数据,要与gpio_config.hcs中 + // 对应控制器保持一致,其他控制器信息也在文件中 + } + } } } - } - } } ``` - - gpio_config.hcs配置参考 - - ``` + + - gpio_config.hcs配置参考: + + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/gpio/gpio_config.hcs文件配置器件属性,其中配置参数如下: + + ```c root { - platform { - gpio_config { - controller_0x120d0000 { - match_attr = "hisilicon_hi35xx_pl061"; //【必要】必须和device_info.hcs中的deviceMatchAttr值一致。 - groupNum = 12; //【必要】GPIO组索引,需要根据设备情况填写。 - bitNum = 8; //【必要】每组GPIO管脚数 。 - regBase = 0x120d0000; //【必要】物理基地址。 - regStep = 0x1000; //【必要】寄存器偏移步进。 - irqStart = 48; //【必要】开启中断。 - irqShare = 0; //【必要】共享中断。 - } + platform { + gpio_config { + controller_0x120d0000 { + match_attr = "hisilicon_hi35xx_pl061"; // 【必要】必须和device_info.hcs中的deviceMatchAttr值一致 + groupNum = 12; // 【必要】GPIO组索引,需要根据设备情况填写 + bitNum = 8; // 【必要】每组GPIO管脚数 + regBase = 0x120d0000; // 【必要】物理基地址 + regStep = 0x1000; // 【必要】寄存器偏移步进 + irqStart = 48; // 【必要】开启中断 + irqShare = 0; // 【必要】共享中断 + } + ... + } } } - } ``` -3. 完成驱动入口注册之后,下一步就是以核心层GpioCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化GpioCntlr成员GpioMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 + 需要注意的是,新增gpio_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 + + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/gpio/gpio_config.hcs" // 配置文件相对路径 + ``` + +3. 实例化GPIO控制器对象。 + + 完成驱动入口注册之后,下一步就是以核心层GpioCntlr对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化GpioCntlr成员GpioMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 - - 自定义结构体参考。 + - 驱动适配者自定义结构体参考。 从驱动的角度看,自定义结构体是参数和数据的载体,而且gpio_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层GpioCntlr对象,例如索引、管脚数等。 - - ``` - struct Pl061GpioCntlr { - struct GpioCntlr cntlr; //【必要】是核心层控制对象,其成员定义见下面。 - volatile unsigned char *regBase; //【必要】寄存器基地址。 - uint32_t phyBase; //【必要】物理基址。 - uint32_t regStep; //【必要】寄存器偏移步进。 - uint32_t irqStart; //【必要】中断开启。 - uint16_t groupNum; //【必要】用于描述厂商的GPIO端口号的参数。 - uint16_t bitNum; //【必要】用于描述厂商的GPIO端口号的参数。 - uint8_t irqShare; //【必要】共享中断。 - struct Pl061GpioGroup *groups; //【可选】根据厂商需要设置。 + ```c + //GPIO分组信息定义 + struct Pl061GpioGroup { + struct GpioCntlr cntlr; // 【必要】是核心层控制对象,其成员定义见下面。 + volatile unsigned char *regBase; // 【必要】寄存器基地址。 + unsigned int index; + unsigned int irq; + OsalIRQHandle irqFunc; + OsalSpinlock lock; + uint32_t irqSave; + bool irqShare; + struct PlatformDumper *dumper; + char *dumperName; }; - struct Pl061GpioGroup { // 包括寄存器地址,中断号,中断函数和锁。 - volatile unsigned char *regBase; - unsigned int index; - unsigned int irq; - OsalIRQHandle irqFunc; - OsalSpinlock lock; + + struct Pl061GpioData { + volatile unsigned char *regBase; // 【必要】寄存器基地址。 + uint32_t phyBase; // 【必要】物理基址。 + uint32_t regStep; // 【必要】寄存器偏移步进。 + uint32_t irqStart; // 【必要】中断开启。 + uint16_t groupNum; // 【必要】用于描述厂商的GPIO端口号的参数。 + uint16_t bitNum; // 【必要】用于描述厂商的GPIO端口号的参数。 + uint8_t irqShare; // 【必要】共享中断。 + struct Pl061GpioGroup *groups; // 【可选】根据厂商需要设置。 + struct GpioInfo *gpioInfo; + void *priv; + }; + + struct GpioInfo { + struct GpioCntlr *cntlr; + char name[GPIO_NAME_LEN]; + OsalSpinlock spin; + uint32_t irqSave; + struct GpioIrqRecord *irqRecord; }; - // GpioCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值。 struct GpioCntlr { - struct IDeviceIoService service; - struct HdfDeviceObject *device; - struct GpioMethod *ops; - struct DListHead list; - OsalSpinlock spin; - uint16_t start; - uint16_t count; - struct GpioInfo *ginfos; - void *priv; + struct PlatformDevice device; + struct GpioMethod *ops; + uint16_t start; + uint16_t count; + struct GpioInfo *ginfos; + bool isAutoAlloced; + void *priv; }; ``` - - GpioCntlr成员回调函数结构体GpioMethod的实例化,其他成员在Init函数中初始化。 - - ``` - //GpioMethod结构体成员都是回调函数,厂商需要根据表1完成相应的函数功能。 + - GpioCntlr成员钩子函数结构体GpioMethod的实例化,其他成员在Init函数中初始化。 + + ```c + //GpioMethod结构体成员都是钩子函数,驱动适配者需要根据表1完成相应的函数功能。 static struct GpioMethod g_method = { .request = NULL, .release = NULL, - .write = Pl061GpioWrite, // 写管脚。 - .read = Pl061GpioRead, // 读管脚。 - .setDir = Pl061GpioSetDir, // 设置管脚方向。 - .getDir = Pl061GpioGetDir, // 获取管脚方向。 - .toIrq = NULL, - .setIrq = Pl061GpioSetIrq, // 设置管脚中断,如不具备此能力可忽略。 - .unsetIrq = Pl061GpioUnsetIrq, // 取消管脚中断设置,如不具备此能力可忽略。 - .enableIrq = Pl061GpioEnableIrq, // 使能管脚中断,如不具备此能力可忽略。 - .disableIrq = Pl061GpioDisableIrq,// 禁止管脚中断,如不具备此能力可忽略。 + .write = Pl061GpioWrite, // 写管脚 + .read = Pl061GpioRead, // 读管脚 + .setDir = Pl061GpioSetDir, // 设置管脚方向 + .getDir = Pl061GpioGetDir, // 获取管脚方向 + .toIrq = NULL, + .setIrq = Pl061GpioSetIrq, // 设置管脚中断,如不具备此能力可忽略 + .unsetIrq = Pl061GpioUnsetIrq, // 取消管脚中断设置,如不具备此能力可忽略 + .enableIrq = Pl061GpioEnableIrq, // 使能管脚中断,如不具备此能力可忽略 + .disableIrq = Pl061GpioDisableIrq, // 禁止管脚中断,如不具备此能力可忽略 }; ``` - - Init函数参考 + - Init函数开发参考 入参: - HdfDeviceObject这个是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: - HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 + HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 - **表2** Init函数说明 - - | 状态(值) | 问题描述 | + **表2** Init函数说明 + + | 状态(值) | 问题描述 | | -------- | -------- | - | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | - | HDF_ERR_MALLOC_FAIL | 内存分配失败 | - | HDF_ERR_INVALID_PARAM | 参数非法 | - | HDF_ERR_IO | I/O 错误 | - | HDF_SUCCESS | 初始化成功 | - | HDF_FAILURE | 初始化失败 | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_INVALID_PARAM | 参数非法 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | 函数说明: 初始化自定义结构体对象,初始化GpioCntlr成员,调用核心层GpioCntlrAdd函数,接入VFS(可选)。 - - ``` + ```c + static struct Pl061GpioData g_pl061 = { + .groups = NULL, + .groupNum = PL061_GROUP_MAX, + .bitNum = PL061_BIT_MAX, + }; + + static int32_t Pl061GpioInitGroups(struct Pl061GpioData *pl061) + { + int32_t ret; + uint16_t i; + struct Pl061GpioGroup *groups = NULL; + + if (pl061 == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + groups = (struct Pl061GpioGroup *)OsalMemCalloc(sizeof(*groups) * pl061->groupNum); + if (groups == NULL) { + return HDF_ERR_MALLOC_FAIL; + } + pl061->groups = groups; + + for (i = 0; i < pl061->groupNum; i++) { + // 相关信息初始化 + groups[i].index = i; + groups[i].regBase = pl061->regBase + i * pl061->regStep; + groups[i].irq = pl061->irqStart + i; + groups[i].irqShare = pl061->irqShare; + groups[i].cntlr.start = i * pl061->bitNum; + groups[i].cntlr.count = pl061->bitNum; + groups[i].cntlr.ops = &g_method; + groups[i].cntlr.ginfos = &pl061->gpioInfo[i * pl061->bitNum]; + + if ((ret = OsalSpinInit(&groups[i].lock)) != HDF_SUCCESS) { + goto ERR_EXIT; + } + + ret = GpioCntlrAdd(&groups[i].cntlr); // 向HDF core中添加相关信息 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: err add controller(%hu:%hu):%d", __func__, + groups[i].cntlr.start, groups[i].cntlr.count, ret); + (void)OsalSpinDestroy(&groups[i].lock); + goto ERR_EXIT; + } + } + return HDF_SUCCESS; + + ERR_EXIT: + while (i-- > 0) { + GpioCntlrRemove(&groups[i].cntlr); + (void)OsalSpinDestroy(&groups[i].lock); + } + pl061->groups = NULL; + OsalMemFree(groups); + return ret; + } + static int32_t Pl061GpioInit(struct HdfDeviceObject *device) { - ... - struct Pl061GpioCntlr *pl061 = &g_pl061;// 利用静态全局变量完成初始化 - // static struct Pl061GpioCntlr g_pl061 = { - // .groups = NULL, - // .groupNum = PL061_GROUP_MAX, - // .bitNum = PL061_BIT_MAX, - //}; - ret = Pl061GpioReadDrs(pl061, device->property);// 利用从gpio_config.HCS文件读取的属性值来初始化自定义结构体对象成员 - ... - pl061->regBase = OsalIoRemap(pl061->phyBase, pl061->groupNum * pl061->regStep);//地址映射 - ... - ret = Pl061GpioInitCntlrMem(pl061); // 内存分配 - ... - pl061->cntlr.count = pl061->groupNum * pl061->bitNum;//【必要】管脚数量计算 - pl061->cntlr.priv = (void *)device->property; //【必要】存储设备属性 - pl061->cntlr.ops = &g_method; //【必要】GpioMethod的实例化对象的挂载 - pl061->cntlr.device = device; //【必要】使HdfDeviceObject与GpioCntlr可以相互转化的前提 - ret = GpioCntlrAdd(&pl061->cntlr); //【必要】调用此函数填充核心层结构体,返回成功信号后驱动才完全接入平台核心层。 - ... - Pl061GpioDebugCntlr(pl061); - #ifdef PL061_GPIO_USER_SUPPORT //【可选】若支持用户级的虚拟文件系统,则接入。 - if (GpioAddVfs(pl061->bitNum) != HDF_SUCCESS) { - HDF_LOGE("%s: add vfs fail!", __func__); - } - #endif - ... + int32_t ret; + struct Pl061GpioData *pl061 = &g_pl061; + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property null!", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + pl061->gpioInfo = OsalMemCalloc(sizeof(struct GpioInfo) * GPIO_MAX_INFO_NUM); + if (pl061->gpioInfo == NULL) { + HDF_LOGE("%s: failed to calloc gpioInfo!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = Pl061GpioReadDrs(pl061, device->property); // 利用从gpio_config.HCS文件读取的属性值来初始化自定义结构体对象成员 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: failed to read drs:%d", __func__, ret); + return ret; + } + + if (pl061->groupNum > PL061_GROUP_MAX || pl061->groupNum <= 0 || + pl061->bitNum > PL061_BIT_MAX || pl061->bitNum <= 0) { + HDF_LOGE("%s: err groupNum:%hu, bitNum:%hu", __func__, pl061->groupNum, pl061->bitNum); + return HDF_ERR_INVALID_PARAM; + } + + pl061->regBase = OsalIoRemap(pl061->phyBase, pl061->groupNum * pl061->regStep); //地址映射 + if (pl061->regBase == NULL) { + HDF_LOGE("%s: err remap phy:0x%x", __func__, pl061->phyBase); + return HDF_ERR_IO; + } + + ret = Pl061GpioInitGroups(pl061); //group信息初始化,并添加到HDF核心层 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: err init groups:%d", __func__, ret); + OsalIoUnmap((void *)pl061->regBase); + pl061->regBase = NULL; + return ret; + } + pl061->priv = (void *)device->property; + device->priv = (void *)pl061; + Pl061GpioDebug(pl061); + + #ifdef PL061_GPIO_USER_SUPPORT + if (GpioAddVfs(pl061->bitNum) != HDF_SUCCESS) { + HDF_LOGE("%s: add vfs fail!", __func__); + } + #endif + HDF_LOGI("%s: dev service:%s init success!", __func__, HdfDeviceGetServiceName(device)); + return HDF_SUCCESS; } ``` - - Release函数参考 + + - Release函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -276,23 +393,50 @@ GPIO控制器分组管理所有管脚,相关参数会在属性文件中有所 > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。 - - ``` + ```c + static void Pl061GpioUninitGroups(struct Pl061GpioData *pl061) + { + uint16_t i; + struct Pl061GpioGroup *group = NULL; + + for (i = 0; i < pl061->groupNum; i++) { + group = &pl061->groups[i]; + GpioDumperDestroy(&pl061->groups[i]); + GpioCntlrRemove(&group->cntlr); // 从HDF核心层删除 + } + + OsalMemFree(pl061->groups); + pl061->groups = NULL; + } + static void Pl061GpioRelease(struct HdfDeviceObject *device) { - struct GpioCntlr *cntlr = NULL; - struct Pl061GpioCntlr *pl061 = NULL; - ... - cntlr = GpioCntlrFromDevice(device);//【必要】通过强制转换获取核心层控制对象 - // return (device == NULL) ? NULL : (struct GpioCntlr *)device->service; - ... - #ifdef PL061_GPIO_USER_SUPPORT - GpioRemoveVfs();//与Init中GpioAddVfs相反 - #endif - GpioCntlrRemove(cntlr); //【必要】取消设备信息、服务等内容在核心层上的挂载 - pl061 = ToPl061GpioCntlr(cntlr); // return (struct Pl061GpioCntlr *)cntlr; - Pl061GpioRleaseCntlrMem(pl061); //【必要】锁和内存的释放 - OsalIoUnmap((void *)pl061->regBase);//【必要】解除地址映射 - pl061->regBase = NULL; + struct Pl061GpioData *pl061 = NULL; + + HDF_LOGI("%s: enter", __func__); + if (device == NULL) { + HDF_LOGE("%s: device is null!", __func__); + return; + } + + #ifdef PL061_GPIO_USER_SUPPORT + GpioRemoveVfs(); + #endif + + pl061 = (struct Pl061GpioData *)device->priv; + if (pl061 == NULL) { + HDF_LOGE("%s: device priv is null", __func__); + return; + } + + Pl061GpioUninitGroups(pl061); + OsalMemFree(pl061->gpioInfo); + pl061->gpioInfo = NULL; + OsalIoUnmap((void *)pl061->regBase); + pl061->regBase = NULL; } ``` + +4. 驱动调试。 + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如GPIO控制状态,中断响应情况等。 \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-mmc-develop.md b/zh-cn/device-dev/driver/driver-platform-mmc-develop.md index 73e1f9bba87c5ad88940132eeb284e5c2fc0fe5a..956b94fdedb0126b0d2261a004a714f1d6c0f9aa 100755 --- a/zh-cn/device-dev/driver/driver-platform-mmc-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-mmc-develop.md @@ -1,221 +1,248 @@ # MMC - ## 概述 -MMC(MultiMedia Card)即多媒体卡。在HDF框架中,MMC的接口适配模式采用独立服务模式。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +### 功能简介 + +MMC(MultiMedia Card)即多媒体卡,是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 + +MMC后续泛指一个接口协定(一种卡式),能符合这种接口的内存器都可称作MMC储存体。主要包括几个部分:MMC控制器、MMC总线、存储卡(包括MMC卡、SD卡、SDIO卡、TF卡)。 + +MMC、SD、SDIO总线,其总线规范类似,都是从MMC总线规范演化而来的。MMC强调的是多媒体存储;SD强调的是安全和数据保护;SDIO是从SD演化出来的,强调的是接口,不再关注另一端的具体形态(可以是WIFI设备、Bluetooth设备、GPS等等)。 + +### 基本概念 + +- SD卡(Secure Digital Memory Card) + + SD卡即安全数码卡。它是在MMC的基础上发展而来,SD卡强调数据的安全安全,可以设定存储内容的使用权限,防止数据被他人复制。在数据传输和物理规范上,SD卡(24mm\*32mm\*2.1mm,比MMC卡更厚一点),向前兼容了MMC卡。所有支持SD卡的设备也支持MMC卡。 + +- SDIO(Secure Digital Input and Output) + + 即安全数字输入输出接口。SDIO是在SD规范的标准上定义的一种外设接口,它相较于SD规范增加了低速标准,可以用最小的硬件开销支持低速I/O。SDIO接口兼容以前的SD内存卡,也可以连接SDIO接口的设备。 + +### 运作机制 + +在HDF框架中,MMC的接口适配模式采用独立服务模式(如图1所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 + +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: + +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 - **图1** MMC独立服务模式结构图 +MMC模块各分层作用: - ![zh-cn_image_0000001176603968](figures/独立服务模式结构图.png "MMC独立服务模式结构图") +- 接口层提供打开MMC设备、检查MMC控制器是否存在设备、关闭MMC设备的接口。 +- 核心层主要提供MMC控制器、移除和管理的能力,还有公共控制器业务。通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 +**图1** MMC独立服务模式结构图 -## 接口说明 +![img1](figures/独立服务模式结构图.png "MMC独立服务模式结构图") + +## 开发指导 + +### 场景介绍 + +MMC用于多媒体文件的存储,当驱动开发者需要将MMC设备适配到OpenHarmony时,需要进行MMC驱动适配。下文将介绍如何进行MMC驱动适配。 + +### 接口说明 + +为了保证上层在调用MMC接口时能够正确的操作MMC控制器,核心层在//drivers/hdf_core/framework/model/storage/include/mmc/mmc_corex.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 MmcCntlrOps定义: - -``` +```c struct MmcCntlrOps { - int32_t (*request)(struct MmcCntlr *cntlr, struct MmcCmd *cmd); - int32_t (*setClock)(struct MmcCntlr *cntlr, uint32_t clock); - int32_t (*setPowerMode)(struct MmcCntlr *cntlr, enum MmcPowerMode mode); - int32_t (*setBusWidth)(struct MmcCntlr *cntlr, enum MmcBusWidth width); - int32_t (*setBusTiming)(struct MmcCntlr *cntlr, enum MmcBusTiming timing); - int32_t (*setSdioIrq)(struct MmcCntlr *cntlr, bool enable); - int32_t (*hardwareReset)(struct MmcCntlr *cntlr); - int32_t (*systemInit)(struct MmcCntlr *cntlr); - int32_t (*setEnhanceStrobe)(struct MmcCntlr *cntlr, bool enable); - int32_t (*switchVoltage)(struct MmcCntlr *cntlr, enum MmcVolt volt); - bool (*devReadOnly)(struct MmcCntlr *cntlr); - bool (*devPlugged)(struct MmcCntlr *cntlr); - bool (*devBusy)(struct MmcCntlr *cntlr); - int32_t (*tune)(struct MmcCntlr *cntlr, uint32_t cmdCode); - int32_t (*rescanSdioDev)(struct MmcCntlr *cntlr); + int32_t (*request)(struct MmcCntlr *cntlr, struct MmcCmd *cmd); + int32_t (*setClock)(struct MmcCntlr *cntlr, uint32_t clock); + int32_t (*setPowerMode)(struct MmcCntlr *cntlr, enum MmcPowerMode mode); + int32_t (*setBusWidth)(struct MmcCntlr *cntlr, enum MmcBusWidth width); + int32_t (*setBusTiming)(struct MmcCntlr *cntlr, enum MmcBusTiming timing); + int32_t (*setSdioIrq)(struct MmcCntlr *cntlr, bool enable); + int32_t (*hardwareReset)(struct MmcCntlr *cntlr); + int32_t (*systemInit)(struct MmcCntlr *cntlr); + int32_t (*setEnhanceStrobe)(struct MmcCntlr *cntlr, bool enable); + int32_t (*switchVoltage)(struct MmcCntlr *cntlr, enum MmcVolt volt); + bool (*devReadOnly)(struct MmcCntlr *cntlr); + bool (*devPlugged)(struct MmcCntlr *cntlr); + bool (*devBusy)(struct MmcCntlr *cntlr); + int32_t (*tune)(struct MmcCntlr *cntlr, uint32_t cmdCode); + int32_t (*rescanSdioDev)(struct MmcCntlr *cntlr); }; ``` - **表1** MmcCntlrOps结构体成员的回调函数功能说明 +**表1** MmcCntlrOps结构体成员的钩子函数功能说明 -| 成员函数 | 入参 | 返回值 | 功能 | +| 成员函数 | 入参 | 返回值 | 功能 | | -------- | -------- | -------- | -------- | -| doRequest | cntlr:核心层结构体指针,MMC控制器
cmd:结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 | -| setClock | cntlr:核心层结构体指针,MMC控制器
clock:时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 | -| setPowerMode | cntlr:核心层结构体指针,MMC控制器
mode:枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 | -| setBusWidth | cntlr:核心层结构体指针,MMC控制器
width:枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 | -| setBusTiming | cntlr:核心层结构体指针,MMC控制器
timing:枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 | -| setSdioIrq | cntlr:核心层结构体指针,MMC控制器
enable:布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 | -| hardwareReset | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 复位硬件 | -| systemInit | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 系统初始化 | -| setEnhanceStrobe | cntlr:核心层结构体指针,MMC控制器
enable:布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 | -| switchVoltage | cntlr:核心层结构体指针,MMC控制器
volt:枚举值,电压值(3.3,1.8,1.2V) | HDF_STATUS相关状态 | 设置电压值 | -| devReadOnly | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否只读 | -| cardPlugged | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否拔出 | -| devBusy | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否忙碌 | -| tune | cntlr:核心层结构体指针,MMC控制器
cmdCode:uint32_t,命令代码 | HDF_STATUS相关状态 | 调谐 | -| rescanSdioDev | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 扫描并添加SDIO设备 | - - -## 开发步骤 - -MMC模块适配的三个必选环节是实例化驱动入口,配置属性文件,以及实例化核心层接口函数。 - -1. 实例化驱动入口 - - 实例化HdfDriverEntry结构体成员。 - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 - -2. 配置属性文件 - - 在device_info.hcs文件中添加deviceNode描述。 - - 【可选】添加mmc_config.hcs器件属性文件。 - -3. 实例化MMC控制器对象 - - 初始化MmcCntlr成员。 - - 实例化MmcCntlr成员MmcCntlrOps。 - > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
- > 实例化MmcCntlr成员MmcCntlrOps,其定义和成员说明见[接口说明](#接口说明)。 +| doRequest | cntlr:结构体指针,核心层MMC控制器
cmd:结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 | +| setClock | cntlr:结构体指针,核心层MMC控制器
clock:时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 | +| setPowerMode | cntlr:结构体指针,核心层MMC控制器
mode:枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 | +| setBusWidth | cntlr:核心层结构体指针,核心层MMMC控制器
width:枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 | +| setBusTiming | cntlr:结构体指针,核心层MMC控制器
timing:枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 | +| setSdioIrq | cntlr:结构体指针,核心层MMC控制器
enable:布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 | +| hardwareReset | cntlr:结构体指针,核心层MMC控制器 | HDF_STATUS相关状态 | 复位硬件 | +| systemInit | cntlr:结构体指针,核心层MMC控制器 | HDF_STATUS相关状态 | 系统初始化 | +| setEnhanceStrobe | cntlr:结构体指针,核心层MMC控制器
enable:布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 | +| switchVoltage | cntlr:结构体指针,核心层MMC控制器
volt:枚举值,电压值(3.3,1.8,1.2V) | HDF_STATUS相关状态 | 设置电压值 | +| devReadOnly | cntlr:结构体指针,核心层MMC控制器 | 布尔值 | 检验设备是否只读 | +| cardPlugged | cntlr:结构体指针,核心层MMC控制器 | 布尔值 | 检验设备是否拔出 | +| devBusy | cntlr:结构体指针,核心层MMC控制器 | 布尔值 | 检验设备是否忙碌 | +| tune | cntlr:结构体指针,核心层MMC控制器
cmdCode:uint32_t类型,命令代码 | HDF_STATUS相关状态 | 调谐 | +| rescanSdioDev | cntlr:结构体指针,核心层MMC控制器 | HDF_STATUS相关状态 | 扫描并添加SDIO设备 | -4. 驱动调试 +### 开发步骤 - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,设备启动是否成功等。 +MMC模块适配包含以下四个步骤: +- 实例化驱动入口。 +- 配置属性文件。 +- 实例化MMC控制器对象。 +- 驱动调试。 -## 开发实例 +### 开发实例 -下方将以himci.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/mmc/himci_v200/himci.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 -1. 驱动开发首先需要实例化驱动入口。 +1. 实例化驱动入口。 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 - 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - MMC驱动入口参考: - - ``` + MMC驱动入口开发参考: + + ```c struct HdfDriverEntry g_mmcDriverEntry = { .moduleVersion = 1, - .Bind = HimciMmcBind, // 见Bind参考 - .Init = HimciMmcInit, // 见Init参考 - .Release = HimciMmcRelease, // 见Release参考 - .moduleName = "hi3516_mmc_driver",// 【必要且与HCS文件中里面的moduleName匹配】 + .Bind = HimciMmcBind, // 见Bind参考 + .Init = HimciMmcInit, // 见Init参考 + .Release = HimciMmcRelease, // 见Release参考 + .moduleName = "hi3516_mmc_driver", // 【必要且与HCS文件中里面的moduleName匹配】 }; - HDF_INIT(g_mmcDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 + HDF_INIT(g_mmcDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 ``` -2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在mmc_config.hcs中配置器件属性。 - - deviceNode信息与驱动入口注册相关,器件属性值与核心层MmcCntlr成员的默认值或限制范围有密切关系。 - - 如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在mmc_config文件中增加对应的器件属性。 - - - device_info.hcs 配置参考 - - - ``` - root { - device_info { - match_attr = "hdf_manager"; - platform :: host { - hostName = "platform_host"; - priority = 50; - device_mmc:: device { - device0 :: deviceNode { - policy = 2; - priority = 10; - permission = 0644; - moduleName = "hi3516_mmc_driver"; // 【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致。 - serviceName = "HDF_PLATFORM_MMC_0"; // 【必要】驱动对外发布服务的名称,必须唯一。 - deviceMatchAttr = "hi3516_mmc_emmc";// 【必要】用于配置控制器私有数据,要与mmc_config.hcs中对应控制器保持一致。 - } - device1 :: deviceNode { - policy = 1; - priority = 20; - permission = 0644; - moduleName = "hi3516_mmc_driver"; - serviceName = "HDF_PLATFORM_MMC_1"; - deviceMatchAttr = "hi3516_mmc_sd"; // SD类型 - } - device2 :: deviceNode { - policy = 1; - priority = 30; - permission = 0644; - moduleName = "hi3516_mmc_driver"; - serviceName = "HDF_PLATFORM_MMC_2"; - deviceMatchAttr = "hi3516_mmc_sdio";// SDIO类型 - } - } - } - } - } - ``` - - - mmc_config.hcs配置参考 - - - ``` - root { - platform { - mmc_config { - template mmc_controller { // 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。 - match_attr = ""; - voltDef = 0; // 3.3V - freqMin = 50000; // 【必要】最小频率值 - freqMax = 100000000; // 【必要】最大频率值 - freqDef = 400000; // 【必要】默认频率值 - maxBlkNum = 2048; // 【必要】最大的block号 - maxBlkSize = 512; // 【必要】最大的block个数 - ocrDef = 0x300000; // 【必要】工作电压设置相关 - caps2 = 0; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps2定义。 - regSize = 0x118; // 【必要】寄存器位宽 - hostId = 0; // 【必要】主机号 - regBasePhy = 0x10020000;// 【必要】寄存器物理基地址 - irqNum = 63; // 【必要】中断号 - devType = 2; // 【必要】模式选择:emmc、SD、SDIO、COMBO - caps = 0x0001e045; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps 定义。 - } - controller_0x10100000 :: mmc_controller { - match_attr = "hi3516_mmc_emmc";// 【必要】需要和device_info.hcs中的deviceMatchAttr值一致 - hostId = 0; - regBasePhy = 0x10100000; - irqNum = 96; - devType = 0; // emmc类型 - caps = 0xd001e045; - caps2 = 0x60; - } - controller_0x100f0000 :: mmc_controller { - match_attr = "hi3516_mmc_sd"; - hostId = 1; - regBasePhy = 0x100f0000; - irqNum = 62; - devType = 1; // SD类型 - caps = 0xd001e005; - } - controller_0x10020000 :: mmc_controller { - match_attr = "hi3516_mmc_sdio"; - hostId = 2; - regBasePhy = 0x10020000; - irqNum = 63; - devType = 2; // SDIO类型 - caps = 0x0001e04d; - } - } - } - } - ``` - -3. 完成驱动入口注册之后,下一步就是以核心层MmcCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MmcCntlr成员MmcCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 - - - 自定义结构体参考 +2. 配置属性文件。 + + 完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以三个MMC控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息。器件属性值与核心层MmcCntlr成员的默认值或限制范围有密切关系,需要在mmc_config.hcs中配置器件属性。 + + - device_info.hcs 配置参考: + + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c + root { + device_info { + match_attr = "hdf_manager"; + platform :: host { + hostName = "platform_host"; + priority = 50; + device_mmc:: device { + device0 :: deviceNode { // 驱动的DeviceNode节点 + policy = 2; // policy字段是驱动服务发布的策略,如果需要面向用户态,则为2 + priority = 10; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "hi3516_mmc_driver"; // 【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致。 + serviceName = "HDF_PLATFORM_MMC_0"; // 【必要】驱动对外发布服务的名称,必须唯一。 + deviceMatchAttr = "hi3516_mmc_emmc"; // 【必要】用于配置控制器私有数据,要与mmc_config.hcs中对应控制器保持一致。 + } + device1 :: deviceNode { + policy = 1; + priority = 20; + permission = 0644; + moduleName = "hi3516_mmc_driver"; + serviceName = "HDF_PLATFORM_MMC_1"; + deviceMatchAttr = "hi3516_mmc_sd"; // SD类型 + } + device2 :: deviceNode { + policy = 1; + priority = 30; + permission = 0644; + moduleName = "hi3516_mmc_driver"; + serviceName = "HDF_PLATFORM_MMC_2"; + deviceMatchAttr = "hi3516_mmc_sdio"; // SDIO类型 + } + ... + } + } + } + } + ``` + + - mmc_config.hcs配置参考: + + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/mmc/mmc_config.hcs文件配置器件属性,其中配置参数如下: + + ```c + root { + platform { + mmc_config { + template mmc_controller { // 配置模板,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值。 + match_attr = ""; + voltDef = 0; // MMC默认电压,0代表3.3V,1代表1.8V,2代表1.2V + freqMin = 50000; // 【必要】最小频率值 + freqMax = 100000000; // 【必要】最大频率值 + freqDef = 400000; // 【必要】默认频率值 + maxBlkNum = 2048; // 【必要】最大的block号 + maxBlkSize = 512; // 【必要】最大的block个数 + ocrDef = 0x300000; // 【必要】工作电压设置相关 + caps2 = 0; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps2定义。 + regSize = 0x118; // 【必要】寄存器位宽 + hostId = 0; // 【必要】主机号 + regBasePhy = 0x10020000; // 【必要】寄存器物理基地址 + irqNum = 63; // 【必要】中断号 + devType = 2; // 【必要】模式选择:EMMC、SD、SDIO、COMBO + caps = 0x0001e045; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps定义。 + } + controller_0x10100000 :: mmc_controller { + match_attr = "hi3516_mmc_emmc"; // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致 + hostId = 0; + regBasePhy = 0x10100000; + irqNum = 96; + devType = 0; // eMMC类型 + caps = 0xd001e045; + caps2 = 0x60; + } + controller_0x100f0000 :: mmc_controller { + match_attr = "hi3516_mmc_sd"; + hostId = 1; + regBasePhy = 0x100f0000; + irqNum = 62; + devType = 1; // SD类型 + caps = 0xd001e005; + } + controller_0x10020000 :: mmc_controller { + match_attr = "hi3516_mmc_sdio"; + hostId = 2; + regBasePhy = 0x10020000; + irqNum = 63; + devType = 2; // SDIO类型 + caps = 0x0001e04d; + } + } + } + } + ``` - 从驱动的角度看,自定义结构体是参数和数据的载体,而且mmc_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象。 + 需要注意的是,新增mmc_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 - + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/mmc/mmc_config.hcs" // 配置文件相对路径 ``` + +3. 实例化MMC控制器对象。 + + 完成配置属性文件之后,下一步就是以核心层MmcCntlr对象的初始化为核心,包括驱动适配自定义结构体(传递参数和数据),实例化MmcCntlr成员MmcCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 + + - 驱动适配者自定义结构体参考 + + 从驱动的角度看,自定义结构体是参数和数据的载体,而且mmc_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象。 + + ```c struct HimciHost { - struct MmcCntlr *mmc;// 【必要】核心层结构体 - struct MmcCmd *cmd; // 【必要】核心层结构体,传递命令的,相关命令见枚举量MmcCmdCode。 - // 【可选】根据厂商驱动需要添加 - void *base; + struct MmcCntlr *mmc; // 【必要】核心层控制对象 + struct MmcCmd *cmd; // 【必要】核心层结构体,传递命令,相关命令见枚举量MmcCmdCode + void *base; // 地址映射需要,寄存器基地址 enum HimciPowerStatus powerStatus; uint8_t *alignedBuff; uint32_t buffLen; @@ -260,53 +287,54 @@ MMC模块适配的三个必选环节是实例化驱动入口,配置属性文 }; ``` - - MmcCntlr成员回调函数结构体MmcCntlrOps的实例化,其他成员在Bind函数中初始化。 + - MmcCntlr成员钩子函数结构体MmcCntlrOps的实例化,其他成员在Bind函数中初始化。 - - ``` + ```c static struct MmcCntlrOps g_himciHostOps = { - .request = HimciDoRequest, - .setClock = HimciSetClock, - .setPowerMode = HimciSetPowerMode, - .setBusWidth = HimciSetBusWidth, - .setBusTiming = HimciSetBusTiming, - .setSdioIrq = HimciSetSdioIrq, - .hardwareReset = HimciHardwareReset, - .systemInit = HimciSystemInit, - .setEnhanceStrobe= HimciSetEnhanceStrobe, - .switchVoltage = HimciSwitchVoltage, - .devReadOnly = HimciDevReadOnly, - .devPlugged = HimciCardPlugged, - .devBusy = HimciDevBusy, - .tune = HimciTune, - .rescanSdioDev = HimciRescanSdioDev, + .request = HimciDoRequest, + .setClock = HimciSetClock, + .setPowerMode = HimciSetPowerMode, + .setBusWidth = HimciSetBusWidth, + .setBusTiming = HimciSetBusTiming, + .setSdioIrq = HimciSetSdioIrq, + .hardwareReset = HimciHardwareReset, + .systemInit = HimciSystemInit, + .setEnhanceStrobe = HimciSetEnhanceStrobe, + .switchVoltage = HimciSwitchVoltage, + .devReadOnly = HimciDevReadOnly, + .devPlugged = HimciCardPlugged, + .devBusy = HimciDevBusy, + .tune = HimciTune, + .rescanSdioDev = HimciRescanSdioDev, }; ``` - - Bind函数参考 + + - Bind函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: - HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 + HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 - | 状态(值) | 问题描述 | + **表2** Bind函数说明 + + | 状态(值) | 问题描述 | | -------- | -------- | - | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | - | HDF_ERR_MALLOC_FAIL | 内存分配失败 | - | HDF_ERR_INVALID_PARAM | 参数非法 | - | HDF_ERR_IO | I/O 错误 | - | HDF_SUCCESS | 初始化成功 | - | HDF_FAILURE | 初始化失败 | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_INVALID_PARAM | 参数非法 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | 函数说明: - MmcCntlr、HimciHost、HdfDeviceObject之间互相赋值,方便其他函数可以相互转化,初始化自定义结构体HimciHost对象,初始化MmcCntlr成员,调用核心层MmcCntlrAdd函数。 + MmcCntlr、HimciHost、HdfDeviceObject之间互相赋值,方便其他函数可以相互转化,初始化自定义结构体HimciHost对象,初始化MmcCntlr成员,调用核心层MmcCntlrAdd函数,完成MMC控制器的添加。 - - ``` + ```c static int32_t HimciMmcBind(struct HdfDeviceObject *obj) { struct MmcCntlr *cntlr = NULL; @@ -315,34 +343,34 @@ MMC模块适配的三个必选环节是实例化驱动入口,配置属性文 cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr)); host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost)); - host->mmc = cntlr; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提 - cntlr->priv = (void *)host; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提 - cntlr->ops = &g_himciHostOps; // 【必要】MmcCntlrOps的实例化对象的挂载 - cntlr->hdfDevObj = obj; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 - obj->service = &cntlr->service; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 - ret = MmcCntlrParse(cntlr, obj); // 【必要】 初始化cntlr,失败就goto _ERR。 - ... - ret = HimciHostParse(host, obj); // 【必要】 初始化host对象的相关属性,失败就goto _ERR。 + host->mmc = cntlr; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提 + cntlr->priv = (void *)host; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提 + cntlr->ops = &g_himciHostOps; // 【必要】MmcCntlrOps的实例化对象的挂载 + cntlr->hdfDevObj = obj; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 + obj->service = &cntlr->service; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 + ret = MmcCntlrParse(cntlr, obj); // 【必要】 初始化cntlr,失败就goto _ERR。 + ... + ret = HimciHostParse(host, obj); // 【必要】 初始化host对象的相关属性,失败就goto _ERR。 ... - ret = HimciHostInit(host, cntlr); // 厂商自定义的初始化,失败就goto _ERR。 + ret = HimciHostInit(host, cntlr); // 驱动适配者自定义的初始化,失败就goto _ERR。 ... - ret = MmcCntlrAdd(cntlr); // 调用核心层函数,失败就goto _ERR。 + ret = MmcCntlrAdd(cntlr); // 调用核心层函数,失败就goto _ERR。 ... - (void)MmcCntlrAddDetectMsgToQueue(cntlr);// 将卡检测消息添加到队列中。 + (void)MmcCntlrAddDetectMsgToQueue(cntlr); // 将卡检测消息添加到队列中。 HDF_LOGD("HimciMmcBind: success."); return HDF_SUCCESS; - _ERR: + ERR: HimciDeleteHost(host); HDF_LOGD("HimciMmcBind: fail, err = %d.", ret); return ret; } ``` - - Init函数参考 + - Init函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -352,8 +380,7 @@ MMC模块适配的三个必选环节是实例化驱动入口,配置属性文 实现ProcMciInit。 - - ``` + ```c static int32_t HimciMmcInit(struct HdfDeviceObject *obj) { static bool procInit = false; @@ -368,11 +395,12 @@ MMC模块适配的三个必选环节是实例化驱动入口,配置属性文 return HDF_SUCCESS; } ``` - - Release函数参考 + + - Release函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -380,20 +408,22 @@ MMC模块适配的三个必选环节是实例化驱动入口,配置属性文 函数说明: - 释放内存和删除控制器等操作,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用 Release释放驱动资源。 + 释放内存和删除控制器等操作,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。 > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。 - - - ``` + ```c static void HimciMmcRelease(struct HdfDeviceObject *obj) { struct MmcCntlr *cntlr = NULL; ... - cntlr = (struct MmcCntlr *)obj->service; // 这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数。 + cntlr = (struct MmcCntlr *)obj->service; // 这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数。 ... - HimciDeleteHost((struct HimciHost *)cntlr->priv);// 厂商自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化。 + HimciDeleteHost((struct HimciHost *)cntlr->priv); // 驱动适配者自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化。 } ``` + +4. 驱动调试。 + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。 \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-pin-des.md b/zh-cn/device-dev/driver/driver-platform-pin-des.md index b81839ada182907fe0dd3be34bd6036b5a29a693..aaa3ee8e27dddec654de040ada8e910ad73b394a 100644 --- a/zh-cn/device-dev/driver/driver-platform-pin-des.md +++ b/zh-cn/device-dev/driver/driver-platform-pin-des.md @@ -1,18 +1,21 @@ -# PIN +# PIN ## 概述 ### 功能简介 -PIN即管脚控制器,用于统一管理各SoC厂商管脚资源,对外提供管脚复用功能:包括管脚推拉方式、管脚推拉强度以及管脚功能。 +PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能:包括管脚推拉方式、管脚推拉强度以及管脚功能。 + PIN接口定义了操作PIN管脚的通用方法集合,包括: -- 获取/释放管脚描述句柄: 传入管脚名与链表中每个控制器下管脚名进行匹配,匹配则会获取一个管脚描述句柄,操作完PIN管脚后释放该管脚描述句柄。 -- 设置/获取管脚推拉方式:推拉方式可以是上拉、下拉以及悬空。 -- 设置/获取管脚推拉强度:用户可根据实际设置管脚推拉强度大小。 -- 设置/获取管脚功能:通过管脚功能名设置/获取管脚功能,实现管脚复用。 + +- 获取/释放管脚描述句柄:传入管脚名与链表中每个控制器下管脚名进行匹配,匹配则会获取一个管脚描述句柄,操作完PIN管脚后释放该管脚描述句柄。 +- 设置/获取管脚推拉方式:推拉方式可以是上拉、下拉以及悬空。 +- 设置/获取管脚推拉强度:用户可根据实际设置管脚推拉强度大小。 +- 设置/获取管脚功能:通过管脚功能名设置/获取管脚功能,实现管脚复用。 ### 基本概念 -PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。 + +PIN是一个软件层面的概念,目的是为了统一各SoC的PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。 - SoC(System on Chip) @@ -24,50 +27,53 @@ PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚 ### 运作机制 -在HDF框架中,PIN模块暂不支持用户态,所以不需要发布服务。接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型。对于没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。 +在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。PIN模块接口适配模式采用统一服务模式。 + +在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。 PIN模块各分层作用: + - 接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。 - 核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 - 适配层主要是将钩子函数的功能实例化,实现具体的功能。 -**图 1** PIN无服务模式 -![](figures/无服务模式结构图.png "PIN无服务模式") +**图 1** PIN统一服务模式 +![PIN统一服务模式](figures/统一服务模式结构图.png "统一服务模式") ### 约束与限制 - PIN模块目前仅支持轻量和小型系统内核(LiteOS)。 +PIN模块目前只支持小型系统LiteOS-A内核。 - ## 使用指导 +## 使用指导 - ### 场景介绍 +### 场景介绍 - PIN模块仅是一个软件层面的概念,主要工作是管脚资源管理。使用复用管脚时,通过设置管脚功能、设置管脚推拉方式、设置管脚推拉强度来适配指定场景的需求。 +PIN模块仅是一个软件层面的概念,主要工作是管脚资源管理。使用复用管脚时,通过设置管脚功能、设置管脚推拉方式、设置管脚推拉强度来适配指定场景的需求。 ### 接口说明 -PIN模块提供的主要接口如[表1](#table1)所示,更多关于接口的介绍请参考对应的API接口文档。 +PIN模块提供的主要接口如表1所示,更多关于接口的介绍请参考对应的API接口文档。 **表 1** PIN驱动API接口功能介绍 | **接口名** | **描述** | | ------------------------------------------------------------ | ---------------- | -| DevHandle PinGet(const char *pinName); | 获取管脚描述句柄 | -| void PinPut(DevHandle handle); | 释放管脚描述句柄 | -| int32_t PinSetPull(DevHandle handle, enum PinPullType pullType); | 设置管脚推拉方式 | -| int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType); | 获取管脚推拉方式 | -| int32_t PinSetStrength(DevHandle handle, uint32_t strength); | 设置管脚推拉强度 | -| int32_t PinGetStrength(DevHandle handle, uint32_t *strength); | 获取管脚推拉强度 | -| int32_t PinSetFunc(DevHandle handle, const char *funcName); | 设置管脚功能 | -| int32_t PinGetFunc(DevHandle handle, const char **funcName); | 获取管脚功能 | +| DevHandle PinGet(const char *pinName) | 获取管脚描述句柄 | +| void PinPut(DevHandle handle) | 释放管脚描述句柄 | +| int32_t PinSetPull(DevHandle handle, enum PinPullType pullType) | 设置管脚推拉方式 | +| int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType) | 获取管脚推拉方式 | +| int32_t PinSetStrength(DevHandle handle, uint32_t strength) | 设置管脚推拉强度 | +| int32_t PinGetStrength(DevHandle handle, uint32_t *strength) | 获取管脚推拉强度 | +| int32_t PinSetFunc(DevHandle handle, const char *funcName) | 设置管脚功能 | +| int32_t PinGetFunc(DevHandle handle, const char **funcName) | 获取管脚功能 | >![](../public_sys-resources/icon-note.gif) **说明:**
->本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 +>本文涉及PIN的所有接口,支持内核态及用户态使用。 ### 开发步骤 -使用PIN设备的一般流程如[图2](#fig2)所示。 +使用PIN设备的一般流程如图2所示。 **图 2** PIN使用流程图 ![](figures/PIN使用流程图.png "PIN使用流程图") @@ -76,7 +82,7 @@ PIN模块提供的主要接口如[表1](#table1)所示,更多关于接口的 在使用PIN进行管脚操作时,首先要调用PinGet获取管脚描述句柄,该函数会返回匹配传入管脚名的管脚描述句柄。 -``` +```c DevHandle PinGet(const char *pinName); ``` @@ -93,9 +99,10 @@ DevHandle PinGet(const char *pinName); 假设PIN需要操作的管脚名为P18,获取其管脚描述句柄的示例如下: -``` -DevHandle handle = NULL; /* PIN管脚描述句柄 */ -char pinName = "P18"; /* PIN管脚号 */ +```c +DevHandle handle = NULL; // PIN管脚描述句柄 + +char pinName = "P18"; // PIN管脚名 handle = PinGet(pinName); if (handle == NULL) { HDF_LOGE("PinGet: get handle failed!\n"); @@ -107,7 +114,7 @@ if (handle == NULL) { PIN设置管脚推拉方式的函数如下所示: -``` +```c int32_t PinSetPull(DevHandle handle, enum PinPullType pullType); ``` @@ -125,9 +132,10 @@ int32_t PinSetPull(DevHandle handle, enum PinPullType pullType); 假设PIN要设置的管脚推拉方式为上拉,其实例如下: -``` +```c int32_t ret; enum PinPullType pullTypeNum; + /* PIN设置管脚推拉方式 */ pullTypeNum = 1; ret = PinSetPull(handle, pullTypeNum); @@ -141,7 +149,7 @@ if (ret != HDF_SUCCESS) { PIN获取管脚推拉方式的函数如下所示: -``` +```c int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType); ``` @@ -159,9 +167,10 @@ int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType); PIN获取管脚推拉方式的实例如下: -``` +```c int32_t ret; enum PinPullType pullTypeNum; + /* PIN获取管脚推拉方式 */ ret = PinGetPull(handle, &pullTypeNum); if (ret != HDF_SUCCESS) { @@ -174,7 +183,7 @@ if (ret != HDF_SUCCESS) { PIN设置管脚推拉强度函数如下所示: -``` +```c int32_t PinSetStrength(DevHandle handle, uint32_t strength); ``` @@ -192,7 +201,7 @@ int32_t PinSetStrength(DevHandle handle, uint32_t strength); 假设PIN要设置的管脚推拉强度为2,其实例如下: -``` +```c int32_t ret; uint32_t strengthNum; /* PIN设置管脚推拉强度 */ @@ -208,7 +217,7 @@ if (ret != HDF_SUCCESS) { PIN设置管脚推拉强度后,可以通过PIN获取管脚推拉强度接口来查看PIN管脚推拉强度,PIN获取管脚推拉强度的函数如下所示: -``` +```c int32_t PinGetStrength(DevHandle handle, uint32_t *strength); ``` @@ -226,9 +235,10 @@ int32_t PinGetStrength(DevHandle handle, uint32_t *strength); PIN获取管脚推拉强度的实例如下: -``` +```c int32_t ret; uint32_t strengthNum; + /* PIN获取管脚推拉强度 */ ret = PinGetStrength(handle, &strengthNum); if (ret != HDF_SUCCESS) { @@ -239,11 +249,11 @@ if (ret != HDF_SUCCESS) { #### PIN设置管脚功能 -管脚功能特指的是管脚复用的功能,每个管脚功能都不相同,管脚功能名详细可以参考[PIN配置hcs文件](https://gitee.com/openharmony/device_soc_hisilicon/blob/master/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs)。 +管脚功能特指的是管脚复用的功能,每个管脚功能都不相同,管脚功能名详细可以参考//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs。 PIN设置管脚功能函数如下所示: -``` +```c int32_t PinSetFunc(DevHandle handle, const char *funcName); ``` @@ -261,9 +271,10 @@ int32_t PinSetFunc(DevHandle handle, const char *funcName); 假设PIN需要设置的管脚功能为LSADC_CH1(ADC通道1),其实例如下: -``` +```c int32_t ret; char funcName = "LSADC_CH1"; + /* PIN设置管脚功能 */ ret = PinSetFunc(handle, funcName); if (ret != HDF_SUCCESS) { @@ -276,7 +287,7 @@ if (ret != HDF_SUCCESS) { PIN设置管脚功能后,可以通过PIN获取管脚功能接口来查看PIN管脚功能,PIN获取管脚功能的函数如下所示: -``` +```c int32_t PinGetFunc(DevHandle handle, const char **funcName); ``` @@ -294,11 +305,12 @@ int32_t PinGetFunc(DevHandle handle, const char **funcName); PIN获取管脚功能的实例如下: -``` +```c int32_t ret; -char *funcName; +char *funcName = NULL; + /* PIN获取管脚功能 */ -ret = PinGetFunc(handle,&funcName); +ret = PinGetFunc(handle, &funcName); if (ret != HDF_SUCCESS) { HDF_LOGE("PinGetFunc: failed, ret %d\n", ret); return ret; @@ -309,7 +321,7 @@ if (ret != HDF_SUCCESS) { PIN不再进行任何操作后,需要释放PIN管脚描述管脚句柄,函数如下所示: -``` +```c void PinPut(DevHandle handle); ``` @@ -325,13 +337,14 @@ void PinPut(DevHandle handle); PIN销毁管脚描述句柄实例如下: -``` +```c PinPut(handle); ``` ## 使用实例 -使用PIN设置管脚相关属性完整使用可以参考如下示例代码,步骤主要如下: +下面将基于Hi3516DV300开发板展示使用PIN设置管脚相关属性完整操作,步骤主要如下: + 1. 传入要设置的管脚名,获取PIN管脚描述句柄。 2. 通过PIN管脚描述句柄以及推拉方式pullTypeNum设置管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。 3. 通过PIN管脚描述句柄,并用pullTypeNum承接获取的管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。 @@ -341,9 +354,9 @@ PinPut(handle); 6. 通过PIN管脚描述句柄,并用funName承接获取的管脚功能名,如果操作失败则释放PIN管脚描述句柄。 7. 使用完PIN后,不再对管脚进行操作,释放PIN管脚描述句柄。 -``` -#include "hdf_log.h" /* 标准日志打印头文件 */ -#include "pin_if.h" /* PIN标准接口头文件 */ +```c +#include "hdf_log.h" /* 标准日志打印头文件 */ +#include "pin_if.h" /* PIN标准接口头文件 */ int32_t PinTestSample(void) { @@ -359,7 +372,7 @@ int32_t PinTestSample(void) /* PIN获取管脚描述句柄 */ handle = PinGet(pinName); if (handle == NULL) { - HDF_LOGE("PinGet: failed!\n"); + HDF_LOGE("PinGet: pin get failed!\n"); return; } /* PIN设置管脚推拉方式为上拉 */ @@ -405,4 +418,5 @@ ERR: /* 释放PIN管脚描述句柄 */ PinPut(handle); return ret; -} \ No newline at end of file +} +``` diff --git a/zh-cn/device-dev/driver/driver-platform-pin-develop.md b/zh-cn/device-dev/driver/driver-platform-pin-develop.md index f3da58f351440a893e3566eda4d94eaf72dcc6b4..00ae1b6b003d658265815ed4535c47845aa03a67 100755 --- a/zh-cn/device-dev/driver/driver-platform-pin-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-pin-develop.md @@ -1,18 +1,18 @@ # PIN - ## 概述 ### 功能简介 -PIN即管脚控制器,用于统一管理各SoC厂商管脚资源,对外提供管脚复用功能。 + +PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能。 ### 基本概念 -PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。 +PIN是一个软件层面的概念,目的是为了统一对各SoC的PIN管脚进行管理,对外提供管脚复用功能,配置PIN管脚的电气特性。 - SoC(System on Chip) - 系统级芯片,也有称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。 + 系统级芯片,又称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。 - 管脚复用 @@ -20,30 +20,34 @@ PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚 ### 运作机制 -在HDF框架中,PIN模块暂不支持用户态,所以不需要发布服务。接口适配模式采用无服务模式(如图1所示),用于不需要在用户态提供API的设备类型。对于没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。 +在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。PIN模块接口适配模式采用统一服务模式(如图1所示)。 + +在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。 PIN模块各分层作用: + - 接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。 - 核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 - 适配层主要是将钩子函数的功能实例化,实现具体的功能。 -**图 1** 无服务模式结构图 +**图 1** 统一服务模式结构图 -![无服务模式结构图](figures/无服务模式结构图.png) +![统一服务模式结构图](figures/统一服务模式结构图.png) ### 约束与限制 -PIN模块目前仅支持轻量和小型系统内核(LiteOS)。 +PIN模块目前只支持小型系统LiteOS-A内核。 ## 开发指导 ### 场景介绍 -PIN模块主要用于管脚资源管理。在各SoC厂商对接HDF框架时,需要来适配PIN驱动。 +PIN模块主要用于管脚资源管理。在各SoC对接HDF框架时,需要来适配PIN驱动。下文将介绍如何进行PIN驱动适配。 ### 接口说明 -通过以下PinCntlrMethod中的函数调用PIN驱动对应的函数。 +为了保证上层在调用PIN接口时能够正确的操作PIN管脚,核心层在//drivers/hdf_core/framework/support/platform/include/pin/pin_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 + PinCntlrMethod定义: ```c @@ -57,383 +61,410 @@ struct PinCntlrMethod { }; ``` -**表 1** PinCntlrMethod成员的回调函数功能说明 +**表 1** PinCntlrMethod成员的钩子函数功能说明 | 成员函数 | 入参 | 出参 | 返回值 | 功能 | | ------------ | ------------------------------------------- | ------ | ---- | ---- | -| SetPinPull | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号
pullType:枚举常量,Pin管脚推拉方式 | 无 |HDF_STATUS相关状态|PIN设置管脚推拉方式| -| GetPinPull | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号 | pullType:枚举常量指针,传出Pin管脚推拉方式 | HDF_STATUS相关状态 | PIN获取管脚推拉方式 | -| SetPinStrength | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号
strength:uint32_t变量,Pin推拉强度 | 无 | HDF_STATUS相关状态 | PIN设置推拉强度 | -| GetPinStrength | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号 | strength:uint32_t变量指针,传出Pin推拉强度 | HDF_STATUS相关状态 | PIN获取推拉强度 | -| SetPinFunc | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号
funcName:char指针常量,传入Pin管脚功能 | 无 | HDF_STATUS相关状态 | PIN设置管脚功能 | -| GetPinFunc | cntlr:结构体指针,核心层Pin控制器
index:uint32_t变量,管脚索引号 | funcName:char双重指针常量,传出Pin管脚功能 | HDF_STATUS相关状态 | PIN获取管脚功能 | +| SetPinPull | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号
pullType:枚举常量,PIN管脚推拉方式 | 无 |HDF_STATUS相关状态|PIN设置管脚推拉方式| +| GetPinPull | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号 | pullType:枚举常量指针,传出获取的PIN管脚推拉方式 | HDF_STATUS相关状态 | PIN获取管脚推拉方式 | +| SetPinStrength | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号
strength:uint32_t变量,PIN推拉强度 | 无 | HDF_STATUS相关状态 | PIN设置推拉强度 | +| GetPinStrength | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号 | strength:uint32_t变量指针,传出获取的PIN推拉强度 | HDF_STATUS相关状态 | PIN获取推拉强度 | +| SetPinFunc | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号
funcName:char指针常量,传入PIN管脚功能 | 无 | HDF_STATUS相关状态 | PIN设置管脚功能 | +| GetPinFunc | cntlr:结构体指针,核心层PIN控制器
index:uint32_t类型变量,管脚索引号 | funcName:char双重指针常量,传出获取的PIN管脚功能 | HDF_STATUS相关状态 | PIN获取管脚功能 | ### 开发步骤 -PIN模块适配包含以下四个步骤: +PIN模块适配HDF框架包含以下四个步骤: - 实例化驱动入口。 - 配置属性文件。 -- 实例化核心层接口函数。 +- 实例化PIN控制器对象。 - 驱动调试。 -1. 实例化驱动入口: - - - 实例化HdfDriverEntry结构体成员。 - - 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。 - - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 - - 一般在加载驱动时HDF会先调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - - ```c - static struct HdfDriverEntry g_hi35xxPinDriverEntry = { - .moduleVersion = 1, - .Bind = Hi35xxPinBind, - .Init = Hi35xxPinInit, - .Release = Hi35xxPinRelease, - .moduleName = "hi35xx_pin_driver", // 【必要且与HCS文件中里面的moduleName匹配】 - }; - HDF_INIT(g_hi35xxPinDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 - ``` - -2. 配置属性文件: - - - 在vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 - - ```c - root { - device_info { - platform :: host { - hostName = "platform_host"; - priority = 50; - device_pin :: device { - device0 :: deviceNode { // 为每一个Pin控制器配置一个HDF设备节点,存在多个时须添加,否则不用。 - policy = 0; // 2:用户态可见;1:内核态可见;0:不需要发布服务。 - priority = 10; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - /* 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。 */ - moduleName = "hi35xx_pin_driver"; - /* 【必要】用于配置控制器私有数据,要与pin_config.hcs中对应控制器保持一致,具体的控制器信息在pin_config.hcs中。 */ - deviceMatchAttr = "hisilicon_hi35xx_pin_0"; - } - device1 :: deviceNode { - policy = 0; - priority = 10; - permission = 0644; - moduleName = "hi35xx_pin_driver"; - deviceMatchAttr = "hisilicon_hi35xx_pin_1"; - } - ...... - } - } - } - } - ``` - - 添加pin_config.hcs器件属性文件。 - - 在device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs目录下配置器件属性,其中配置参数如下: - ```c - root { - platform { - pin_config_hi35xx { - template pin_controller { // 【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。 - number = 0; // 【必要】controller编号 - regStartBasePhy = 0; // 【必要】寄存器物理基地址起始地址 - regSize = 0; // 【必要】寄存器位宽 - pinCount = 0; // 【必要】管脚数量 - match_attr = ""; - template pin_desc { - pinName = ""; // 【必要】管脚名称 - init = 0; // 【必要】寄存器默认值 - F0 = ""; // 【必要】功能0 - F1 = ""; // 功能1 - F2 = ""; // 功能2 - F3 = ""; // 功能3 - F4 = ""; // 功能4 - F5 = ""; // 功能5 - } - } - controller_0 :: pin_controller { - number = 0; - regStartBasePhy = 0x10FF0000; - regSize = 0x48; - pinCount = 18; - match_attr = "hisilicon_hi35xx_pin_0"; - T1 :: pin_desc { - pinName = "T1"; - init = 0x0600; - F0 = "EMMC_CLK"; - F1 = "SFC_CLK"; - F2 = "SFC_BOOT_MODE"; - } - ...... // 对应管脚控制器下的每个管脚,按实际添加。 - } - ......// 每个管脚控制器对应一个controller节点,如存在多个Pin控制器,请依次添加对应的controller节点。 - } - } - } - ``` - -3. 实例化PIN控制器对象: - - - 初始化PinCntlr成员。 - - 在Hi35xxPinCntlrInit函数中对PinCntlr成员进行初始化操作。 - - ```c - struct Hi35xxPinDesc { - // 管脚名 - const char *pinName; - // 初始化值 - uint32_t init; - // 管脚索引 - uint32_t index; - // 管脚推拉方式 - int32_t pullType; - // 管脚推拉强度 - int32_t strength; - // 管脚功能名字符串数组 - const char *func[HI35XX_PIN_FUNC_MAX]; - }; - - struct Hi35xxPinCntlr { - // 管脚控制器 - struct PinCntlr cntlr; - // 管脚描述结构体指针 - struct Hi35xxPinDesc *desc; - // 寄存器映射地址 - volatile unsigned char *regBase; - // 管脚控制器编号 - uint16_t number; - // 寄存器物理基地址起始地址 - uint32_t regStartBasePhy; - // 寄存器位宽 - uint32_t regSize; - // 管脚数量 - uint32_t pinCount; - }; - - // PinCntlr是核心层控制器,其中的成员在Init函数中会被赋值。 - struct PinCntlr { - struct IDeviceIoService service; - struct HdfDeviceObject *device; - struct PinCntlrMethod *method; - struct DListHead node; // 链表节点 - OsalSpinlock spin; // 自旋锁 - uint16_t number; // 管脚控制器编号 - uint16_t pinCount; // 管脚数量 - struct PinDesc *pins; - void *priv; // 私有数据 - }; - - // PinCntlr管脚控制器初始化 - static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx) - { - struct DeviceResourceIface *drsOps = NULL; - int32_t ret; - // 从hcs文件读取管脚控制器相关属性 - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) { - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return HDF_FAILURE; - } - ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read number failed", __func__); - return ret; - } - - ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regStartBasePhy failed", __func__); - return ret; - } - ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read regSize failed", __func__); - return ret; - } - ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read pinCount failed", __func__); - return ret; - } - // 将读取的值赋值给管脚控制器的成员,完成管脚控制器初始化。 - hi35xx->cntlr.pinCount = hi35xx->pinCount; - hi35xx->cntlr.number = hi35xx->number; - hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize); // 管脚控制器映射 - if (hi35xx->regBase == NULL) { - HDF_LOGE("%s: remap Pin base failed", __func__); - return HDF_ERR_IO; - } - hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount); - hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount); - return HDF_SUCCESS; - } - ``` - - - PinCntlr成员回调函数结构体PinCntlrMethod的实例化,其他成员在Init函数中初始化。 - - ```c - // PinCntlrMethod结构体成员都是回调函数,厂商需要根据表1完成相应的函数功能。 - static struct PinCntlrMethod g_method = { - .SetPinPull = Hi35xxPinSetPull, // 设置推拉方式 - .GetPinPull = Hi35xxPinGetPull, // 获取推拉方式 - .SetPinStrength = Hi35xxPinSetStrength, // 设置推拉强度 - .GetPinStrength = Hi35xxPinGetStrength, // 获取推拉强度 - .SetPinFunc = Hi35xxPinSetFunc, // 设置管脚功能 - .GetPinFunc = Hi35xxPinGetFunc, // 获取管脚功能 - }; - ``` - - - Init函数 - - 入参: - - HdfDeviceObject这个是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 - - 返回值: - - HDF\_STATUS相关状态(下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS定义)。 - - | **状态(值)** | **问题描述** | - | ---------------------- | -------------- | - | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | - | HDF_ERR_MALLOC_FAIL | 内存分配失败 | - | HDF_ERR_INVALID_PARAM | 参数非法 | - | HDF_ERR_IO | I/O 错误 | - | HDF_SUCCESS | 初始化成功 | - | HDF_FAILURE | 初始化失败 | - - 函数说明: - - 初始化自定义结构体对象和PinCntlr成员,并通过调用核心层PinCntlrAdd函数挂载Pin控制器。 - - ```c - static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc, const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps) - { - int32_t ret; - uint32_t funcNum = 0; - // 从hcs中读取管脚控制器子节点管脚功能名 - ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL"); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read F0 failed", __func__); - return ret; - } - - funcNum++; - ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL"); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read F1 failed", __func__); - return ret; - } - - funcNum++; - ...... - return HDF_SUCCESS; - } - - static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node, struct Hi35xxPinCntlr *hi35xx, int32_t index) - { - int32_t ret; - struct DeviceResourceIface *drsOps = NULL; - // 从hcs中读取管脚控制器子节点管脚相关属性 - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) { - HDF_LOGE("%s: invalid drs ops fail!", __func__); - return HDF_FAILURE; - } - ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL"); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read pinName failed", __func__); - return ret; - } - ...... - ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s:Pin read Func failed", __func__); - return ret; - } - hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName; - hi35xx->cntlr.pins[index].priv = (void *)node; - ...... - return HDF_SUCCESS; - } - - static int32_t Hi35xxPinInit(struct HdfDeviceObject *device) - { - ...... - struct Hi35xxPinCntlr *hi35xx = NULL; - ...... - ret = Hi35xxPinCntlrInit(device, hi35xx); // 管脚控制器初始化 - ...... - DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { // 遍历管脚控制器的每个子节点 - ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // 解析子节点 - ...... - } - - hi35xx->cntlr.method = &g_method; // 实例化method - ret = PinCntlrAdd(&hi35xx->cntlr); // 挂载控制器 - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: add Pin cntlr: failed", __func__); - ret = HDF_FAILURE; - } - return HDF_SUCCESS; - } - ``` - - - Release函数 - - 入参: - - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 - - 返回值: - - 无。 - - 函数说明: - - 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给 Release 接口。当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。 - - ```c - static void Hi35xxPinRelease(struct HdfDeviceObject *device) - { - int32_t ret; - uint16_t number; - struct PinCntlr *cntlr = NULL; - struct Hi35xxPinCntlr *hi35xx = NULL; - struct DeviceResourceIface *drsOps = NULL; - - if (device == NULL || device->property == NULL) { - HDF_LOGE("%s: device or property is null", __func__); - return; - } - // 从hcs文件中读取管脚控制器编号 - drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); - if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) { - HDF_LOGE("%s: invalid drs ops", __func__); - return; - } - ret = drsOps->GetUint16(device->property, "number", &number, 0); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: read cntlr number failed", __func__); - return; - } - - cntlr = PinCntlrGetByNumber(number); // 通过管脚控制器编号获取管脚控制器 - PinCntlrRemove(cntlr); - hi35xx = (struct Hi35xxPinCntlr *)cntlr; - if (hi35xx != NULL) { - if (hi35xx->regBase != NULL) { - OsalIoUnmap((void *)hi35xx->regBase); - } - OsalMemFree(hi35xx); - } - } - ``` -4. 驱动调试: +### 开发实例 + +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/pin/pin_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 + +1. 实例化驱动入口。 + + 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 + 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + + PIN驱动入口开发参考: + + ```c + static struct HdfDriverEntry g_hi35xxPinDriverEntry = { + .moduleVersion = 1, + .Bind = Hi35xxPinBind, + .Init = Hi35xxPinInit, + .Release = Hi35xxPinRelease, + .moduleName = "hi35xx_pin_driver", // 【必要且与HCS文件中里面的moduleName匹配】 + }; + HDF_INIT(g_hi35xxPinDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 + ``` + +2. 配置属性文件。 + + 完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以两个PIN控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息。器件属性值对于驱动适配者的驱动实现以及核心层PinCntlr相关成员的默认值或限制范围有密切关系,比如控制器号,控制器管脚数量、管脚等。需要在pin_config.hcs中配置器件属性。 + + - device_info.hcs 配置参考: + + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c + root { + device_info { + platform :: host { + hostName = "platform_host"; + priority = 50; + device_pin :: device { + device0 :: deviceNode { // 用于统一管理PIN并发布服务 + policy = 2; // 2:用户态可见;1:内核态可见;0:不需要发布服务。 + priority = 8; // 启动优先级 + permission = 0644; // 创建设备节点权限 + moduleName = "HDF_PLATFORM_PIN_MANAGER"; + serviceName = "HDF_PLATFORM_PIN_MANAGER"; + } + device1 :: deviceNode { // 为每一个PIN控制器配置一个HDF设备节点,存在多个时必须添加,否则不用。 + policy = 0; + priority = 10; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "hi35xx_pin_driver"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。 + deviceMatchAttr = "hisilicon_hi35xx_pin_0"; // 【必要】用于配置控制器私有数据,要与pin_config.hcs中对应控制器保持一致,具体的控制器信息在pin_config.hcs中。 + } + device2 :: deviceNode { + policy = 0; + priority = 10; + permission = 0644; + moduleName = "hi35xx_pin_driver"; + deviceMatchAttr = "hisilicon_hi35xx_pin_1"; + } + ... + } + } + } + } + ``` + + - pin_config.hcs配置参考: + + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs文件配置器件属性,其中配置参数如下: + + ```c + root { + platform { + pin_config_hi35xx { + template pin_controller { // 【必要】配置模板配,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值。 + number = 0; // 【必要】PIN控制器号 + regStartBasePhy = 0; // 【必要】寄存器物理基地址起始地址 + regSize = 0; // 【必要】寄存器位宽 + pinCount = 0; // 【必要】管脚数量 + match_attr = ""; + template pin_desc { + pinName = ""; // 【必要】管脚名称 + init = 0; // 【必要】寄存器默认值 + F0 = ""; // 【必要】功能0 + F1 = ""; // 功能1 + F2 = ""; // 功能2 + F3 = ""; // 功能3 + F4 = ""; // 功能4 + F5 = ""; // 功能5 + } + } + controller_0 :: pin_controller { + number = 0; + regStartBasePhy = 0x10FF0000; + regSize = 0x48; + pinCount = 18; + match_attr = "hisilicon_hi35xx_pin_0"; + T1 :: pin_desc { + pinName = "T1"; + init = 0x0600; + F0 = "EMMC_CLK"; + F1 = "SFC_CLK"; + F2 = "SFC_BOOT_MODE"; + } + ... // 对应管脚控制器下的每个管脚,按实际添加。 + } + ... // 每个管脚控制器对应一个控制器节点,如存在多个PIN控制器,请依次添加对应的控制器节点。 + } + } + } + ``` + + 需要注意的是,新增pin_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 + + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs" // 配置文件相对路径 + ``` + +3. 实例化PIN控制器对象。 + + 完成配置属性文件之后,下一步就是以核心层PinCntlr对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化PinCntlr成员PinCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 + + - 驱动适配者自定义结构体参考 + + 从驱动的角度看,自定义结构体是参数和数据的载体,而且pin_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象。 + + 在Hi35xxPinCntlrInit函数中对PinCntlr成员进行初始化操作。 + + ```c + // 驱动适配者自定义管脚描述结构体 + struct Hi35xxPinDesc { + const char *pinName; // 管脚名 + uint32_t init; // 初始化值 + uint32_t index; // 管脚索引 + int32_t pullType; // 管脚推拉方式 + int32_t strength; // 管脚推拉强度 + const char *func[HI35XX_PIN_FUNC_MAX]; // 管脚功能名字符串数组 + }; + + // 驱动适配者自定义结构体 + struct Hi35xxPinCntlr { + struct PinCntlr cntlr; // 是核心层控制对象,具体描述见下面 + struct Hi35xxPinDesc *desc; // 驱动适配者自定义管脚描述结构体指针 + volatile unsigned char *regBase; // 寄存器映射地址 + uint16_t number; // 管脚控制器编号 + uint32_t regStartBasePhy; // 寄存器物理基地址起始地址 + uint32_t regSize; // 寄存器位宽 + uint32_t pinCount; // 管脚数量 + }; + + // PinCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值。 + struct PinCntlr { + struct IDeviceIoService service; // 驱动服务 + struct HdfDeviceObject *device; // 驱动设备对象 + struct PinCntlrMethod *method; // 钩子函数 + struct DListHead node; // 链表节点 + OsalSpinlock spin; // 自旋锁 + uint16_t number; // 管脚控制器编号 + uint16_t pinCount; // 管脚数量 + struct PinDesc *pins; // 管脚资源 + void *priv; // 私有数据 + }; + + // PIN管脚控制器初始化 + static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx) + { + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + // 从hcs文件读取管脚控制器相关属性 + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) { + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return HDF_FAILURE; + } + ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read number failed", __func__); + return ret; + } + + if (hi35xx->number > HI35XX_PIN_MAX_NUMBER) { + HDF_LOGE("%s: invalid number:%u", __func__, hi35xx->number); + return HDF_ERR_INVALID_PARAM; + } + ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regStartBasePhy failed", __func__); + return ret; + } + ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read regSize failed", __func__); + return ret; + } + ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read pinCount failed", __func__); + return ret; + } + if (hi35xx->pinCount > PIN_MAX_CNT_PER_CNTLR) { + HDF_LOGE("%s: invalid number:%u", __func__, hi35xx->number); + return HDF_ERR_INVALID_PARAM; + } + // 将读取的值赋值给管脚控制器的成员,完成管脚控制器初始化。 + hi35xx->cntlr.pinCount = hi35xx->pinCount; + hi35xx->cntlr.number = hi35xx->number; + hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize); // 管脚控制器映射 + if (hi35xx->regBase == NULL) { + HDF_LOGE("%s: remap Pin base failed", __func__); + return HDF_ERR_IO; + } + hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount); + if (hi35xx->desc == NULL) { + HDF_LOGE("%s: memcalloc hi35xx desc failed", __func__); + return HDF_ERR_MALLOC_FAIL; + } + hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount); + if (hi35xx->desc == NULL) { + HDF_LOGE("%s: memcalloc hi35xx cntlr pins failed", __func__); + return HDF_ERR_MALLOC_FAIL; + } + return HDF_SUCCESS; + } + ``` + + - PinCntlr成员钩子函数结构体PinCntlrMethod的实例化,其他成员在Init函数中初始化。 + + ```c + static struct PinCntlrMethod g_method = { + .SetPinPull = Hi35xxPinSetPull, // 设置推拉方式 + .GetPinPull = Hi35xxPinGetPull, // 获取推拉方式 + .SetPinStrength = Hi35xxPinSetStrength, // 设置推拉强度 + .GetPinStrength = Hi35xxPinGetStrength, // 获取推拉强度 + .SetPinFunc = Hi35xxPinSetFunc, // 设置管脚功能 + .GetPinFunc = Hi35xxPinGetFunc, // 获取管脚功能 + }; + ``` + + - Init函数开发参考 + + 入参 + + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 + + 返回值: + + HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 + + | **状态(值)** | **问题描述** | + | ---------------------- | -------------- | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_INVALID_PARAM | 参数非法 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | + + 函数说明: + + 初始化自定义结构体对象和PinCntlr成员,并通过调用核心层PinCntlrAdd函数挂载PIN控制器。 + + ```c + static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc, const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps) + { + int32_t ret; + uint32_t funcNum = 0; + // 从hcs中读取管脚控制器子节点管脚功能名 + ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL"); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read F0 failed", __func__); + return ret; + } + + funcNum++; + ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL"); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read F1 failed", __func__); + return ret; + } + + funcNum++; + ... + return HDF_SUCCESS; + } + + static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node, struct Hi35xxPinCntlr *hi35xx, int32_t index) + { + int32_t ret; + struct DeviceResourceIface *drsOps = NULL; + // 从hcs中读取管脚控制器子节点管脚相关属性 + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) { + HDF_LOGE("%s: invalid drs ops fail!", __func__); + return HDF_FAILURE; + } + ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL"); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read pinName failed", __func__); + return ret; + } + ... + ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s:Pin read Func failed", __func__); + return ret; + } + hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName; + hi35xx->cntlr.pins[index].priv = (void *)node; + ... + return HDF_SUCCESS; + } + + static int32_t Hi35xxPinInit(struct HdfDeviceObject *device) + { + ... + struct Hi35xxPinCntlr *hi35xx = NULL; + ... + ret = Hi35xxPinCntlrInit(device, hi35xx); // 管脚控制器初始化 + ... + DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { // 遍历管脚控制器的每个子节点 + ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // 解析子节点 + ... + } + + hi35xx->cntlr.method = &g_method; // PinCntlrMethod实例化实例化对象的挂载 + ret = PinCntlrAdd(&hi35xx->cntlr); // 添加控制器 + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: add Pin cntlr: failed", __func__); + ret = HDF_FAILURE; + } + return HDF_SUCCESS; + } + ``` + + - Release函数开发参考 + + 入参: + + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 + + 返回值: + + 无。 + + 函数说明: + + 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口。当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。 + + ```c + static void Hi35xxPinRelease(struct HdfDeviceObject *device) + { + int32_t ret; + uint16_t number; + struct PinCntlr *cntlr = NULL; + struct Hi35xxPinCntlr *hi35xx = NULL; + struct DeviceResourceIface *drsOps = NULL; + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property is null", __func__); + return; + } + // 从hcs文件中读取管脚控制器编号 + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) { + HDF_LOGE("%s: invalid drs ops", __func__); + return; + } + ret = drsOps->GetUint16(device->property, "number", &number, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read cntlr number failed", __func__); + return; + } + + cntlr = PinCntlrGetByNumber(number); // 通过管脚控制器编号获取管脚控制器 + PinCntlrRemove(cntlr); + hi35xx = (struct Hi35xxPinCntlr *)cntlr; + if (hi35xx != NULL) { + if (hi35xx->regBase != NULL) { + OsalIoUnmap((void *)hi35xx->regBase); + } + OsalMemFree(hi35xx); + } + } + ``` + +4. 驱动调试。 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。 \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-pwm-des.md b/zh-cn/device-dev/driver/driver-platform-pwm-des.md index be8c703fb3699c971fce77988d76f7dc42c10ff5..18dd7fd810d9762fecd60cd9783acbf6e48baca2 100644 --- a/zh-cn/device-dev/driver/driver-platform-pwm-des.md +++ b/zh-cn/device-dev/driver/driver-platform-pwm-des.md @@ -1,417 +1,408 @@ # PWM - ## 概述 -PWM是脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术。常用于马达控制、背光亮度调节等。 +### 功能简介 + +PWM即脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术。 PWM接口定义了操作PWM设备的通用方法集合,包括: -- PWM设备句柄获取和释放。 -- PWM周期、占空比、极性的设置。 +- PWM设备句柄获取和释放 +- PWM周期、占空比、极性的设置 +- PWM使能和关闭 +- PWM配置信息的获取和设置 -- PWM使能和关闭。 +### 基本概念 -- PWM配置信息的获取和设置。 +脉冲是“电脉冲”的简称,指电路中电流或电压短暂起伏的现象,其特点是突变和不连续性。脉冲的种类很多,常见的脉冲波形有:三角脉冲、尖脉冲、矩形脉冲、方形脉冲、梯形脉冲及阶梯脉冲等。脉冲的主要参数包括重复周期T(T=1/F,F为煎复频率)、脉冲幅度U、脉冲前沿上升时间ts、后沿下降时间t、脉冲宽度tk等。 +### 运作机制 -### PwmConfig结构体 +在HDF框架中,PWM接口适配模式采用独立服务模式(如图1所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 - **表1** PwmConfig结构体介绍 +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: -| 名称 | 描述 | -| -------- | -------- | -| duty | 占空时间,以纳秒为单位。 | -| period | PWM周期,以纳秒为单位。 | -| number | 要生成的方波数:
- 正值:表示将生成指定数量的方波
- 0:表示方波将不断产生 | -| polarity | 极性:正极性/反极性。 | -| status | 状态:启用状态/禁用状态。 | +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 +PWM模块各分层作用: -## 接口说明 +- 接口层提供打开PWM设备、设置PWM设备周期、设置PWM设备占空时间、设置PWM设备极性、设置PWM设备参数、获取PWM设备参数、使能PWM设备、禁止PWM设备、关闭PWM设备的接口。 +- 核心层主要提供PWM控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 - **表2** PWM驱动API接口功能介绍 +**图1** PWM独立服务模式结构图 -| 功能分类 | 接口描述 | -| -------- | -------- | -| PWM句柄操作 | - PwmOpen:获取PWM设备驱动句柄
- PwmClose:释放PWM设备驱动句柄 | -| 使能/禁用PWM | - PwmEnable:使能PWM
- PwmDisable:禁用PWM | -| PWM配置操作 | - PwmSetPeriod:设置PWM周期
- PwmSetDuty:设置PWM占空时间
- PwmSetPolarity:设置PWM极性 | -| 设置/获取PWM配置信息 | - PwmSetConfig:设置PWM设备参数
- PwmGetConfig:获取PWM设备参数 | +![image1](figures/独立服务模式结构图.png "PWM独立服务模式结构图") -> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
-> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 +## 使用指导 +### 场景介绍 -## 使用指导 +通常情况下,在使用马达控制、背光亮度调节时会用到PWM模块。 +### 接口说明 -### 使用流程 +PWM模块设备属性如表1所示,PWM模块提供的主要接口如表2所示。 -使用PWM的一般流程如下图所示。 +**表1** PwmConfig结构体介绍 - **图1** PWM使用流程图 +| 名称 | 描述 | +| -------- | -------- | +| duty | 占空时间,以纳秒为单位。 | +| period | PWM周期,以纳秒为单位。 | +| number | 要生成的方波数:
- 正值:表示将生成指定数量的方波
- 0:表示方波将不断产生 | +| polarity | 极性:正极性/反极性。 | +| status | 状态:启用状态/禁用状态。 | + +**表2** PWM驱动API接口功能介绍 + +| 接口名 | | +| ------------------------------------------------------------ | ------------------- | +| DevHandle PwmOpen(uint32_t num) | 打开PWM设备 | +| void PwmClose(DevHandle handle) | 关闭PWM设备 | +| int32_t PwmSetPeriod(DevHandle handle, uint32_t period) | 设置PWM设备周期 | +| int32_t PwmSetDuty(DevHandle handle, uint32_t duty) | 设置PWM设备占空时间 | +| int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity) | 设置PWM设备极性 | +| int32_t PwmEnable(DevHandle handle) | 使能PWM设备 | +| int32_t PwmDisable(DevHandle handle) | 禁用PWM设备 | +| int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config) | 设置PWM设备参数 | +| int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config) | 获取PWM设备参数 | -![image](figures/PWM设备使用流程图.png "PWM设备使用流程图") +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+> 本文涉及PWM的所有接口,支持内核态及用户态使用。 +### 开发步骤 -### 获取PWM设备句柄 +使用PWM的一般流程如下图所示。 -在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。 +**图2** PWM使用流程图 +![image2](figures/PWM设备使用流程图.png "PWM设备使用流程图") -``` +#### 获取PWM设备句柄 + +在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。 + +```c DevHandle PwmOpen(uint32_t num); ``` - **表3** PwmOpen参数和返回值描述 +**表3** PwmOpen参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | -| num | PWM设备编号 | +| num | PWM设备号 | | **返回值** | **返回值描述** | -| handle | 获取成功,返回PWM设备句柄 | -| NULL | 获取失败 | +| handle | 打开PWM设备成功,返回PWM设备句柄 | +| NULL | 打开PWM设备失败 | 假设系统中的PWM设备号为0,获取该PWM设备句柄的示例如下: - -``` -uint32_t num = 0; /* PWM设备号 */ +```c +uint32_t num = 0; // PWM设备号 DevHandle handle = NULL; -/* 获取PWM设备句柄 */ -handle = PwmOpen(num); +handle = PwmOpen(num); // 打开PWM 0设备并获取PWM设备句柄 if (handle == NULL) { - /* 错误处理 */ + HDF_LOGE("PwmOpen: open pwm_%u failed.\n", num); + return; } ``` - -### 销毁PWM设备句柄 +#### 销毁PWM设备句柄 关闭PWM设备,系统释放对应的资源。 - -``` -voidPwmClose(DevHandle handle); +```c +void PwmClose(DevHandle handle); ``` - **表4** PwmClose参数描述 +**表4** PwmClose参数描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | - +```c +PwmClose(handle); // 关闭PWM设备销毁PWM设备句柄 ``` -/* 销毁PWM设备句柄 */ -PwmClose(handle); -``` - - -### 使能 - -启用PWM设备。 +#### 使能PWM设备 -``` +```c int32_t PwmEnable(DevHandle handle); ``` - **表5** PwmEnable参数和返回值描述 +**表5** PwmEnable参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | **返回值** | **返回值描述** | -| 0 | 使能成功 | +| HDF_SUCCESS | 使能成功 | | 负数 | 使能失败 | - -``` +```c int32_t ret; -/*启用PWM设备*/ -ret = PwmEnable(handle); -if (ret != 0) { - /*错误处理*/ +ret = PwmEnable(handle); // 启用PWM设备 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmEnable: enable pwm failed, ret:%d\n", ret); + return ret; } ``` +#### 禁用PWM设备 -### 禁用 - -禁用PWM设备。 - - -``` +```c int32_t PwmDisable(DevHandle handle); ``` - **表6** PwmDisable参数和返回值描述 +**表6** PwmDisable参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | **返回值** | **返回值描述** | -| 0 | 禁用成功 | +| HDF_SUCCESS | 禁用成功 | | 负数 | 禁用失败 | - -``` +```c int32_t ret; -/* 禁用PWM设备 */ -ret = PwmDisable(handle); -if (ret != 0) { - /* 错误处理 */ +ret = PwmDisable(handle); // 禁用PWM设备 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmDisable: disable pwm failed, ret:%d\n", ret); + return ret; } ``` +#### 设置PWM设备周期 -### 设置PWM设备周期 - -设置PWM设备周期。 - - -``` +```c int32_t PwmSetPeriod(DevHandle handle, uint32_t period); ``` - **表7** PwmSetPeriod参数和返回值描述 +**表7** PwmSetPeriod参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | period | 要设置的周期,单位为纳秒 | | **返回值** | **返回值描述** | -| 0 | 设置成功 | +| HDF_SUCCESS | 设置成功 | | 负数 | 设置失败 | - -``` +```c int32_t ret; -/* 设置周期为50000000纳秒 */ -ret = PwmSetPeriod(handle, 50000000); -if (ret != 0) { - /*错误处理*/ +ret = PwmSetPeriod(handle, 50000000); // 设置周期为50000000纳秒 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetPeriod: pwm set period failed, ret:%d\n", ret); + return ret; } ``` +#### 设置PWM设备占空时间 -### 设置设备占空时间 - -设置PWM设备占空时间。 - - -``` +```c int32_t PwmSetDuty(DevHandle handle, uint32_t duty); ``` - **表8** PwmSetDuty参数和返回值描述 +**表8** PwmSetDuty参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | duty | 要设置的占空时间,单位为纳秒 | | **返回值** | **返回值描述** | -| 0 | 设置成功 | +| HDF_SUCCESS | 设置成功 | | 负数 | 设置失败 | -``` +```c int32_t ret; -/* 设置占空时间为25000000纳秒 */ -ret = PwmSetDuty(handle, 25000000); -if (ret != 0) { - /* 错误处理 */ +ret = PwmSetDuty(handle, 25000000); // 设置占空时间为25000000纳秒 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetDuty: pwm set duty failed, ret:%d\n", ret); + return ret; } ``` +#### 设置PWM设备极性 -### 设置PWM设备极性 - -设置PWM设备极性。 - - -``` +```c int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity); ``` - **表9** PwmSetPolarity参数和返回值描述 +**表9** PwmSetPolarity参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | polarity | 要设置的极性,正/反 | | **返回值** | **返回值描述** | -| 0 | 设置成功 | +| HDF_SUCCESS | 设置成功 | | 负数 | 设置失败 | -``` +```c int32_t ret; -/* 设置极性为反 */ -ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); -if (ret != 0) { - /* 错误处理 */ +ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); // 设置极性为反 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetPolarity: pwm set polarity failed, ret:%d\n", ret); + return ret; } ``` +#### 设置PWM设备参数 -### 设置PWM设备参数 - -设置PWM设备参数。 - - -``` +```c int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config); ``` - **表10** PwmSetConfig参数和返回值描述 +**表10** PwmSetConfig参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | \*config | 参数指针 | | **返回值** | **返回值描述** | -| 0 | 设置成功 | +| HDF_SUCCESS | 设置成功 | | 负数 | 设置失败 | - -``` +```c int32_t ret; struct PwmConfig pcfg; -pcfg.duty = 25000000; /* 占空时间为25000000纳秒 */ -pcfg.period = 50000000; /* 周期为50000000纳秒 */ -pcfg.number = 0; /* 不断产生方波 */ -pcfg.polarity = PWM_INVERTED_POLARITY; /* 极性为反 */ -pcfg.status = PWM_ENABLE_STATUS; /* 运行状态为启用 */ - -/* 设置PWM设备参数 */ -ret = PwmSetConfig(handle, &pcfg); -if (ret != 0) { - /* 错误处理 */ -} -``` - -### 获取PWM设备参数 +pcfg.duty = 25000000; // 占空时间为25000000纳秒 +pcfg.period = 50000000; // 周期为50000000纳秒 +pcfg.number = 0; // 不断产生方波 +pcfg.polarity = PWM_INVERTED_POLARITY; // 极性为反 +pcfg.status = PWM_ENABLE_STATUS; // 运行状态为启用 -获取PWM设备参数。 +ret = PwmSetConfig(handle, &pcfg); // 设置PWM设备参数 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetConfig: pwm set config failed, ret:%d\n", ret); + return ret; +} +``` +#### 获取PWM设备参数 -``` +```c int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config); ``` - **表11** PwmGetConfig参数和返回值描述 +**表11** PwmGetConfig参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | PWM设备句柄 | | \*config | 参数指针 | | **返回值** | **返回值描述** | -| 0 | 获取成功 | +| HDF_SUCCESS | 获取成功 | | 负数 | 获取失败 | - -``` +```c int32_t ret; struct PwmConfig pcfg; -/*获取PWM设备参数*/ -ret = PwmGetConfig(handle, &pcfg); -if (ret != 0) { - /*错误处理*/ +ret = PwmGetConfig(handle, &pcfg); // 获取PWM设备参数 +if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmGetConfig: pwm get config failed, ret:%d\n", ret); + return ret; } ``` - ## 使用实例 -PWM设备完整的使用示例如下所示,首先获取PWM设备句柄,然后设置设备周期、占空时间、极性,获取设备参数。使能,设置设备参数,禁用,最后销毁PWM设备句柄。 +下面将基于Hi3516DV300开发板展示使用PWM完整操作,步骤主要如下: +1. 传入PWM设备号,打开PWM设备并获得PWM设备句柄。 +2. 通过PWM设备句柄及待设置的周期,设置PWM设备周期。 +3. 通过PWM设备句柄及待设置的占空时间,设置PWM设备占空时间。 +4. 通过PWM设备句柄及待设置的极性,设置PWM设备极性。 +5. 通过PWM设备句柄及待获取的设备参数,获取PWM设备参数。 +6. 通过PWM设备句柄,使能PWM设备。 +7. 通过PWM设备句柄及待设置的设备参数,设置PWM设备参数。 +8. 通过PWM设备句柄,禁用PWM设备。 +9. 通过PWM设备句柄,关闭PWM设备。 -``` -void PwmTestSample(void) +```c +#include "pwm_if.h" // pwm标准接口头文件 +#include "hdf_log.h" // 标准日志打印头文件 + +static int32_t PwmTestSample(void) { int32_t ret; uint32_t num; + uint32_t period DevHandle handle = NULL; struct PwmConfig pcfg; - pcfg.duty = 20000000; /* 占空时间为20000000纳秒 */ - pcfg.period = 40000000; /* 周期为40000000纳秒 */ - pcfg.number = 100; /* 生成100个方波 */ - pcfg.polarity = PWM_NORMAL_POLARITY; /* 极性为正 */ - pcfg.status = PWM_ENABLE_STATUS; /* 运行状态为启用 */ + pcfg.duty = 20000000; // 占空时间为20000000纳秒 + pcfg.period = 40000000; // 周期为40000000纳秒 + pcfg.number = 100; // 生成100个方波 + pcfg.polarity = PWM_NORMAL_POLARITY; // 极性为正 + pcfg.status = PWM_ENABLE_STATUS; // 运行状态为启用 - /* PWM设备编号,要填写实际平台上的编号 */ - num = 1; + num = 1; // PWM设备编号,要填写实际平台上的编号 - /* 获取PWM设备句柄 */ - handle = PwmOpen(num); + handle = PwmOpen(num); // 获取PWM设备句柄 if (handle == NULL) { - HDF_LOGE("PwmOpen: failed!\n"); + HDF_LOGE("PwmOpen: open pwm_%u failed!\n", num); return; } - /* 设置周期为50000000纳秒 */ - ret = PwmSetPeriod(handle, 50000000); - if (ret != 0) { - HDF_LOGE("PwmSetPeriod: failed, ret %d\n", ret); - goto _ERR; + ret = PwmSetPeriod(handle, 50000000); // 设置周期为50000000纳秒 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetPeriod: pwm set period failed, ret %d\n", ret); + goto ERR; } - /* 设置占空时间为25000000纳秒 */ - ret = PwmSetDuty(handle, 25000000); - if (ret != 0) { - HDF_LOGE("PwmSetDuty: failed, ret %d\n", ret); - goto _ERR; + ret = PwmSetDuty(handle, 25000000); // 设置占空时间为25000000纳秒 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetDuty: pwm set duty failed, ret %d\n", ret); + goto ERR; } - /* 设置极性为反 */ - ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); - if (ret != 0) { - HDF_LOGE("PwmSetPolarity: failed, ret %d\n", ret); - goto _ERR; + ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY); // 设置极性为反 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetPolarity: pwm set polarity failed, ret %d\n", ret); + goto ERR; } - /* 获取PWM设备参数 */ - ret = PwmGetConfig(handle, &pcfg); - if (ret != 0) { - HDF_LOGE("PwmGetConfig: failed, ret %d\n", ret); - goto _ERR; + ret = PwmGetConfig(handle, &pcfg); // 获取PWM设备参数 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmGetConfig: get pwm config failed, ret %d\n", ret); + goto ERR; } - /* 启用PWM设备 */ - ret = PwmEnable(handle); - if (ret != 0) { - HDF_LOGE("PwmEnable: failed, ret %d\n", ret); - goto _ERR; + ret = PwmEnable(handle); // 启用PWM设备 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmEnable: enable pwm failed, ret %d\n", ret); + goto ERR; } - /* 设置PWM设备参数 */ - ret = PwmSetConfig(handle, &pcfg); - if (ret != 0) { - HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret); - goto _ERR; + ret = PwmSetConfig(handle, &pcfg); // 设置PWM设备参数 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmSetConfig: set pwm config failed, ret %d\n", ret); + goto ERR; } - /* 禁用PWM设备 */ - ret = PwmDisable(handle); - if (ret != 0) { - HDF_LOGE("PwmDisable: failed, ret %d\n", ret); - goto _ERR; + ret = PwmDisable(handle); // 禁用PWM设备 + if (ret != HDF_SUCCESS) { + HDF_LOGE("PwmDisable: disable pwm failed, ret %d\n", ret); + goto ERR; } -_ERR: - /* 销毁PWM设备句柄 */ - PwmClose(handle); +ERR: + PwmClose(handle); // 销毁PWM设备句柄 + return ret; } ``` diff --git a/zh-cn/device-dev/driver/driver-platform-pwm-develop.md b/zh-cn/device-dev/driver/driver-platform-pwm-develop.md index 2b83466cfae808ebc2d85c30ea96f920055f5baf..192c93865f7973df001e0f478bded02db9fbb949 100755 --- a/zh-cn/device-dev/driver/driver-platform-pwm-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-pwm-develop.md @@ -1,210 +1,226 @@ # PWM - ## 概述 -PWM(Pulse Width Modulator)即脉冲宽度调节器。在HDF框架中,PWM的接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +### 功能简介 - **图1** PWM独立服务模式结构图 +PWM(Pulse Width Modulation)即脉冲宽度调制,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。通常情况下,在使用马达控制、背光亮度调节时会用到PWM模块。 - ![image](figures/独立服务模式结构图.png "PWM独立服务模式结构图") +### 基本概念 +脉冲是“电脉冲”的简称,指电路中电流或电压短暂起伏的现象,其特点是突变和不连续性。脉冲的种类很多,常见的脉冲波形有:三角脉冲、尖脉冲、矩形脉冲、方形脉冲、梯形脉冲及阶梯脉冲等。脉冲的主要参数包括重复周期T(T=1/F,F为煎复频率)、脉冲幅度U、脉冲前沿上升时间ts、后沿下降时间t、脉冲宽度tk等。 -## 接口说明 +### 运作机制 -PwmMethod定义: +在HDF框架中,PWM接口适配模式采用独立服务模式(如图1所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 - -``` -struct PwmMethod { - int32_t (*setConfig)(struct PwmDev *pwm, struct PwmConfig *config); - int32_t (*open)(struct PwmDev *pwm); - int32_t (*close)(struct PwmDev *pwm); -}; -``` +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: - **表1** PwmMethod结构体成员的回调函数功能说明 +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 -| 成员函数 | 入参 | 返回值 | 功能 | -| -------- | -------- | -------- | -------- | -| setConfig | pwm:结构体指针,核心层PWM控制器
config:结构体指针,属性传入值 | HDF_STATUS相关状态 | 配置属性 | -| open | pwm:结构体指针,核心层PWM控制器 | HDF_STATUS相关状态 | 打开设备 | -| close | pwm:结构体指针,核心层PWM控制器 | HDF_STATUS相关状态 | 关闭设备 | +PWM模块各分层作用: +- 接口层提供打开PWM设备、设置PWM设备周期、设置PWM设备占空时间、设置PWM设备极性、设置PWM设备参数、获取PWM设备参数、使能PWM设备、禁止PWM设备、关闭PWM设备的接口。 +- 核心层主要提供PWM控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 -## 开发步骤 +**图1** PWM独立服务模式结构图 -PWM模块适配HDF框架的三个必选环节是实例化驱动入口,配置属性文件,以及填充核心层接口函数。 +![image](figures/独立服务模式结构图.png "PWM独立服务模式结构图") -1. 实例化驱动入口 - - 实例化HdfDriverEntry结构体成员。 - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 +## 开发指导 -2. 配置属性文件 - - 在device_info.hcs文件中添加deviceNode描述。 - - 【可选】添加pwm_config.hcs器件属性文件。 +### 场景介绍 -3. 实例化PWM控制器对象 - - 初始化PwmDev成员。 - - 实例化PwmDev成员PwmMethod。 - > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
- > 实例化PwmDev成员PwmMethod,其定义和成员说明见[接口说明](#接口说明)。 +PWM用于脉冲宽度调制,当驱动开发者需要将PWM设备适配到OpenHarmony时,需要进行PWM驱动适配。下文将介绍如何进行PWM驱动适配。 -4. 驱动调试 +### 接口说明 - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如PWM控制状态,中断响应情况等。 +为了保证上层在调用PWM接口时能够正确的操作PWM控制器,核心层在//drivers/hdf_core/framework/support/platform/include/pwm/pwm_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 +PwmMethod定义: -## 开发实例 +```c +struct PwmMethod { + int32_t (*setConfig)(struct PwmDev *pwm, struct PwmConfig *config); + int32_t (*open)(struct PwmDev *pwm); + int32_t (*close)(struct PwmDev *pwm); +}; +``` -下方将以pwm_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 +**表1** PwmMethod结构体成员的钩子函数功能说明 -1. 驱动开发首先需要实例化驱动入口。 +| 成员函数 | 入参 | 返回值 | 功能 | +| -------- | -------- | -------- | -------- | +| setConfig | pwm:结构体指针,核心层PWM控制器
config:结构体指针,传入设置得设备属性 | HDF_STATUS相关状态 | 配置属性 | +| open | pwm:结构体指针,核心层PWM控制器 | HDF_STATUS相关状态 | 打开PWM设备 | +| close | pwm:结构体指针,核心层PWM控制器 | HDF_STATUS相关状态 | 关闭PWM设备 | - 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。 +### 开发步骤 - HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 +PWM模块适配包含以下四个步骤: +- 驱实例化驱动入口。 +- 配置属性文件。 +- 实例化PWM控制器对象。 +- 驱动调试。 + +### 开发实例 + +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/pwm/pwm_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 + +1. 驱实例化驱动入口。 + + 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - PWM驱动入口参考: - - ``` + PWM驱动入口开发参考: + + ```c struct HdfDriverEntry g_hdfPwm = { .moduleVersion = 1, - .moduleName = "HDF_PLATFORM_PWM",// 【必要且与HCS文件中里面的moduleName匹配】 - .Bind = HdfPwmBind, - .Init = HdfPwmInit, - .Release = HdfPwmRelease, + .moduleName = "HDF_PLATFORM_PWM", // 【必要且与HCS文件中里面的moduleName匹配】 + .Bind = HdfPwmBind, // 见Bind参考 + .Init = HdfPwmInit, // 见Init参考 + .Release = HdfPwmRelease, // 见Release参考 }; - // 调用HDF_INIT将驱动入口注册到HDF框架中 - HDF_INIT(g_hdfPwm); + HDF_INIT(g_hdfPwm); // 调用HDF_INIT将驱动入口注册到HDF框架中 ``` -2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在pwm_config.hcs中配置器件属性。 +2. 配置属性文件。 - deviceNode信息与驱动入口注册相关,器件属性值与核心层PwmDev成员的默认值或限制范围有密切关系。如有更多个器件信息,则需要在device_info文件增加deviceNode信息,以及在pwm_config文件中增加对应的器件属性。 + 完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以两个PWM控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息。器件属性值与核心层PwmDev成员的默认值或限制范围有密切关系,比如PWM设备号,需要在pwm_config.hcs文件中增加对应的器件属性。 - - device_info.hcs配置参考 + - device_info.hcs 配置参考: - - ``` + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c root { - device_info { - platform :: host { - hostName = "platform_host"; - priority = 50; - device_pwm :: device { // 为每一个pwm控制器配置一个HDF设备节点 - device0 :: deviceNode { - policy = 1; // 等于1,向内核态发布服务。 - priority = 80; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - moduleName = "HDF_PLATFORM_PWM"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。 - serviceName = "HDF_PLATFORM_PWM_0"; // 【必要且唯一】驱动对外发布服务的名称 - deviceMatchAttr = "hisilicon_hi35xx_pwm_0";// 【必要】用于配置控制器私有数据,要与pwm_config.hcs中对应 - // 控制器保持一致,具体的控制器信息在pwm_config.hcs中。 - } - device1 :: deviceNode { - policy = 1; - priority = 80; - permission = 0644; - moduleName = "HDF_PLATFORM_PWM"; - serviceName = "HDF_PLATFORM_PWM_1"; - deviceMatchAttr = "hisilicon_hi35xx_pwm_1"; + device_info { + platform :: host { + hostName = "platform_host"; + priority = 50; + device_pwm :: device { // 为每一个PWM控制器配置一个HDF设备节点 + device0 :: deviceNode { + policy = 1; // 等于1,向内核态发布服务 + priority = 80; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "HDF_PLATFORM_PWM"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致 + serviceName = "HDF_PLATFORM_PWM_0"; // 【必要且唯一】驱动对外发布服务的名称 + deviceMatchAttr = "hisilicon_hi35xx_pwm_0"; // 【必要】用于配置控制器私有数据,要与pwm_config.hcs中对应控制器保持一致,具体的控制器信息在pwm_config.hcs中 + } + device1 :: deviceNode { + policy = 1; + priority = 80; + permission = 0644; + moduleName = "HDF_PLATFORM_PWM"; + serviceName = "HDF_PLATFORM_PWM_1"; + deviceMatchAttr = "hisilicon_hi35xx_pwm_1"; + } + ... + } } - } } - } } ``` + - pwm_config.hcs 配置参考 - - ``` + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pwm/pwm_config.hcs文件配置器件属性,其中配置参数如下: + + ```c root { - platform { - pwm_config { - template pwm_device { // 【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。 - serviceName = ""; - match_attr = ""; - num = 0; // 【必要】设备号 - base = 0x12070000; // 【必要】地址映射需要 - } - device_0x12070000 :: pwm_device { // 存在多个设备时,请逐一添加相关HDF节点和设备节点信息。 - match_attr = "hisilicon_hi35xx_pwm_0";// 【必要】需要和device_info.hcs中的deviceMatchAttr值一致 - } - device_0x12070020 :: pwm_device { - match_attr = "hisilicon_hi35xx_pwm_1"; - num = 1; - base = 0x12070020; // 【必要】地址映射需要 - } + platform { + pwm_config { + template pwm_device { // 【必要】配置模板,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值 + serviceName = ""; + match_attr = ""; + num = 0; // 【必要】设备号 + base = 0x12070000; // 【必要】地址映射需要 + } + device_0x12070000 :: pwm_device { // 存在多个设备时,请逐一添加相关HDF节点和设备节点信息。 + match_attr = "hisilicon_hi35xx_pwm_0"; // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致 + } + device_0x12070020 :: pwm_device { + match_attr = "hisilicon_hi35xx_pwm_1"; + num = 1; + base = 0x12070020; // 【必要】地址映射需要 + } + } } - } } ``` -3. 完成驱动入口注册之后,下一步就是以核心层PwmDev对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化PwmDev成员PwmMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 + 需要注意的是,新增pwm_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 - - 自定义结构体参考。 + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pwm/pwm_config.hcs" // 配置文件相对路径 + ``` - 从驱动的角度看,自定义结构体是参数和数据的载体,而且pwm_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如设备号等。 +3. 实例化PWM控制器对象。 - - ``` + 完成驱动入口注册之后,下一步就是以核心层PwmDev对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化PwmDev成员PwmMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 + + - 驱动适配者自定义结构体参考。 + + 从驱动的角度看,驱动适配者自定义结构体是参数和数据的载体,而且pwm_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如PWM设备号。 + + ```c struct HiPwm { - struct PwmDev dev; // 【必要】 核心层结构体 - volatile unsigned char *base; - struct HiPwmRegs *reg; // 设备属性结构体,可自定义。 - bool supportPolarity; + struct PwmDev dev; // 【必要】 核是核心层控制对象 + volatile unsigned char *base; // 【必要】地址映射需要,寄存器基地址 + struct HiPwmRegs *reg; // 设备属性结构体,可自定义。 + bool supportPolarity; // 是否支持极性 }; - - // PwmDev是核心层控制器结构体,其中的成员在Init函数中会被赋值。 - struct PwmDev { - struct IDeviceIoService service; - struct HdfDeviceObject *device; - struct PwmConfig cfg; // 属性结构体,相关定义见下。 - struct PwmMethod *method; // 钩子函数模板 - bool busy; - uint32_t num; // 设备号 - OsalSpinlock lock; - void *priv; // 私有数据,一般存储自定义结构体首地址,方便调用。 + + struct PwmDev { // PwmDev是核心层控制器结构体,其中的成员在Init函数中会被赋值。 + struct IDeviceIoService service; // 驱动服务 + struct HdfDeviceObject *device; // 驱动设备对象 + struct PwmConfig cfg; // 设备属性结构体,相关定义见下。 + struct PwmMethod *method; // 钩子函数 + bool busy; // 是否繁忙 + uint32_t num; // 设备号 + OsalSpinlock lock; // 自旋锁 + void *priv; // 私有数据 }; - struct PwmConfig { - uint32_t duty; // 占空时间 nanoseconds - uint32_t period; // pwm 周期 nanoseconds - uint32_t number; // pwm 连续个数 - uint8_t polarity; // Polarity - // ------------------- | -------------- - // PWM_NORMAL_POLARITY | Normal polarity - // PWM_INVERTED_POLARITY | Inverted polarity - // - uint8_t status; // 运行状态 - // ------------------ | ----------------- - // PWM_DISABLE_STATUS | Disabled - // PWM_ENABLE_STATUS | Enabled + + struct PwmConfig { // PWM设备属性 + uint32_t duty; // 占空时间 nanoseconds + uint32_t period; // pwm 周期 nanoseconds + uint32_t number; // pwm 连续个数 + uint8_t polarity; // Polarity + // ------------------- | -------------- + // PWM_NORMAL_POLARITY | Normal polarity + // PWM_INVERTED_POLARITY | Inverted polarity + // + uint8_t status; // 运行状态 + // ------------------ | ----------------- + // PWM_DISABLE_STATUS | Disabled + // PWM_ENABLE_STATUS | Enabled }; ``` - - PwmDev成员回调函数结构体PwmMethod的实例化,其他成员在Init函数中初始化。 - - - ``` - // pwm_hi35xx.c中的示例:钩子函数的填充 - struct PwmMethod g_pwmOps = { - .setConfig = HiPwmSetConfig,// 配置属性 + - PwmDev成员钩子函数结构体PwmMethod的实例化,其他成员在Init函数中初始化。 + + ```c + struct PwmMethod g_pwmOps = { // pwm_hi35xx.c中的示例:钩子函数实例化 + .setConfig = HiPwmSetConfig, // 配置属性 }; ``` - - Init函数参考 + + - Init函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: - HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 + HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 - | 状态(值) | 问题描述 | + | 状态(值) | 问题描述 | | -------- | -------- | | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | | HDF_ERR_MALLOC_FAIL | 内存分配失败 | @@ -215,58 +231,58 @@ PWM模块适配HDF框架的三个必选环节是实例化驱动入口,配置 函数说明: - 初始化自定义结构体对象,初始化PwmDev成员,调用核心层PwmDeviceAdd函数。 + 初始化自定义结构体对象,初始化PwmDev成员,调用核心层PwmDeviceAdd函数,完成PWM控制器的添加。 - - ``` - // 此处Bind函数为空函数,可与Init函数结合,也可根据厂商需要实现相关操作。 + ```c + // 此处Bind函数为空函数,可与Init函数结合,也可根据驱动适配者需要实现相关操作。 static int32_t HdfPwmBind(struct HdfDeviceObject *obj) { - (void)obj; - return HDF_SUCCESS; + (void)obj; + return HDF_SUCCESS; } - + static int32_t HdfPwmInit(struct HdfDeviceObject *obj) { - int ret; - struct HiPwm *hp = NULL; - ... - hp = (struct HiPwm *)OsalMemCalloc(sizeof(*hp)); - ... - ret = HiPwmProbe(hp, obj); // 【必要】实现见下 - ... - return ret; + int ret; + struct HiPwm *hp = NULL; + ... + hp = (struct HiPwm *)OsalMemCalloc(sizeof(*hp)); + ... + ret = HiPwmProbe(hp, obj); // 【必要】实现见下 + ... + return ret; } - + static int32_t HiPwmProbe(struct HiPwm *hp, struct HdfDeviceObject *obj) { uint32_t tmp; struct DeviceResourceIface *iface = NULL; - iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);//初始化自定义结构体HiPwm + iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); //初始化自定义结构体HiPwm ... - hp->reg = (struct HiPwmRegs *)hp->base; // 初始化自定义结构体HiPwm - hp->supportPolarity = false; // 初始化自定义结构体HiPwm - hp->dev.method = &g_pwmOps; // PwmMethod的实例化对象的挂载 - hp->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE; // 初始化PwmDev - hp->dev.cfg.period = PWM_DEFAULT_PERIOD; // 初始化PwmDev - hp->dev.cfg.polarity = PWM_DEFAULT_POLARITY; // 初始化PwmDev - hp->dev.cfg.status = PWM_DISABLE_STATUS; // 初始化PwmDev - hp->dev.cfg.number = 0; // 初始化PwmDev - hp->dev.busy = false; // 初始化PwmDev - if (PwmDeviceAdd(obj, &(hp->dev)) != HDF_SUCCESS) { // 【重要】调用核心层函数,初始化hp->dev的设备和服务。 + hp->reg = (struct HiPwmRegs *)hp->base; // 初始化自定义结构体HiPwm + hp->supportPolarity = false; // 初始化自定义结构体HiPwm + hp->dev.method = &g_pwmOps; // PwmMethod的实例化对象的挂载 + hp->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE; // 初始化PwmDev + hp->dev.cfg.period = PWM_DEFAULT_PERIOD; // 初始化PwmDev + hp->dev.cfg.polarity = PWM_DEFAULT_POLARITY; // 初始化PwmDev + hp->dev.cfg.status = PWM_DISABLE_STATUS; // 初始化PwmDev + hp->dev.cfg.number = 0; // 初始化PwmDev + hp->dev.busy = false; // 初始化PwmDev + if (PwmDeviceAdd(obj, &(hp->dev)) != HDF_SUCCESS) { // 【重要】调用核心层函数,初始化hp->dev的设备和服务。 OsalIoUnmap((void *)hp->base); return HDF_FAILURE; } return HDF_SUCCESS; } ``` - - Release函数参考 + + - Release函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -276,15 +292,18 @@ PWM模块适配HDF框架的三个必选环节是实例化驱动入口,配置 释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。 - - ``` + ```c static void HdfPwmRelease(struct HdfDeviceObject *obj) { struct HiPwm *hp = NULL; ... - hp = (struct HiPwm *)obj->service;// 这里有HdfDeviceObject到HiPwm的强制转化 - ... - PwmDeviceRemove(obj, &(hp->dev)); // 【必要】调用核心层函数,释放PwmDev的设备和服务,这里有HiPwm到PwmDev的强制转化。 - HiPwmRemove(hp); // 释放HiPwm + hp = (struct HiPwm *)obj->service; // 这里有HdfDeviceObject到HiPwm的强制转化 + ... + PwmDeviceRemove(obj, &(hp->dev)); // 【必要】调用核心层函数,释放PwmDev的设备和服务,这里有HiPwm到PwmDev的强制转化。 + HiPwmRemove(hp); // 释放HiPwm } ``` + +4. 驱动调试。 + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如PWM控制状态,中断响应情况等。 \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-uart-des.md b/zh-cn/device-dev/driver/driver-platform-uart-des.md index b042d8fd09c9783091e3ce6ecbc3a5f848735a4b..500ab657eac4f5a9392d64771cc3eb01f9bed8b3 100644 --- a/zh-cn/device-dev/driver/driver-platform-uart-des.md +++ b/zh-cn/device-dev/driver/driver-platform-uart-des.md @@ -1,328 +1,350 @@ # UART - ## 概述 -UART指异步收发传输器(Universal Asynchronous Receiver/Transmitter),是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 +### 功能简介 -UART应用比较广泛,常用于输出打印信息,也可以外接各种模块,如GPS、蓝牙等。 +UART指异步收发传输器(Universal Asynchronous Receiver/Transmitter),是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: + - TX:发送数据端,和对端的RX相连。 - RX:接收数据端,和对端的TX相连。 - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连。 - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连。 - **图1** 2线UART设备连接示意图 +**图1** 2线UART设备连接示意图 - ![image](figures/2线UART设备连接示意图.png "2线UART设备连接示意图") +![image1](figures/2线UART设备连接示意图.png "2线UART设备连接示意图") - **图2** 4线UART设备连接示意图 +**图2** 4线UART设备连接示意图 - ![image](figures/4线UART设备连接示意图.png "4线UART设备连接示意图") +![image2](figures/4线UART设备连接示意图.png "4线UART设备连接示意图") -- UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 +UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 -- UART接口定义了操作UART端口的通用方法集合,包括获取、释放设备句柄、读写数据、获取和设置波特率、获取和设置设备属性。 +UART接口定义了操作UART端口的通用方法集合,包括: +- 打开/关闭UART设备 +- 读写数据 +- 设置/获取UART设备波特率 +- 设置/获取UART设备属性 -## 接口说明 +### 基本概念 - **表1** UART驱动API接口功能介绍 +- 异步通信 -| 接口名 | 接口描述 | -| -------- | -------- | -| UartOpen | UART获取设备句柄 | -| UartClose | UART释放设备句柄 | -| UartRead | 从UART设备中读取指定长度的数据 | -| UartWrite | 向UART设备中写入指定长度的数据 | -| UartGetBaud | UART获取波特率 | -| UartSetBaud | UART设置波特率 | -| UartGetAttribute | UART获取设备属性 | -| UartSetAttribute | UART设置设备属性 | -| UartSetTransMode | UART设置传输模式 | + 异步通信中,数据通常以字符或者字节为单位组成字符帧传送。字符帧由发送端逐帧发送,通过传输线被接收设备逐帧接收。发送端和接收端可以由各自的时钟来控制数据的发送和接收,这两个时钟源彼此独立,互不同步。异步通信以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而在同一个字符中的两个相邻位代码间的时间间隔是固定的。 -> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
-> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 +- 全双工传输(Full Duplex) + + 此通信模式允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工可以同时进行信号的双向传输。 + +### 运作机制 + +在HDF框架中,UART接口适配模式采用独立服务模式(如图3所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: + +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 + +UART模块各分层作用: + +- 接口层提供打开UART设备、UART设备读取指定长度数据、UART设备写入指定长度数据、设置UART设备波特率、获取设UART设备波特率、设置UART设备属性、获取UART设备波特率、设置UART设备传输模式、关闭UART设备的接口。 +- 核心层主要提供看UART控制器的创建、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 + +**图3** UART独立服务模式结构图 + +![image3](figures/独立服务模式结构图.png "UART独立服务模式结构图") ## 使用指导 +### 场景介绍 + +UART模块应用比较广泛,主要用于实现设备之间的低速串行通信,例如输出打印信息,当然也可以外接各种模块,如GPS、蓝牙等。 + +### 接口说明 + +**表1** UART驱动API接口功能介绍 + +| 接口名 | 接口描述 | +| -------- | -------- | +| DevHandle UartOpen(uint32_t port) | UART获取设备句柄 | +| void UartClose(DevHandle handle) | UART释放设备句柄 | +| int32_t UartRead(DevHandle handle, uint8_t *data, uint32_t size) | 从UART设备中读取指定长度的数据 | +| int32_t UartWrite(DevHandle handle, uint8_t *data, uint32_t size) | 向UART设备中写入指定长度的数据 | +| int32_t UartGetBaud(DevHandle handle, uint32_t *baudRate) | UART获取波特率 | +| int32_t UartSetBaud(DevHandle handle, uint32_t baudRate) | UART设置波特率 | +| int32_t UartGetAttribute(DevHandle handle, struct UartAttribute *attribute) | UART获取设备属性 | +| int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute) | UART设置设备属性 | +| int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode) | UART设置传输模式 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+> 本文涉及的UART所有接口,支持内核态及用户态使用。 -### 使用流程 +### 开发步骤 使用UART的一般流程如下图所示。 - **图3** UART使用流程图 +**图3** UART使用流程图 - ![image](figures/UART使用流程图.png "UART使用流程图") +![image3](figures/UART使用流程图.png "UART使用流程图") -### 获取UART设备句柄 +#### 获取UART设备句柄 在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 - -``` +```c DevHandle UartOpen(uint32_t port); ``` - **表2** UartOpen参数和返回值描述 +**表2** UartOpen参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| port | UART设备号 | -| **返回值** | **返回值描述** | -| NULL | 获取UART设备句柄失败 | -| 设备句柄 | UART设备句柄 | +| port | UART设备号 | +| **返回值** | **返回值描述** | +| NULL | 获取UART设备句柄失败 | +| 设备句柄 | UART设备句柄 | + +假设系统中的UART端口号为1,获取该UART设备句柄的示例如下: + +```c +DevHandle handle = NULL; // UART设备句柄 +uint32_t port = 1; // UART设备端口号 - 假设系统中的UART端口号为3,获取该UART设备句柄的示例如下: - -``` -DevHandle handle = NULL; /* UART设备句柄 */ -uint32_t port = 3; /* UART设备端口号 */ handle = UartOpen(port); if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); + HDF_LOGE("UartOpen: open uart_%u failed!\n", port); return; } ``` - -### UART设置波特率 +#### UART设置波特率 在通信之前,需要设置UART的波特率,设置波特率的函数如下所示: - -``` +```c int32_t UartSetBaud(DevHandle handle, uint32_t baudRate); ``` - **表3** UartSetBaud参数和返回值描述 +**表3** UartSetBaud参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| baudRate | 待设置的波特率值 | -| **返回值** | **返回值描述** | -| 0 | UART设置波特率成功 | -| 负数 | UART设置波特率失败 | +| handle | UART设备句柄 | +| baudRate | 待设置的波特率值 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART设置波特率成功 | +| 负数 | UART设置波特率失败 | 假设需要设置的UART波特率为9600,设置波特率的实例如下: - -``` +```c int32_t ret; -/* 设置UART波特率 */ -ret = UartSetBaud(handle, 9600); -if (ret != 0) { + +ret = UartSetBaud(handle, 9600); // 设置UART波特率 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); + return ret; } ``` - -### UART获取波特率 +#### UART获取波特率 设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率,获取波特率的函数如下所示: - -``` +```c int32_t UartGetBaud(DevHandle handle, uint32_t *baudRate); ``` - **表4** UartGetBaud参数和返回值描述 +**表4** UartGetBaud参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| baudRate | 接收波特率值的指针 | -| **返回值** | **返回值描述** | -| 0 | UART获取波特率成功 | -| 负数 | UART获取波特率失败 | +| handle | UART设备句柄 | +| baudRate | 接收波特率值的指针 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART获取波特率成功 | +| 负数 | UART获取波特率失败 | 获取波特率的实例如下: - -``` +```c int32_t ret; uint32_t baudRate; -/* 获取UART波特率 */ -ret = UartGetBaud(handle, &baudRate); -if (ret != 0) { + +ret = UartGetBaud(handle, &baudRate); // 获取UART波特率 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartGetBaud: failed, ret %d\n", ret); + return ret; } ``` +#### UART设置设备属性 -### UART设置设备属性 - -在通信之前,需要设置UART的设备属性,设置设备属性的函数如下图所示: +在通信之前,需要设置UART的设备属性,设置设备属性的函数如下所示: - -``` -int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute); +```c +int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute); ``` - **表5** UartSetAttribute参数和返回值描述 +**表5** UartSetAttribute参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| attribute | 待设置的设备属性 | -| **返回值** | **返回值描述** | -| 0 | UART设置设备属性成功 | -| 负数 | UART设置设备属性失败 | +| handle | UART设备句柄 | +| attribute | 待设置的设备属性 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART设置设备属性成功 | +| 负数 | UART设置设备属性失败 | 设置UART的设备属性的实例如下: - -``` +```c int32_t ret; struct UartAttribute attribute; -attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ -attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ -attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ -attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ -attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ -attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ -attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ -/* 设置UART设备属性 */ -ret = UartSetAttribute(handle, &attribute); -if (ret != 0) { + +attribute.dataBits = UART_ATTR_DATABIT_7; // UART传输数据位宽,一次传输7个bit +attribute.parity = UART_ATTR_PARITY_NONE; // UART传输数据无校检 +attribute.stopBits = UART_ATTR_STOPBIT_1; // UART传输数据停止位为1位 +attribute.rts = UART_ATTR_RTS_DIS; // UART禁用RTS +attribute.cts = UART_ATTR_CTS_DIS; // UART禁用CTS +attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; // UART使能RX FIFO +attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; // UART使能TX FIFO + +ret = UartSetAttribute(handle, &attribute); // 设置UART设备属性 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); +turn ret; } ``` +#### UART获取设备属性 -### UART获取设备属性 - -设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下图所示: +设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性,获取设备属性的函数如下所示: - -``` +```c int32_t UartGetAttribute(DevHandle handle, struct UartAttribute *attribute); ``` - **表6** UartGetAttribute参数和返回值描述 +**表6** UartGetAttribute参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| attribute | 接收UART设备属性的指针 | -| **返回值** | **返回值描述** | -| 0 | UART获取设备属性成功 | -| 负数 | UART获取设备属性失败 | +| handle | UART设备句柄 | +| attribute | 接收UART设备属性的指针 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART获取设备属性成功 | +| 负数 | UART获取设备属性失败 | 获取UART的设备属性的实例如下: - -``` +```c int32_t ret; struct UartAttribute attribute; -/* 获取UART设备属性 */ -ret = UartGetAttribute(handle, &attribute); -if (ret != 0) { + +ret = UartGetAttribute(handle, &attribute); // 获取UART设备属性 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret); + return ret; } ``` +#### 设置UART传输模式 -### 设置UART传输模式 - -在通信之前,需要设置UART的传输模式,设置传输模式的函数如下图所示: +在通信之前,需要设置UART的传输模式,设置传输模式的函数如下所示: - -``` -int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode); +```c +int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode); ``` - **表7** UartSetTransMode参数和返回值描述 +**表7** UartSetTransMode参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| mode | 待设置的传输模式, | -| **返回值** | **返回值描述** | -| 0 | UART设置传输模式成功 | -| 负数 | UART设置传输模式失败 | +| handle | UART设备句柄 | +| mode | 待设置的传输模式, | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART设置传输模式成功 | +| 负数 | UART设置传输模式失败 | 假设需要设置的UART传输模式为UART_MODE_RD_BLOCK,设置传输模式的实例如下: - -``` +```c int32_t ret; -/* 设置UART传输模式 */ -ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); -if (ret != 0) { + +ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK); // 设置UART传输模式 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); + return ret; } ``` - -### 向UART设备写入指定长度的数据 +#### 向UART设备写入指定长度的数据 对应的接口函数如下所示: - -``` +```c int32_t UartWrite(DevHandle handle, uint8_t *data, uint32_t size); ``` - **表8** UartWrite参数和返回值描述 +**表8** UartWrite参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| data | 待写入数据的指针 | -| size | 待写入数据的长度 | -| **返回值** | **返回值描述** | -| 0 | UART写数据成功 | -| 负数 | UART写数据失败 | +| handle | UART设备句柄 | +| data | 待写入数据的指针 | +| size | 待写入数据的长度 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | UART写数据成功 | +| 负数 | UART写数据失败 | 写入指定长度数据的实例如下: - -``` +```c int32_t ret; uint8_t wbuff[5] = {1, 2, 3, 4, 5}; -/* 向UART设备写入指定长度的数据 */ -ret = UartWrite(handle, wbuff, 5); -if (ret != 0) { + +ret = UartWrite(handle, wbuff, 5); // 向UART设备写入指定长度的数据 +if (ret != HDF_SUCCESS) { HDF_LOGE("UartWrite: failed, ret %d\n", ret); + return ret; } ``` - -### 从UART设备中读取指定长度的数据 +#### 从UART设备中读取指定长度的数据 对应的接口函数如下所示: - -``` +```c int32_t UartRead(DevHandle handle, uint8_t *data, uint32_t size); ``` - **表9** UartRead参数和返回值描述 +**表9** UartRead参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | -| data | 接收读取数据的指针 | -| size | 待读取数据的长度 | -| **返回值** | **返回值描述** | -| 非负数 | UART读取到的数据长度 | -| 负数 | UART读取数据失败 | +| handle | UART设备句柄 | +| data | 接收读取数据的指针 | +| size | 待读取数据的长度 | +| **返回值** | **返回值描述** | +| 非负数 | UART读取到的数据长度 | +| 负数 | UART读取数据失败 | 读取指定长度数据的实例如下: - -``` +```c int32_t ret; uint8_t rbuff[5] = {0}; -/* 从UART设备读取指定长度的数据 */ -ret = UartRead(handle, rbuff, 5); + +ret = UartRead(handle, rbuff, 5); // 从UART设备读取指定长度的数据 if (ret < 0) { HDF_LOGE("UartRead: failed, ret %d\n", ret); + return ret; } ``` @@ -330,94 +352,115 @@ if (ret < 0) { > UART返回值为非负值,表示UART读取成功。若返回值等于0,表示UART无有效数据可以读取。若返回值大于0,表示实际读取到的数据长度,该长度小于或等于传入的参数size的大小,并且不超过当前正在使用的UART控制器规定的最大单次读取数据长度的值。 -### 销毁UART设备句柄 +#### 销毁UART设备句柄 UART通信完成之后,需要销毁UART设备句柄,函数如下所示: - -``` +```c void UartClose(DevHandle handle); ``` 该函数会释放申请的资源。 - **表10** UartClose参数和返回值描述 +**表10** UartClose参数和返回值描述 -| 参数 | 参数描述 | +| 参数 | 参数描述 | | -------- | -------- | -| handle | UART设备句柄 | +| handle | UART设备句柄 | 销毁UART设备句柄的实例如下: - -``` -UartClose(handle); /* 销毁UART设备句柄 * +```c +UartClose(handle); // 销毁UART设备句柄 ``` - ## 使用实例 - UART设备完整的使用示例如下所示,首先获取UART设备句柄,接着设置波特率、设备属性和传输模式,之后进行UART通信,最后销毁UART设备句柄。 - -``` +下面将基于Hi3516DV300开发板展示使用UART完整操作,步骤主要如下: + +1. 传入UART端口号num,打开端口号对应的UART设备并获得UART设备句柄。 +2. 通过UART设备句柄及设置的波特率,设置UART设备的波特率。 +3. 通过UART设备句柄及待获取的波特率,获取UART设备的波特率。 +4. 通过UART设备句柄及待设置的设备属性,设置UART设备的设备属性。 +5. 通过UART设备句柄及待获取的设备属性,获取UART设备的设备属性。 +6. 通过UART设备句柄及待设置的传输模式,设置UART设备的传输模式。 +7. 通过UART设备句柄及待传输的数据及大小,传输指定长度的数据。 +8. 通过UART设备句柄及待接收的数据及大小,接收指定长度的数据。 +9. 通过UART设备句柄,关闭UART设备。 + +```c #include "hdf_log.h" #include "uart_if.h" void UartTestSample(void) { int32_t ret; - uint32_t port; + uint32_t port; + uint32_t baud; DevHandle handle = NULL; uint8_t wbuff[5] = { 1, 2, 3, 4, 5 }; uint8_t rbuff[5] = { 0 }; struct UartAttribute attribute; - attribute.dataBits = UART_ATTR_DATABIT_7; /* UART传输数据位宽,一次传输7个bit */ - attribute.parity = UART_ATTR_PARITY_NONE; /* UART传输数据无校检 */ - attribute.stopBits = UART_ATTR_STOPBIT_1; /* UART传输数据停止位为1位 */ - attribute.rts = UART_ATTR_RTS_DIS; /* UART禁用RTS */ - attribute.cts = UART_ATTR_CTS_DIS; /* UART禁用CTS */ - attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; /* UART使能RX FIFO */ - attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; /* UART使能TX FIFO */ - /* UART设备端口号,要填写实际平台上的端口号 */ - port = 1; - /* 获取UART设备句柄 */ - handle = UartOpen(port); + + attribute.dataBits = UART_ATTR_DATABIT_7; // UART传输数据位宽,一次传输7个bit + attribute.parity = UART_ATTR_PARITY_NONE; // UART传输数据无校检 + attribute.stopBits = UART_ATTR_STOPBIT_1; // UART传输数据停止位为1位 + attribute.rts = UART_ATTR_RTS_DIS; // UART禁用RTS + attribute.cts = UART_ATTR_CTS_DIS; // UART禁用CTS + attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; // UART使能RX FIFO + attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; // UART使能TX FIFO + + port = 1; // UART设备端口号,要填写实际平台上的端口号 + + handle = UartOpen(port); // 获取UART设备句柄 if (handle == NULL) { - HDF_LOGE("UartOpen: failed!\n"); + HDF_LOGE("UartOpen: open uart_%u failed!\n", port); return; } - /* 设置UART波特率为9600 */ - ret = UartSetBaud(handle, 9600); - if (ret != 0) { - HDF_LOGE("UartSetBaud: failed, ret %d\n", ret); - goto _ERR; + + ret = UartSetBaud(handle, 9600); // 设置UART波特率为9600 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartSetBaud: set baud failed, ret %d\n", ret); + goto ERR; } - /* 设置UART设备属性 */ - ret = UartSetAttribute(handle, &attribute); - if (ret != 0) { - HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret); - goto _ERR; + + ret = UartGetBaud(handle, &baud); // 获取UART波特率 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartGetBaud: get baud failed, ret %d\n", ret); + goto ERR; } - /* 设置UART传输模式为非阻塞模式 */ - ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); - if (ret != 0) { - HDF_LOGE("UartSetTransMode: failed, ret %d\n", ret); - goto _ERR; + + ret = UartSetAttribute(handle, &attribute); // 设置UART设备属性 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartSetAttribute: set attribute failed, ret %d\n", ret); + goto ERR; } - /* 向UART设备写入5字节的数据 */ - ret = UartWrite(handle, wbuff, 5); - if (ret != 0) { - HDF_LOGE("UartWrite: failed, ret %d\n", ret); - goto _ERR; + + ret = UartGetAttribute(handle, &attribute); // 获取UART设备属性 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartGetAttribute: get attribute failed, ret %d\n", ret); + goto ERR; } - /* 从UART设备读取5字节的数据 */ - ret = UartRead(handle, rbuff, 5); + + ret = UartSetTransMode(handle, UART_MODE_RD_NONBLOCK); // 设置UART传输模式为非阻塞模式 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartSetTransMode: set trans mode failed, ret %d\n", ret); + goto ERR; + } + + ret = UartWrite(handle, wbuff, 5); // 向UART设备写入5字节的数据 + if (ret != HDF_SUCCESS) { + HDF_LOGE("UartWrite: write data failed, ret %d\n", ret); + goto ERR; + } + + ret = UartRead(handle, rbuff, 5); // 从UART设备读取5字节的数据 if (ret < 0) { - HDF_LOGE("UartRead: failed, ret %d\n", ret); - goto _ERR; + HDF_LOGE("UartRead: read data failed, ret %d\n", ret); + goto ERR; } -_ERR: - /* 销毁UART设备句柄 */ - UartClose(handle); +ERR: + UartClose(handle); // 销毁UART设备句柄 + return ret; } ``` diff --git a/zh-cn/device-dev/driver/driver-platform-uart-develop.md b/zh-cn/device-dev/driver/driver-platform-uart-develop.md index 29495e8eec5394b09e1d0a9446575abd59a097e3..cff8e0e2b1c72bd1b9ad3e2ed2750e8a83ed89d7 100755 --- a/zh-cn/device-dev/driver/driver-platform-uart-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-uart-develop.md @@ -1,299 +1,334 @@ # UART - ## 概述 -在HDF框架中,UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)的接口适配模式采用独立服务模式。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +### 功能简介 - **图1** UART独立服务模式结构图 +UART指异步收发传输器(Universal Asynchronous Receiver/Transmitter),是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 - ![image](figures/独立服务模式结构图.png "UART独立服务模式结构图") +两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是: + - TX:发送数据端,和对端的RX相连。 + - RX:接收数据端,和对端的TX相连。 + - RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连。 + - CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连。 -## 接口说明 +**图1** 2线UART设备连接示意图 -UartHostMethod定义: +![image1](figures/2线UART设备连接示意图.png "2线UART设备连接示意图") - -``` -struct UartHostMethod { - int32_t (*Init)(struct UartHost *host); - int32_t (*Deinit)(struct UartHost *host); - int32_t (*Read)(struct UartHost *host, uint8_t *data, uint32_t size); - int32_t (*Write)(struct UartHost *host, uint8_t *data, uint32_t size); - int32_t (*GetBaud)(struct UartHost *host, uint32_t *baudRate); - int32_t (*SetBaud)(struct UartHost *host, uint32_t baudRate); - int32_t (*GetAttribute)(struct UartHost *host, struct UartAttribute *attribute); - int32_t (*SetAttribute)(struct UartHost *host, struct UartAttribute *attribute); - int32_t (*SetTransMode)(struct UartHost *host, enum UartTransMode mode); - int32_t (*pollEvent)(struct UartHost *host, void *filep, void *table); -}; -``` +**图2** 4线UART设备连接示意图 - **表1** UartHostMethod结构体成员的回调函数功能说明 +![image2](figures/4线UART设备连接示意图.png "4线UART设备连接示意图") -| 函数 | 入参 | 出参 | 返回值 | 功能 | -| -------- | -------- | -------- | -------- | -------- | -| Init | host:结构体指针,核心层UART控制器 | 无 | HDF_STATUS相关状态 | 初始化Uart设备 | -| Deinit | host:结构体指针,核心层UART控制器 | 无 | HDF_STATUS相关状态 | 去初始化Uart设备 | -| Read | host:结构体指针,核心层UART控制器
size:uint32_t,数据大小 | data:uint8_t指针,传出的数据 | HDF_STATUS相关状态 | 接收数据RX | -| Write | host:结构体指针,核心层UART控制器
data:uint8_t指针,传入数据
size:uint32_t,数据大小 | 无 | HDF_STATUS相关状态 | 发送数据TX | -| SetBaud | host:结构体指针,核心层UART控制器
baudRate:uint32_t指针,波特率传入值 | 无 | HDF_STATUS相关状态 | 设置波特率 | -| GetBaud | host:结构体指针,核心层UART控制器 | baudRate:uint32_t指针,传出的波特率 | HDF_STATUS相关状态 | 获取当前设置的波特率 | -| GetAttribute | host:结构体指针,核心层UART控制器 | attribute:结构体指针,传出的属性值(见uart_if.h中UartAttribute定义) | HDF_STATUS相关状态 | 获取设备uart相关属性 | -| SetAttribute | host:结构体指针,核心层UART控制器
attribute:结构体指针,属性传入值 | 无 | HDF_STATUS相关状态 | 设置设备UART相关属性 | -| SetTransMode | host:结构体指针,核心层UART控制器
mode:枚举值(见uart_if.h中UartTransMode定义),传输模式 | 无 | HDF_STATUS相关状态 | 设置传输模式 | -| PollEvent | host:结构体指针,核心层UART控制器
filep:void指针file
table:void指针poll_table | 无 | HDF_STATUS相关状态 | poll机制 | +UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。 +### 基本概念 -## 开发步骤 +- 异步通信 -UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置属性文件,以及实例化核心层接口函数。 + 异步通信中,数据通常以字符或者字节为单位组成字符帧传送。字符帧由发送端逐帧发送,通过传输线被接收设备逐帧接收。发送端和接收端可以由各自的时钟来控制数据的发送和接收,这两个时钟源彼此独立,互不同步。异步通信以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而在同一个字符中的两个相邻位代码间的时间间隔是固定的。 -1. 实例化驱动入口 - - 实例化HdfDriverEntry结构体成员。 - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 +- 全双工传输(Full Duplex) -2. 配置属性文件 - - 在device_info.hcs文件中添加deviceNode描述。 - - 【可选】添加uart_config.hcs器件属性文件。 + 此通信模式允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工可以同时进行信号的双向传输。 -3. 实例化UART控制器对象 - - 初始化UartHost成员。 - - 实例化UartHost成员UartHostMethod。 - > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
- > 实例化UartHost成员UartHostMethod,其定义和成员说明见[接口说明](#接口说明)。 +### 运作机制 + +在HDF框架中,UART接口适配模式采用独立服务模式(如图3所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 + +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: + +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 + +UART模块各分层作用: + +- 接口层提供打开UART设备、UART设备读取指定长度数据、UART设备写入指定长度数据、设置UART设备波特率、获取设UART设备波特率、设置UART设备属性、获取UART设备波特率、设置UART设备传输模式、关闭UART设备的接口。 +- 核心层主要提供看UART控制器的创建、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 + +**图3** UART独立服务模式结构图 + +![image3](figures/独立服务模式结构图.png "UART独立服务模式结构图") + +## 开发指导 + +### 场景介绍 -4. 驱动调试 +UART模块应用比较广泛,主要用于实现设备之间的低速串行通信,例如输出打印信息,当然也可以外接各种模块,如GPS、蓝牙等。当驱动开发者需要将UART设备适配到OpenHarmony时,需要进行UART驱动适配。下文将介绍如何进行UART驱动适配。 - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如UART控制状态,中断响应情况等。 +### 接口说明 +为了保证上层在调用UART接口时能够正确的操作UART控制器,核心层在//drivers/hdf_core/framework/support/platform/include/uart/uart_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 -## 开发实例 +UartHostMethod定义: + +```c +struct UartHostMethod { + int32_t (*Init)(struct UartHost *host); + int32_t (*Deinit)(struct UartHost *host); + int32_t (*Read)(struct UartHost *host, uint8_t *data, uint32_t size); + int32_t (*Write)(struct UartHost *host, uint8_t *data, uint32_t size); + int32_t (*GetBaud)(struct UartHost *host, uint32_t *baudRate); + int32_t (*SetBaud)(struct UartHost *host, uint32_t baudRate); + int32_t (*GetAttribute)(struct UartHost *host, struct UartAttribute *attribute); + int32_t (*SetAttribute)(struct UartHost *host, struct UartAttribute *attribute); + int32_t (*SetTransMode)(struct UartHost *host, enum UartTransMode mode); + int32_t (*pollEvent)(struct UartHost *host, void *filep, void *table); +}; +``` + +**表1** UartHostMethod结构体成员的回调函数功能说明 + +| 函数 | 入参 | 出参 | 返回值 | 功能 | +| -------- | -------- | -------- | -------- | -------- | +| Init | host:结构体指针,核心层UART控制器 | 无 | HDF_STATUS相关状态 | 初始化Uart设备 | +| Deinit | host:结构体指针,核心层UART控制器 | 无 | HDF_STATUS相关状态 | 去初始化Uart设备 | +| Read | host:结构体指针,核心层UART控制器
size:uint32_t类型,接收数据大小 | data:uint8_t类型指针,接收的数据 | HDF_STATUS相关状态 | 接收数据RX | +| Write | host:结构体指针,核心层UART控制器
data:uint8_t类型指针,传入数据
size:uint32_t类型,发送数据大小 | 无 | HDF_STATUS相关状态 | 发送数据TX | +| SetBaud | host:结构体指针,核心层UART控制器
baudRate:uint32_t类型,波特率传入值 | 无 | HDF_STATUS相关状态 | 设置波特率 | +| GetBaud | host:结构体指针,核心层UART控制器 | baudRate:uint32_t类型指针,传出的波特率 | HDF_STATUS相关状态 | 获取当前设置的波特率 | +| GetAttribute | host:结构体指针,核心层UART控制器 | attribute:结构体指针,传出的属性值(见uart_if.h中UartAttribute定义) | HDF_STATUS相关状态 | 获取设备uart相关属性 | +| SetAttribute | host:结构体指针,核心层UART控制器
attribute:结构体指针,属性传入值 | 无 | HDF_STATUS相关状态 | 设置设备UART相关属性 | +| SetTransMode | host:结构体指针,核心层UART控制器
mode:枚举值(见uart_if.h中UartTransMode定义),传输模式 | 无 | HDF_STATUS相关状态 | 设置传输模式 | +| PollEvent | host:结构体指针,核心层UART控制器
filep:void类型指针file
table:void类型指针table | 无 | HDF_STATUS相关状态 | poll轮询机制 | + +### 开发步骤 -下方将以uart_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 +UART模块适配HDF框架包含以下四个步骤: -1. 驱动开发首先需要实例化驱动入口。 +- 实例化驱动入口。 +- 配置属性文件。 +- 实例化UART控制器对象。 +- 驱动调试。 - 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。 +### 开发实例 - HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/uart/uart_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 +1. 实例化驱动入口。 + + 驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - UART驱动入口参考: - - ``` + UART驱动入口开发参考: + + ```c struct HdfDriverEntry g_hdfUartDevice = { .moduleVersion = 1, - .moduleName = "HDF_PLATFORM_UART",// 【必要且与HCS里面的名字匹配】 - .Bind = HdfUartDeviceBind, // 见Bind参考 - .Init = HdfUartDeviceInit, // 见Init参考 - .Release = HdfUartDeviceRelease, // 见Release参考 + .moduleName = "HDF_PLATFORM_UART", // 【必要且与HCS文件中里面的moduleName匹配】 + .Bind = HdfUartDeviceBind, // 见Bind参考 + .Init = HdfUartDeviceInit, // 见Init参考 + .Release = HdfUartDeviceRelease, // 见Release参考 }; - //调用HDF_INIT将驱动入口注册到HDF框架中 - HDF_INIT(g_hdfUartDevice); + HDF_INIT(g_hdfUartDevice); //调用HDF_INIT将驱动入口注册到HDF框架中 ``` -2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在uart_config.hcs中配置器件属性。 - - deviceNode信息与驱动入口注册相关,器件属性值与核心层UartHost成员的默认值或限制范围有密切关系。 +2. 配置属性文件。 - 本例只有一个UART控制器,如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在uart_config文件中增加对应的器件属性。 + 完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以两个UART控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息。器件属性值与核心层UartHost成员的默认值或限制范围有密切关系,比如UART设备端口号,需要在uart_config.hcs文件中增加对应的器件属性。 - device_info.hcs 配置参考: - - - ``` - root { - device_info { - match_attr = "hdf_manager"; - platform :: host { - hostName = "platform_host"; - priority = 50; - device_uart :: device { - device0 :: deviceNode { - policy = 1; // 驱动服务发布的策略,policy大于等于1(用户态可见为2,仅内核态可见为1)。 - priority = 40; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - moduleName = "HDF_PLATFORM_UART"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致。 - serviceName = "HDF_PLATFORM_UART_0"; // 驱动对外发布服务的名称,必须唯一,必须要按照HDF_PLATFORM_UART_X的格式,X为UART控制器编号。 - deviceMatchAttr = "hisilicon_hi35xx_uart_0";// 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值一致。 - } - device1 :: deviceNode { - policy = 2; - permission = 0644; - priority = 40; - moduleName = "HDF_PLATFORM_UART"; - serviceName = "HDF_PLATFORM_UART_1"; - deviceMatchAttr = "hisilicon_hi35xx_uart_1"; - } - ... - } - } - } - } - ``` - + + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c + root { + device_info { + match_attr = "hdf_manager"; + platform :: host { + hostName = "platform_host"; + priority = 50; + device_uart :: device { + device0 :: deviceNode { + policy = 1; // 驱动服务发布的策略,policy大于等于1(用户态可见为2,仅内核态可见为1)。 + priority = 40; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "HDF_PLATFORM_UART"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致。 + serviceName = "HDF_PLATFORM_UART_0"; // 驱动对外发布服务的名称,必须唯一,必须要按照HDF_PLATFORM_UART_X的格式,X为UART控制器编号。 + deviceMatchAttr = "hisilicon_hi35xx_uart_0"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值一致。 + } + device1 :: deviceNode { + policy = 2; + permission = 0644; + priority = 40; + moduleName = "HDF_PLATFORM_UART"; + serviceName = "HDF_PLATFORM_UART_1"; + deviceMatchAttr = "hisilicon_hi35xx_uart_1"; + } + ... + } + } + } + } + ``` + - uart_config.hcs 配置参考: - - - ``` - root { - platform { - template uart_controller {// 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省 - match_attr = ""; - num = 0; // 【必要】设备号 - baudrate = 115200; // 【必要】波特率,数值可按需填写 - fifoRxEn = 1; // 【必要】使能接收FIFO - fifoTxEn = 1; // 【必要】使能发送FIFO - flags = 4; // 【必要】标志信号 - regPbase = 0x120a0000; // 【必要】地址映射需要 - interrupt = 38; // 【必要】中断号 - iomemCount = 0x48; // 【必要】地址映射需要 - } - controller_0x120a0000 :: uart_controller { - match_attr = "hisilicon_hi35xx_uart_0";// 【必要】必须和device_info.hcs中对应的设备的deviceMatchAttr值一致 - } - controller_0x120a1000 :: uart_controller { - num = 1; - baudrate = 9600; - regPbase = 0x120a1000; - interrupt = 39; - match_attr = "hisilicon_hi35xx_uart_1"; - } - ... - // 【可选】可新增,但需要在 device_info.hcs 添加对应的节点 - } - } - ``` - -3. 完成属性文件配置之后,下一步就是以核心层UartHost对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化UartHost成员UartHostMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 - - - 自定义结构体参考 - - 从驱动的角度看,自定义结构体是参数和数据的载体,而且uart_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如设备号等。 - - + + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/uart/uart_config.hcs文件配置器件属性,其中配置参数如下: + + ```c + root { + platform { + template uart_controller { // 配置模板,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值 + match_attr = ""; + num = 0; // 【必要】端口号 + baudrate = 115200; // 【必要】波特率,数值可按需填写 + fifoRxEn = 1; // 【必要】使能接收FIFO + fifoTxEn = 1; // 【必要】使能发送FIFO + flags = 4; // 【必要】标志信号 + regPbase = 0x120a0000; // 【必要】地址映射需要 + interrupt = 38; // 【必要】中断号 + iomemCount = 0x48; // 【必要】地址映射需要 + } + controller_0x120a0000 :: uart_controller { + match_attr = "hisilicon_hi35xx_uart_0"; // 【必要】必须和device_info.hcs中对应的设备的deviceMatchAttr值一致 + } + controller_0x120a1000 :: uart_controller { + num = 1; + baudrate = 9600; + regPbase = 0x120a1000; + interrupt = 39; + match_attr = "hisilicon_hi35xx_uart_1"; + } + ... // 如果存在多个UART设备时【必须】添加节点,否则不用 + } + } ``` - struct UartPl011Port { // 接口相关的结构体 - int32_t enable; - unsigned long physBase; // 物理地址 - uint32_t irqNum; // 中断号 - uint32_t defaultBaudrate;// 默认波特率 - uint32_t flags; // 标志信号,下面三个宏与之相关。 + + 需要注意的是,新增uart_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 + + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/uart/uart_config.hcs" // 配置文件相对路径 + ``` + +3. 实例化UART控制器对象。 + + 完成属性文件配置之后,下一步就是以核心层UartHost对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化UartHost成员UartHostMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 + + - 驱动适配者自定义结构体参考 + + 从驱动的角度看,驱动适配者自定义结构体是参数和数据的载体,而且uart_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象,例如端口号。 + + ```c + struct UartPl011Port { // 驱动适配者自定义管脚描述结构体 + int32_t enable; + unsigned long physBase; // 物理地址 + uint32_t irqNum; // 中断号 + uint32_t defaultBaudrate; // 默认波特率 + uint32_t flags; // 标志信号,下面三个宏与之相关 #define PL011_FLG_IRQ_REQUESTED (1 << 0) #define PL011_FLG_DMA_RX_REQUESTED (1 << 1) #define PL011_FLG_DMA_TX_REQUESTED (1 << 2) - struct UartDmaTransfer *rxUdt; // DMA传输相关 - struct UartDriverData *udd; // 见下 + struct UartDmaTransfer *rxUdt; // DMA传输相关 + struct UartDriverData *udd; }; - struct UartDriverData { // 数据传输相关的结构体 - uint32_t num; - uint32_t baudrate; // 波特率(可设置) - struct UartAttribute attr; // 数据位、停止位等传输属性相关。 - struct UartTransfer *rxTransfer; // 缓冲区相关,可理解为FIFO结构。 - wait_queue_head_t wait; // 条件变量相关的排队等待信号 - int32_t count; // 数据数量 - int32_t state; // UART控制器状态 + struct UartDriverData { // 数据传输相关的结构体 + uint32_t num; // 端口号 + uint32_t baudrate; // 波特率(可设置) + struct UartAttribute attr; // 数据位、停止位等传输属性相关 + struct UartTransfer *rxTransfer; // 缓冲区相关,可理解为FIFO结构 + wait_queue_head_t wait; // 条件变量相关的排队等待信号 + int32_t count; // 数据数量 + int32_t state; // UART控制器状态 #define UART_STATE_NOT_OPENED 0 #define UART_STATE_OPENING 1 #define UART_STATE_USEABLE 2 #define UART_STATE_SUSPENDED 3 - uint32_t flags; // 状态标志 + uint32_t flags; // 状态标志 #define UART_FLG_DMA_RX (1 << 0) #define UART_FLG_DMA_TX (1 << 1) #define UART_FLG_RD_BLOCK (1 << 2) - RecvNotify recv; // 函数指针类型,指向串口数据接收函数。 - struct UartOps *ops; // 自定义函数指针结构体,详情见device/hisilicon/drivers/uart/uart_pl011.c。 - void *private; // 一般用来存储UartPl011Port首地址,方便调用。 + RecvNotify recv; // 函数指针类型,指向串口数据接收函数 + struct UartOps *ops; // 自定义函数指针结构体 + void *private; // 私有数据 }; // UartHost是核心层控制器结构体,其中的成员在Init函数中会被赋值。 struct UartHost { - struct IDeviceIoService service; - struct HdfDeviceObject *device; - uint32_t num; - OsalAtomic atom; - void *priv; // 一般存储厂商自定义结构体首地址,方便后者被调用。 - struct UartHostMethod *method; // 核心层钩子函数,厂商需要实现其成员函数功能并实例化。 + struct IDeviceIoService service; // 驱动服务 + struct HdfDeviceObject *device; // 驱动设备对象 + uint32_t num; // 端口号 + OsalAtomic atom; // 原子量 + void *priv; // 私有数据 + struct UartHostMethod *method; // 回调函数 }; ``` - - UartHost成员回调函数结构体UartHostMethod的实例化,其他成员在Bind函数中初始化。 + - UartHost成员回调函数结构体UartHostMethod的实例化,其中的成员在Init函数中初始化。 - - ``` + ```c // uart_hi35xx.c 中的示例:钩子函数的实例化 struct UartHostMethod g_uartHostMethod = { - .Init = Hi35xxInit, - .Deinit = Hi35xxDeinit, - .Read = Hi35xxRead, - .Write = Hi35xxWrite, - .SetBaud = Hi35xxSetBaud, - .GetBaud = Hi35xxGetBaud, - .SetAttribute = Hi35xxSetAttribute, - .GetAttribute = Hi35xxGetAttribute, - .SetTransMode = Hi35xxSetTransMode, - .pollEvent = Hi35xxPollEvent, + .Init = Hi35xxInit, // 初始化 + .Deinit = Hi35xxDeinit, // 去初始化 + .Read = Hi35xxRead, // 接收数据 + .Write = Hi35xxWrite, // 发送数据 + .SetBaud = Hi35xxSetBaud, // 设置波特率 + .GetBaud = Hi35xxGetBaud, // 获取波特率 + .SetAttribute = Hi35xxSetAttribute, // 设置设备属性 + .GetAttribute = Hi35xxGetAttribute, // 获取设备属性 + .SetTransMode = Hi35xxSetTransMode, // 设置传输模式 + .pollEvent = Hi35xxPollEvent, // 轮询 }; ``` - - Bind函数参考 + - Bind函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: - HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可参见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS定义)。 + HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可参见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS中HDF_STATUS定义)。 - **表2** HDF_STATUS返回值说明 - - | 状态(值) | 问题描述 | + **表2** HDF_STATUS返回值说明 + + | 状态(值) | 问题描述 | | -------- | -------- | - | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | - | HDF_ERR_MALLOC_FAIL | 内存分配失败 | - | HDF_ERR_INVALID_PARAM | 参数非法 | - | HDF_ERR_IO | I/O 错误 | - | HDF_SUCCESS | 初始化成功 | - | HDF_FAILURE | 初始化失败 | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_INVALID_PARAM | 参数非法 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | 函数说明: 初始化自定义结构体对象,初始化UartHost成员。 - - ``` + ```c //uart_hi35xx.c static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device) { ... - return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;// 【必须做】调用核心层函数UartHostCreate + return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS; // 【必须】调用核心层函数UartHostCreate } + // uart_core.c核心层UartHostCreate函数说明 struct UartHost *UartHostCreate(struct HdfDeviceObject *device) { - struct UartHost *host = NULL; // 新建UartHost - ... - host = (struct UartHost *)OsalMemCalloc(sizeof(*host));//分配内存 + struct UartHost *host = NULL; // 新建UartHost + ... + host = (struct UartHost *)OsalMemCalloc(sizeof(*host)); // 分配内存 ... - host->device = device; // 【必要】使HdfDeviceObject与UartHost可以相互转化的前提 - device->service = &(host->service); // 【必要】使HdfDeviceObject与UartHost可以相互转化的前提 - host->device->service->Dispatch = UartIoDispatch; // 为service成员的Dispatch方法赋值 - OsalAtomicSet(&host->atom, 0); // 原子量初始化或者原子量设置 + host->device = device; // 【必要】使HdfDeviceObject与UartHost可以相互转化的前提 + device->service = &(host->service); // 【必要】使HdfDeviceObject与UartHost可以相互转化的前提 + host->device->service->Dispatch = UartIoDispatch; // 为service成员的Dispatch方法赋值 + OsalAtomicSet(&host->atom, 0); // 原子量初始化或者原子量设置 host->priv = NULL; host->method = NULL; return host; } ``` - - Init函数参考 + - Init函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -301,48 +336,44 @@ UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置 函数说明: - 初始化自定义结构体对象,初始化UartHost成员,调用核心层UartAddDev函数,接入VFS。 - - - ``` + 初始化自定义结构体对象,初始化UartHost成员,调用核心层UartAddDev函数,完成UART控制器的添加,接入VFS。 + + ```c int32_t HdfUartDeviceInit(struct HdfDeviceObject *device) { int32_t ret; struct UartHost *host = NULL; HDF_LOGI("%s: entry", __func__); ... - host = UartHostFromDevice(device);// 通过service成员后强制转为UartHost,赋值是在Bind函数中。 - ... - ret = Hi35xxAttach(host, device); // 完成UartHost对象的初始化,见下。 - ... - host->method = &g_uartHostMethod; // UartHostMethod的实例化对象的挂载。 + host = UartHostFromDevice(device); // 通过service成员后强制转为UartHost,赋值是在Bind函数中 + ... + ret = Hi35xxAttach(host, device); // 完成UartHost对象的初始化,见下 + ... + host->method = &g_uartHostMethod; // UartHostMethod的实例化对象的挂载 return ret; } // 完成UartHost对象的初始化。 static int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device) { int32_t ret; - // udd和port对象是厂商自定义的结构体对象,可根据需要实现相关功能。 - struct UartDriverData *udd = NULL; + struct UartDriverData *udd = NULL; // udd和port对象是驱动适配者自定义的结构体对象,可根据需要实现相关功能 struct UartPl011Port *port = NULL; ... // 【必要】步骤【1】~【7】主要实现对udd对象的实例化赋值,然后赋值给核心层UartHost对象。 - udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));//【1】 + udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd)); // 【1】 ... - port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));//【2】 + port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port)); // 【2】 ... - udd->ops = Pl011GetOps(); // 【3】设备开启、关闭、属性设置、发送操作等函数挂载。 - udd->recv = PL011UartRecvNotify;// 【4】数据接收通知函数(条件锁机制)挂载 - udd->count = 0; // 【5】 - port->udd = udd; // 【6】使UartPl011Port与UartDriverData可以相互转化的前提 - ret = UartGetConfigFromHcs(port, device->property);// 将HdfDeviceObject的属性传递给厂商自定义结构体 - // 用于相关操作,示例代码见下 + udd->ops = Pl011GetOps(); // 【3】设备开启、关闭、属性设置、发送操作等函数挂载。 + udd->recv = PL011UartRecvNotify; // 【4】数据接收通知函数(条件锁机制)挂载 + udd->count = 0; // 【5】 + port->udd = udd; // 【6】使UartPl011Port与UartDriverData可以相互转化的前提 + ret = UartGetConfigFromHcs(port, device->property); // 将HdfDeviceObject的属性传递给驱动适配者自定义结构体,用于相关操作,示例代码见下 ... - udd->private = port; //【7】 - - host->priv = udd; // 【必要】使UartHost与UartDriverData可以相互转化的前提 - host->num = udd->num; // 【必要】UART设备号 - UartAddDev(host); // 【必要】核心层uart_dev.c中的函数,作用:注册一个字符设备节点到vfs,这样从用户态可以通过这个虚拟文件节点访问UART。 + udd->private = port; // 【7】 + host->priv = udd; // 【必要】使UartHost与UartDriverData可以相互转化的前提 + host->num = udd->num; // 【必要】UART设备号 + UartAddDev(host); // 【必要】核心层uart_dev.c中的函数,作用:注册一个字符设备节点到vfs,这样从用户态可以通过这个虚拟文件节点访问UART return HDF_SUCCESS; } @@ -352,7 +383,7 @@ UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置 struct UartDriverData *udd = port->udd; struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); ... - // 通过请求参数提取相应的值,并赋值给厂商自定义的结构体。 + // 通过请求参数提取相应的值,并赋值给驱动适配者自定义的结构体。 if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) { HDF_LOGE("%s: read busNum fail", __func__); return HDF_FAILURE; @@ -361,11 +392,12 @@ UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置 return 0; } ``` - - Release函数参考 + + - Release函数开发参考 入参: - HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: @@ -378,18 +410,17 @@ UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置 > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。 - - ``` + ```c void HdfUartDeviceRelease(struct HdfDeviceObject *device) { struct UartHost *host = NULL; ... - host = UartHostFromDevice(device);// 这里有HdfDeviceObject到UartHost的强制转化,通过service成员,赋值见Bind函数。 - ... - if (host->priv != NULL) { - Hi35xxDetach(host); // 厂商自定义的内存释放函数,见下。 - } - UartHostDestroy(host); // 调用核心层函数释放host + host = UartHostFromDevice(device); // 这里有HdfDeviceObject到UartHost的强制转化,通过service成员,赋值见Bind函数。 + ... + if (host->priv != NULL) { + Hi35xxDetach(host); // 驱动适配自定义的内存释放函数,见下。 + } + UartHostDestroy(host); // 调用核心层函数释放host } static void Hi35xxDetach(struct UartHost *host) @@ -397,18 +428,22 @@ UART模块适配HDF框架的三个必选环节是实例化驱动入口,配置 struct UartDriverData *udd = NULL; struct UartPl011Port *port = NULL; ... - udd = host->priv; // 这里有UartHost到UartDriverData的转化 - ... - UartRemoveDev(host); // VFS注销 - port = udd->private; // 这里有UartDriverData到UartPl011Port的转化 - if (port != NULL) { - if (port->physBase != 0) { - OsalIoUnmap((void *)port->physBase);// 地址反映射 + udd = host->priv; // 这里有UartHost到UartDriverData的转化 + ... + UartRemoveDev(host); // VFS注销 + port = udd->private; // 这里有UartDriverData到UartPl011Port的转化 + if (port != NULL) { + if (port->physBase != 0) { + OsalIoUnmap((void *)port->physBase); // 地址反映射 } OsalMemFree(port); udd->private = NULL; } - OsalMemFree(udd); // 释放UartDriverData + OsalMemFree(udd); // 释放UartDriverData host->priv = NULL; } ``` + +4. 驱动调试。 + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。 \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-watchdog-des.md b/zh-cn/device-dev/driver/driver-platform-watchdog-des.md index 6f17e2593688016478c86da65f680a59e1ad4dcd..09a16a81fb094c6d65f7a4f1dbae1104f879480b 100644 --- a/zh-cn/device-dev/driver/driver-platform-watchdog-des.md +++ b/zh-cn/device-dev/driver/driver-platform-watchdog-des.md @@ -1,284 +1,296 @@ # Watchdog - ## 概述 -看门狗(Watchdog),又叫看门狗计时器(Watchdog timer),是一种硬件的计时设备。当系统主程序发生错误导致未及时清除看门狗计时器的计时值时,看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 +### 功能简介 +看门狗(Watchdog),又称看门狗计时器(Watchdog timer),是一种硬件计时设备。一般有一个输入,叫做喂狗,一个输出到系统的复位端。当系统主程序发生错误导致未及时清除看门狗计时器的计时值时,看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 -## 接口说明 +Watchdog接口定义了看门狗操作的通用方法集合,包括: - **表1** 看门狗API接口功能介绍 +- 打开/关闭看门狗设备 +- 启动/停止看门狗设备 +- 设置/获取看门狗设备超时时间 +- 获取看门狗设备状态 +- 喂狗 -| 接口 | 接口描述 | -| -------- | -------- | -| WatchdogOpen | 打开看门狗 | -| WatchdogClose | 关闭看门狗 | -| WatchdogStart | 启动看门狗 | -| WatchdogStop | 停止看门狗 | -| WatchdogSetTimeout | 设置看门狗超时时间 | -| WatchdogGetTimeout | 获取看门狗超时时间 | -| WatchdogGetStatus | 获取看门狗状态 | -| WatchdogFeed | 清除看门狗定时器(喂狗) | +### 基本概念 -> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
-> 本文涉及的看门狗的所有接口,仅限内核态使用,不支持在用户态使用。 +系统正常工作的时候,每隔一段时间输出一个信号到喂狗端,给看门狗清零,这个操作就叫做喂狗。如果超过规定的时间不喂狗,看门狗定时超时,就会给出一个复位信号到系统,使系统复位。 +### 运作机制 -## 使用指导 +在HDF框架中,Watchdog模块接口适配模式采用独立服务模式,如图1所示。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: -### 使用流程 +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 -使用看门狗的一般流程如下图所示。 +Watchdog模块各分层作用: - **图1** 看门狗使用流程图 +- 接口层提供打开看门狗设备、获取看门狗设备状态、启动看门狗设备、设置看门狗设备超时时间、获取看门狗设备超时时间、喂狗、停止看门狗设备超时时间、关闭看门狗设备的接口。 +- 核心层主要提供看门狗控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 - ![image](figures/看门狗使用流程图.png "看门狗使用流程图") +**图 1** Watchdog独立服务模式结构图 +![image1](figures/独立服务模式结构图.png "Watchdog独立服务模式结构图") -### 打开看门狗设备 +## 使用指导 -在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: +### 场景介绍 +对于无法直接观测到的软件异常,我们可以使用看门狗进行自动检测,并在异常产生时及时重置。 -``` -DevHandle WatchdogOpen(int16_t wdtId); -``` +### 接口说明 + +Watchdog模块提供的主要接口如表1所示。 - **表2** WatchdogOpen参数和返回值描述 +**表1** 看门狗API接口功能介绍 -| **参数** | **参数描述** | +| 接口名 | 描述 | | -------- | -------- | -| wdtId | 看门狗设备号 | -| **返回值** | **返回值描述** | -| NULL | 打开失败 | -| DevHandle类型指针 | 看门狗设备句柄 | +| int32_t WatchdogOpen(int16_t wdtId, DevHandle *handle) | 打开看门狗 | +| void WatchdogClose(DevHandle handle) | 关闭看门狗 | +| int32_t WatchdogStart(DevHandle handle) | 启动看门狗 | +| int32_t WatchdogStop(DevHandle handle) | 停止看门狗 | +| int32_t WatchdogSetTimeout(DevHandle handle, uint32_t seconds) | 设置看门狗超时时间 | +| int32_t WatchdogGetTimeout(DevHandle handle, uint32_t *seconds) | 获取看门狗超时时间 | +| int32_t WatchdogGetStatus(DevHandle handle, int32_t *status) | 获取看门狗状态 | +| int32_t WatchdogFeed(DevHandle handle) | 清除看门狗定时器(喂狗) | +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+> 本文涉及的看门狗的所有接口,支持内核态及用户态使用。 -``` -DevHandle handle = NULL; -handle = WatchdogOpen(0); /* 打开0号看门狗设备 */ -if (handle == NULL) { - HDF_LOGE("WatchdogOpen: failed, ret %d\n", ret); - return; -} +### 开发步骤 + +使用看门狗的一般流程如下图所示。 + +**图2** 看门狗使用流程图 + +![image2](figures/看门狗使用流程图.png "看门狗使用流程图") + +#### 打开看门狗设备 + +在操作看门狗之前,需要调用WatchdogOpen打开看门狗设备,一个系统可能有多个看门狗,通过看门狗ID号来打开指定的看门狗设备: + +```c +DevHandle WatchdogOpen(int16_t wdtId, DevHandle *handle); ``` +**表2** WatchdogOpen参数和返回值描述 -### 获取看门狗状态 +| **参数** | **参数描述** | +| -------- | -------- | +| wdtId | 看门狗设备号 | +| handle | 看门狗设备句柄 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 打开看门狗设备成功 | +| 负数 | 打开看门狗设备失败 | +```c +int16_t wdtId = 0; +int32_t ret; +DevHandle *handle = NULL; +ret = WatchdogOpen(wdtId, handle); // 打开0号看门狗设备 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogOpen: open watchdog_%hd failed, ret:%d\n", wdtId, ret); + return ret; +} ``` + +#### 获取看门狗状态 + +```c int32_t WatchdogGetStatus(DevHandle handle, int32_t *status); ``` - **表3** WatchdogGetStatus参数和返回值描述 +**表3** WatchdogGetStatus参数和返回值描述 | **参数** | **参数描述** | | -------- | -------- | | handle | 看门狗设备句柄 | -| status | 获取到的看门狗状态的指针 | +| status | 获取到的看门狗状态 | | **返回值** | **返回值描述** | -| 0 | 获取成功 | -| 负数 | 获取失败 | +| HDF_SUCCESS | 获取看门狗状态成功 | +| 负数 | 获取看门狗状态失败 | - -``` +```c int32_t ret; int32_t status; -/* 获取Watchdog启动状态 */ -ret = WatchdogGetStatus(handle, &status); -if (ret != 0) { - HDF_LOGE("WatchdogGetStatus: failed, ret %d\n", ret); - return; + +ret = WatchdogGetStatus(handle, &status); // 获取Watchdog状态 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogGetStatus: watchdog get status failed, ret:%d\n", ret); + return ret; } ``` - -### 设置超时时间 +#### 设置超时时间 -``` +```c int32_t WatchdogSetTimeout(DevHandle *handle, uint32_t seconds); ``` - **表4** WatchdogSetTimeout参数和返回值描述 +**表4** WatchdogSetTimeout参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | -| seconds | 超时时间,单位为秒 | -| **返回值** | **返回值描述** | -| 0 | 设置成功 | -| 负数 | 设置失败 | - +| handle | 看门狗设备句柄 | +| seconds | 超时时间,单位为秒 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 设置成功 | +| 负数 | 设置失败 | -``` +```c int32_t ret; -uint32_t timeOut = 60; -/* 设置超时时间,单位:秒 */ -ret = WatchdogSetTimeout(handle, timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogSetTimeout: failed, ret %d\n", ret); - return; + +ret = WatchdogSetTimeout(handle, 2); // 设置超时时间2秒 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogSetTimeout: watchdog set timeOut failed, ret:%d\n", ret); + return ret; } ``` +#### 获取超时时间 -### 获取超时时间 - - -``` +```c int32_t WatchdogGetTimeout(DevHandle *handle, uint32_t *seconds); ``` - **表5** WatchdogGetTimeout参数和返回值描述 +**表5** WatchdogGetTimeout参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | -| seconds | 接收超时时间的指针,单位为秒 | -| **返回值** | **返回值描述** | -| 0 | 获取成功 | -| 负数 | 获取失败 | +| handle | 看门狗设备句柄 | +| seconds | 获取的看门狗超时时间 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 获取看门狗超时时间成功 | +| 负数 | 获取看门狗超时时间失败 | +```c + int32_t ret; + uint32_t timeOut; + ret = WatchdogGetTimeout(handle, &timeOut); // 获取超时时间 + if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogGetTimeout: watchdog get timeOut failed, ret:%d\n", ret); + return ret; + } ``` -int32_t ret; -uint32_t timeOut; -/* 获取超时时间,单位:秒 */ -ret = WatchdogGetTimeout(handle, &timeOut); -if (ret != 0) { - HDF_LOGE("WatchdogGetTimeout: failed, ret %d\n", ret); - return; -} -``` - -### 启动看门狗 +#### 启动看门狗 - -``` +```c int32_t WatchdogStart(DevHandle handle); ``` - **表6** WatchdogStart参数和返回值描述 +**表6** WatchdogStart参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | -| **返回值** | **返回值描述** | -| 0 | 启动成功 | -| 负数 | 启动失败 | - +| handle | 看门狗设备句柄 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 启动看门狗成功 | +| 负数 | 启动看门狗失败 | -``` +```c int32_t ret; -/* 启动看门狗 */ -ret = WatchdogStart(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStart: failed, ret %d\n", ret); - return; + +ret = WatchdogStart(handle); // 启动看门狗 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogStart: start watchdog failed, ret:%d\n", ret); + return ret; } ``` +#### 喂狗 -### 喂狗 - - -``` +```c int32_t WatchdogFeed(DevHandle handle); ``` - **表7** WatchdogFeed参数和返回值描述 +**表7** WatchdogFeed参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | -| **返回值** | **返回值描述** | -| 0 | 喂狗成功 | -| 负数 | 喂狗失败 | - +| handle | 看门狗设备句柄 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 喂狗成功 | +| 负数 | 喂狗失败 | -``` +```c int32_t ret; -/* 喂狗 */ -ret = WatchdogFeed(handle); -if (ret != 0) { - HDF_LOGE("WatchdogFeed: failed, ret %d\n", ret); - return; + +ret = WatchdogFeed(handle); // 喂狗 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogFeed: feed watchdog failed, ret:%d\n", ret); + return ret; } ``` +#### 停止看门狗 -### 停止看门狗 - - -``` +```c int32_t WatchdogStop(DevHandle handle); ``` - **表8** WatchdogStop参数和返回值描述 +**表8** WatchdogStop参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | -| **返回值** | **返回值描述** | -| 0 | 停止成功 | -| 负数 | 停止失败 | - +| handle | 看门狗设备句柄 | +| **返回值** | **返回值描述** | +| HDF_SUCCESS | 停止看门狗成功 | +| 负数 | 停止看门狗失败 | -``` +```c int32_t ret; -/* 停止看门狗 */ -ret = WatchdogStop(handle); -if (ret != 0) { - HDF_LOGE("WatchdogStop: failed, ret %d\n", ret); - return; + +ret = WatchdogStop(handle); // 停止看门狗 +if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogStop: stop watchdog failed, ret:%d\n", ret); + return ret; } ``` +#### 关闭看门狗设备 -### 关闭看门狗设备 - -当操作完毕时,使用WatchdogClose关闭打开的设备句柄: +当所有操作完毕后,调用WatchdogClose关闭打开的看门狗设备: - -``` +```c void WatchdogClose(DevHandle handle); ``` - **表9** WatchdogClose参数和返回值描述 +**表9** WatchdogClose参数和返回值描述 -| **参数** | **参数描述** | +| **参数** | **参数描述** | | -------- | -------- | -| handle | 看门狗设备句柄 | - +| handle | 看门狗设备句柄 | -``` -/* 关闭看门狗 */ -ret = WatchdogClose(handle); +```c +WatchdogClose(handle); // 关闭看门狗 ``` - ## 使用实例 -本例程提供看门狗的完整使用流程。 - -在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: +下面将基于Hi3516DV300开发板展示使用Watchdog完整操作,步骤主要如下: -- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 +1. 传入看门狗ID号,及空的描述句柄,打开看门狗设备并获得看门狗设备句柄。 +2. 通过看门狗设备句柄及超时时间,设置看门狗设备超时时间。 +3. 通过看门狗设备句柄及待获取超时时间,获取看门狗设备超时时间。 +4. 通过看门狗设备句柄启动看门狗设备。 +5. 通过看门狗设备句柄喂狗。 +6. 通过看门狗设备句柄停止看门狗设备。 +7. 通过看门狗设备句柄关闭看门狗设备。 -- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。 - - 示例如下: - -``` -#include "watchdog_if.h" -#include "hdf_log.h" -#include "osal_irq.h" -#include "osal_time.h" +```c +#include "watchdog_if.h" /* watchdog标准接口头文件 */ +#include "hdf_log.h" /* 标准日志打印头文件 */ +#include "osal_time.h" /* 标准延迟&睡眠接口头文件 */ #define WATCHDOG_TEST_TIMEOUT 2 #define WATCHDOG_TEST_FEED_TIME 6 @@ -287,14 +299,16 @@ static int32_t TestCaseWatchdog(void) { int32_t i; int32_t ret; + int16_t wdtId = 0; + int32_t status; uint32_t timeout; - DevHandle handle = NULL; + DevHandle *handle = NULL; /* 打开0号看门狗设备 */ - handle = WatchdogOpen(0); - if (handle == NULL) { - HDF_LOGE("Open watchdog failed!"); - return -1; + ret = WatchdogOpen(wdtId, handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("WatchdogOpen: open watchdog_%hd failed, ret:%d\n", wdtId, ret); + return ret; } /* 设置超时时间 */ @@ -305,13 +319,19 @@ static int32_t TestCaseWatchdog(void) return ret; } - /* 回读设置的超时时间值 */ + /* 获取超时时间 */ ret = WatchdogGetTimeout(handle, &timeout); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: get timeout fail! ret:%d\n", __func__, ret); WatchdogClose(handle); return ret; } + /* 比较设置与获取的超时时间是否一致*/ + if (timeout != WATCHDOG_TEST_TIMEOUT) { + HDF_LOGE("%s: set:%u, but get:%u", __func__, WATCHDOG_TEST_TIMEOUT, timeout); + WatchdogClose(handle); + return HDF_FAILURE; + } HDF_LOGI("%s: read timeout back:%u\n", __func__, timeout); /* 启动看门狗,开始计时 */ @@ -321,6 +341,19 @@ static int32_t TestCaseWatchdog(void) WatchdogClose(handle); return ret; } + /* 获取看门狗状态,是否启动*/ + status = WATCHDOG_STOP; + ret = WatchdogGetStatus(handle, &status); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get status fail! ret:%d", __func__, ret); + WatchdogClose(handle); + return ret; + } + if (status != WATCHDOG_START) { + HDF_LOGE("%s: status is:%d after start", __func__, status); + WatchdogClose(handle); + return HDF_FAILURE; + } /* 每隔1S喂狗一次 */ for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { @@ -336,15 +369,26 @@ static int32_t TestCaseWatchdog(void) /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ HDF_LOGI("%s: no reset ... feeding test OK!!!\n", __func__); - /* 接下来持续不喂狗,使得看门狗计时器超时 */ - for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { - HDF_LOGI("%s: waiting dog buck %d times... \n", __func__, i); - OsalSleep(1); + ret = WatchdogStop(handle); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: stop fail! ret:%d", __func__, ret); + WatchdogClose(handle); + return ret; + } + /* 获取看门狗状态,是否停止*/ + status = WATCHDOG_START; + ret = WatchdogGetStatus(handle, &status); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: get status fail! ret:%d", __func__, ret); + WatchdogClose(handle); + return ret; + } + if (status != WATCHDOG_STOP) { + HDF_LOGE("%s: status is:%d after stop", __func__, status); + WatchdogClose(handle); + return HDF_FAILURE; } - - /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ - HDF_LOGI("%s: dog hasn't back!!! \n", __func__, i); WatchdogClose(handle); - return -1; + return HDF_SUCCESS; } -``` +``` \ No newline at end of file diff --git a/zh-cn/device-dev/driver/driver-platform-watchdog-develop.md b/zh-cn/device-dev/driver/driver-platform-watchdog-develop.md index 6062164ef459b842f01b316bffe88a9b74d98a1e..95f0816254de45d7855ebd9f7e7fab10eaa80aad 100755 --- a/zh-cn/device-dev/driver/driver-platform-watchdog-develop.md +++ b/zh-cn/device-dev/driver/driver-platform-watchdog-develop.md @@ -1,230 +1,254 @@ # Watchdog - ## 概述 -看门狗(Watchdog),又叫看门狗计时器(Watchdog timer),是一种硬件的计时设备。在HDF框架中,Watchdog接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 +### 功能简介 + +看门狗(Watchdog),又称看门狗计时器(Watchdog timer),是一种硬件计时设备。一般有一个输入,叫做喂狗,一个输出到系统的复位端。当系统主程序发生错误导致未及时清除看门狗计时器的计时值时,看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。 + +### 基本概念 + +系统正常工作的时候,每隔一段时间输出一个信号到喂狗端,给看门狗清零,这个操作就叫做喂狗。如果超过规定的时间不喂狗,看门狗定时超时,就会给出一个复位信号到系统,使系统复位。 + +### 运作机制 + +在HDF框架中,Watchdog接口适配模式采用独立服务模式(如图1所示)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDF设备管理器的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 + +独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为: + +- 驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。 +- device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。 + +Watchdog模块各分层作用: + +- 接口层提供打开看门狗设备、获取看门狗设备状态、启动看门狗设备、设置看门狗设备超时时间、获取看门狗设备超时时间、喂狗、停止看门狗设备超时时间、关闭看门狗设备的接口。 +- 核心层主要提供看门狗控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。 +- 适配层主要是将钩子函数的功能实例化,实现具体的功能。 + +**图 1** Watchdog独立服务模式结构图 + +![image](figures/独立服务模式结构图.png "Watchdog独立服务模式结构图") + +## 开发指导 - **图1** Watchdog独立服务模式结构图 +### 场景介绍 - ![image](figures/独立服务模式结构图.png "Watchdog独立服务模式结构图") +对于无法直接观测到的软件异常,我们可以使用看门狗进行自动检测,并在异常产生时及时重置。当驱动开发者需要将Watchdog设备适配到OpenHarmony时,需要进行Watchdog驱动适配。下文将介绍如何进行Watchdog驱动适配。 +### 接口说明 -## 接口说明 +为了保证上层在调用Watchdog接口时能够正确的操作Watchdog控制器,核心层在//drivers/hdf_core/framework/support/platform/include/watchdog/watchdog_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 WatchdogMethod定义: - -``` +```c struct WatchdogMethod { - int32_t (*getStatus)(struct WatchdogCntlr *wdt, int32_t *status); - int32_t (*setTimeout)(struct WatchdogCntlr *wdt, uint32_t seconds); - int32_t (*getTimeout)(struct WatchdogCntlr *wdt, uint32_t *seconds); - int32_t (*start)(struct WatchdogCntlr *wdt); - int32_t (*stop)(struct WatchdogCntlr *wdt); - int32_t (*feed)(struct WatchdogCntlr *wdt); - int32_t (*getPriv)(struct WatchdogCntlr *wdt); //【可选】如果WatchdogCntlr中的priv成员存在,则按需实例化 - void (*releasePriv)(struct WatchdogCntlr *wdt);//【可选】 + int32_t (*getStatus)(struct WatchdogCntlr *wdt, int32_t *status); + int32_t (*setTimeout)(struct WatchdogCntlr *wdt, uint32_t seconds); + int32_t (*getTimeout)(struct WatchdogCntlr *wdt, uint32_t *seconds); + int32_t (*start)(struct WatchdogCntlr *wdt); + int32_t (*stop)(struct WatchdogCntlr *wdt); + int32_t (*feed)(struct WatchdogCntlr *wdt); + int32_t (*getPriv)(struct WatchdogCntlr *wdt); // 【可选】如果WatchdogCntlr中的priv成员存在,则按需实例化 + void (*releasePriv)(struct WatchdogCntlr *wdt); // 【可选】 }; ``` - **表1** WatchdogMethod成员的回调函数功能说明 +**表1** WatchdogMethod成员的钩子函数功能说明 -| 成员函数 | 入参 | 出参 | 返回值 | 功能 | +| 成员函数 | 入参 | 出参 | 返回值 | 功能 | | -------- | -------- | -------- | -------- | -------- | -| getStatus | wdt:结构体指针,核心层WDG控制器 | status:int32_t指针,表示狗的状态(打开或关闭) | HDF_STATUS相关状态 | 获取看门狗所处的状态 | -| start | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 打开看门狗 | -| stop | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 关闭看门狗 | -| setTimeout | wdt:结构体指针,核心层WDG控制器;seconds:时间传入值 | 无 | HDF_STATUS相关状态 | 设置看门狗超时时间,单位秒,需要保证看门狗实际运行的时间符合该值 | -| getTimeout | wdt:结构体指针,核心层WDG控制器 | seconds:uint32_t指针,传出的时间值 | HDF_STATUS相关状态 | 回读设置的超时时间值 | -| feed | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 喂狗 | -| getPriv | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 获取看门狗驱动的私有数据 | -| releasePriv | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 释放看门狗驱动的私有数据 | - -## 开发步骤 - -Watchdog模块适配HDF框架的四个环节是实例化驱动入口,配置属性文件,实例化Watchdog控制器对象以及驱动调试。 - -1. **实例化驱动入口:** - - 实例化HdfDriverEntry结构体成员。 - - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 - -2. **配置属性文件:** - - 在device_info.hcs文件中添加deviceNode描述。 - - 【可选】添加watchdog_config.hcs器件属性文件。 - -3. **实例化Watchdog控制器对象:** - - 初始化WatchdogCntlr成员。 - - 实例化WatchdogCntlr成员WatchdogMethod。 - > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
- > 实例化WatchdogCntlr成员WatchdogMethod,其定义和成员说明见[接口说明](#接口说明)。 - -4. **驱动调试:** - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,超时时间设置的成功与否等。 - - -## 开发实例 - -下方将以watchdog_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 - -1. 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 - 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - - Watchdog驱动入口参考: - - ``` - struct HdfDriverEntry g_watchdogDriverEntry = { - .moduleVersion = 1, - .Bind = Hi35xxWatchdogBind, // 见Bind参考 - .Init = Hi35xxWatchdogInit, // 见Init参考 - .Release = Hi35xxWatchdogRelease, // 见Release参考 - .moduleName = "HDF_PLATFORM_WATCHDOG",// 【必要且与HCS文件中里面的moduleName匹配】 - }; - HDF_INIT(g_watchdogDriverEntry);// 调用HDF_INIT将驱动入口注册到HDF框架中 - ``` - -2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在 watchdog_config.hcs 中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层WatchdogCntlr 成员的默认值或限制范围有密切关系。 - 本例只有一个Watchdog控制器,如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在watchdog_config文件中增加对应的器件属性。 +| getStatus | wdt:结构体指针,核心层Watchdog控制器 | status:int32_t类型指针,表示获取的看门狗的状态(打开或关闭) | HDF_STATUS相关状态 | 获取看门狗状态 | +| setTimeout | wdt:结构体指针,核心层Watchdog控制器;seconds:设置的看门狗超时时间 | 无 | HDF_STATUS相关状态 | 设置看门狗超时时间,单位秒,需要保证看门狗实际运行的时间符合该值 | +| getTimeout | wdt:结构体指针,核心层Watchdog控制器 | seconds:uint32_t类型指针,表示获取的超时时间 | HDF_STATUS相关状态 | 获取看门狗超时时间 | +| start | wdt:结构体指针,核心层Watchdog控制器 | 无 | HDF_STATUS相关状态 | 启动看门狗 | +| stop | wdt:结构体指针,核心层Watchdog控制器 | 无 | HDF_STATUS相关状态 | 停止看门狗 | +| feed | wdt:结构体指针,核心层Watchdog控制器 | 无 | HDF_STATUS相关状态 | 喂狗 | +| getPriv | wdt:结构体指针,核心层Watchdog控制器 | 无 | HDF_STATUS相关状态 | 获取看门狗驱动的私有数据 | +| releasePriv | wdt:结构体指针,核心层Watchdog控制器 | 无 | HDF_STATUS相关状态 | 释放看门狗驱动的私有数据 | + +### 开发步骤 + +Watchdog模块适配包含以下四个步骤: + +- 实例化驱动入口。 +- 配置属性文件。 +- 实例化Watchdog控制器对象。 +- 驱动调试。 + +### 开发实例 + +下方将基于Hi3516DV300开发板以//device_soc_hisilicon/common/platform/watchdog/watchdog_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。 + +1. 实例化驱动入口。 + + 驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 + 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + + Watchdog驱动入口开发参考: + + ```c + struct HdfDriverEntry g_watchdogDriverEntry = { + .moduleVersion = 1, + .Bind = Hi35xxWatchdogBind, // 见Bind参考 + .Init = Hi35xxWatchdogInit, // 见Init参考 + .Release = Hi35xxWatchdogRelease, // 见Release参考 + .moduleName = "HDF_PLATFORM_WATCHDOG", // 【必要且与HCS文件中里面的moduleName匹配】 + }; + HDF_INIT(g_watchdogDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中 + ``` + +2. 配置属性文件。 + + 完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode描述。deviceNode信息与驱动入口注册相关。本例以一个Watchdog控制器为例,如有多个器件信息,则需要在device_info文件增加对应的deviceNode描述。器件属性值与核心层WatchdogCntlr成员的默认值或限制范围有密切关系,比如Watchdog设备号,需要在watchdog_config.hcs文件中增加对应的器件属性。 + - device_info.hcs 配置参考: - - - ``` - root { - device_info { - match_attr = "hdf_manager"; - device_watchdog :: device { // 设备节点 - device0 :: deviceNode { // 驱动的DeviceNode节点 - policy = 1; // policy字段是驱动服务发布的策略,如果需要面向用户态,则为2 - priority = 20; // 驱动启动优先级 - permission = 0644; // 驱动创建设备节点权限 - moduleName = "HDF_PLATFORM_WATCHDOG"; - // 【必要】驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 - serviceName = "HDF_PLATFORM_WATCHDOG_0"; - // 【必要且唯一】驱动对外发布服务的名称 - deviceMatchAttr = "hisilicon_hi35xx_watchdog_0"; - // 【必要】驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 - } - } - } - } - ``` - + + 在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。 + + ```c + root { + device_info { + match_attr = "hdf_manager"; + device_watchdog :: device { // 设备节点 + device0 :: deviceNode { // 驱动的DeviceNode节点 + policy = 2; // policy字段是驱动服务发布的策略,如果需要面向用户态,则为2 + priority = 20; // 驱动启动优先级 + permission = 0644; // 驱动创建设备节点权限 + moduleName = "HDF_PLATFORM_WATCHDOG"; // 【必要】用于指定驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 + serviceName = "HDF_PLATFORM_WATCHDOG_0"; // 【必要】驱动对外发布服务的名称,必须唯一。 + deviceMatchAttr = "hisilicon_hi35xx_watchdog_0"; // 【必要】用于配置控制器私有数据,必须和驱动私有数据配置表watchdog_config.hcs中的match_attr值保持一致。 + } + } + } + } + ``` + - watchdog_config.hcs 配置参考: - - - ``` - root { - platform { - template watchdog_controller {// 【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省 - id = 0; - match_attr = ""; - regBase = 0x12050000; // 【必要】地址映射需要 - regStep = 0x1000; // 【必要】地址映射需要 - } - controller_0x12050000 :: watchdog_controller {// 【必要】是作为设备驱动私有数据匹配的关键字 - match_attr = "hisilicon_hi35xx_watchdog_0"; // 【必要】必须和device_info.hcs中的deviceMatchAttr值一致 - } - //存在多个 watchdog 时【必须】添加,否则不用 - ... - } - } - ``` - -3. 完成驱动入口注册之后,最后一步就是以核心层WatchdogCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化WatchdogCntlr成员WatchdogMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 - - 自定义结构体参考。 - - 从驱动的角度看,自定义结构体是参数和数据的载体,而且watchdog_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层WatchdogCntlr对象,例如索引、管脚数等。 - - + + 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/watchdog/watchdog_config.hcs文件配置器件属性,其中配置参数如下: + + ```c + root { + platform { + template watchdog_controller { // 【必要】配置模板,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值 + id = 0; // watchdog ID号 + match_attr = ""; + regBase = 0x12050000; // 【必要】地址映射需要,物理基地址 + regStep = 0x1000; // 【必要】地址映射需要,寄存器偏移步进 + } + controller_0x12050000 :: watchdog_controller { // 【必要】是作为设备驱动私有数据匹配的关键字 + match_attr = "hisilicon_hi35xx_watchdog_0"; // 【必要】必须和device_info.hcs中的deviceMatchAttr值一致 + } + // 如果存在多个watchdog设备时【必须】添加节点,否则不用 + ... + } + } ``` + + 需要注意的是,新增watchdog_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。 + + ```c + #include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/watchdog/watchdog_config.hcs" // 配置文件相对路径 + ``` + +3. 实例化Watchdog控制器对象。 + + 完成驱动入口注册之后,下一步就是以核心层WatchdogCntlr对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化WatchdogCntlr成员WatchdogMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 + + - 驱动适配者自定义结构体参考。 + + 从驱动的角度看,驱动适配者自定义结构体是参数和数据的载体,而且watchdog_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层WatchdogCntlr对象,例如watchdog设备ID号。 + + ```c struct Hi35xxWatchdog { - struct WatchdogCntlr wdt; // 【必要】是链接上下层的载体,具体描述见下面 - OsalSpinlock lock; - volatile unsigned char *regBase;// 【必要】地址映射需要 - uint32_t phyBase; // 【必要】地址映射需要 - uint32_t regStep; // 【必要】地址映射需要 + struct WatchdogCntlr wdt; // 【必要】是核心层控制对象,具体描述见下面 + OsalSpinlock lock; // 【必要】驱动适配者需要基于此锁变量对watchdog设备实现对应的加锁解锁 + volatile unsigned char *regBase; // 【必要】地址映射需要,寄存器基地址 + uint32_t phyBase; // 【必要】地址映射需要,物理基址 + uint32_t regStep; // 【必要】地址映射需要,寄存器偏移步进 }; - //WatchdogCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值 - struct WatchdogCntlr { - struct IDeviceIoService service;// 驱动服务 - struct HdfDeviceObject *device; // 驱动设备 - OsalSpinlock lock; // 此变量在HDF核心层被调用来实现自旋锁功能 - struct WatchdogMethod *ops; // 接口回调函数 - int16_t wdtId; // WDG设备的识别id - void *priv; // 存储指针 + + struct WatchdogCntlr { // WatchdogCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值。 + struct IDeviceIoService service; // 驱动服务 + struct HdfDeviceObject *device; // 驱动设备对象 + OsalSpinlock lock; // 自旋锁 + struct WatchdogMethod *ops; // 钩子函数 + int16_t wdtId; // watchdog设备ID号 + void *priv; // 私有数据 }; ``` - - WatchdogCntlr成员回调函数结构体WatchdogMethod的实例化,其他成员在Init和Bind函数中初始化。 - - ``` - static struct WatchdogMethod g_method = { - .getStatus = Hi35xxWatchdogGetStatus, - .start = Hi35xxWatchdogStart, - .stop = Hi35xxWatchdogStop, - .setTimeout = Hi35xxWatchdogSetTimeout, - .getTimeout = Hi35xxWatchdogGetTimeout, - .feed = Hi35xxWatchdogFeed, + - WatchdogCntlr成员钩子函数结构体WatchdogMethod的实例化,其他成员在Init和Bind函数中初始化。 + + ```c + static struct WatchdogMethod g_method = { // 钩子函数实例化 + .getStatus = Hi35xxWatchdogGetStatus, // 获取看门狗状态 + .start = Hi35xxWatchdogStart, // 启动看门狗 + .stop = Hi35xxWatchdogStop, // 停止看门狗 + .setTimeout = Hi35xxWatchdogSetTimeout, // 设置看门狗超时时间 + .getTimeout = Hi35xxWatchdogGetTimeout, // 获取看门狗超时时间 + .feed = Hi35xxWatchdogFeed, // 喂狗 }; ``` - - Init函数和Bind函数参考: + - Init函数和Bind函数开发参考: 入参: - HdfDeviceObject :HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 + HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。 返回值: - HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。 + HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/hdf_core/framework/include/utils/hdf_base.h中HDF_STATUS的定义)。 - **表2** Init函数和Bind函数返回值和描述 - - | 状态(值) | 问题描述 | + **表2** Init函数和Bind函数返回值和描述 + + | 状态(值) | 问题描述 | | -------- | -------- | - | HDF_ERR_INVALID_OBJECT | 找不到 WDG 设备 | - | HDF_ERR_MALLOC_FAIL | 内存分配失败 | - | HDF_ERR_IO | I/O 错误 | - | HDF_SUCCESS | 初始化成功 | - | HDF_FAILURE | 初始化失败 | + | HDF_ERR_INVALID_OBJECT | 控制器对象非法 | + | HDF_ERR_MALLOC_FAIL | 内存分配失败 | + | HDF_ERR_IO | I/O 错误 | + | HDF_SUCCESS | 初始化成功 | + | HDF_FAILURE | 初始化失败 | 函数说明: - 初始化自定义结构体对象,初始化WatchdogCntlr成员,调用核心层WatchdogCntlrAdd函数。 + 初始化自定义结构体对象,初始化WatchdogCntlr成员,调用核心层WatchdogCntlrAdd函数,完成看门狗控制器的添加。 - - ``` - //一般而言,Init函数需要根据入参(HdfDeviceObject对象)的属性值初始化Hi35xxWatchdog结构体的成员, - //但本例中是在bind函数中实现的 + ```c + // 一般而言,Init函数需要根据入参(HdfDeviceObject对象)的属性值初始化Hi35xxWatchdog结构体的成员, + // 但watchdog_hi35xx.c示例中是在bind函数中实现的 static int32_t Hi35xxWatchdogInit(struct HdfDeviceObject *device) { - (void)device; - return HDF_SUCCESS; + (void)device; + return HDF_SUCCESS; } - + static int32_t Hi35xxWatchdogBind(struct HdfDeviceObject *device) { - int32_t ret; - struct Hi35xxWatchdog *hwdt = NULL; - ... - hwdt = (struct Hi35xxWatchdog *)OsalMemCalloc(sizeof(*hwdt));//Hi35xxWatchdog 结构体的内存申请 - ... - hwdt->regBase = OsalIoRemap(hwdt->phyBase, hwdt->regStep); //地址映射 - ... - hwdt->wdt.priv = (void *)device->property;// 【可选】此处是将设备属性的内容赋值给priv成员,但后续没有调用 priv 成员, - // 如果需要用到priv成员,需要额外实例化WatchdogMethod的getPriv和releasePriv成员函数 - hwdt->wdt.ops = &g_method; // 【必要】将实例化后的对象赋值给ops成员,就可以实现顶层调用WatchdogMethod成员函数 - hwdt->wdt.device = device; // 【必要】这是为了方便HdfDeviceObject与WatchdogcCntlr相互转化 - ret = WatchdogCntlrAdd(&hwdt->wdt); // 【必要】调用此函数初始化核心层结构体,返回成功信号后驱动才完全接入平台核心层 - if (ret != HDF_SUCCESS) { // 不成功的话,需要释放Init函数申请的资源 - OsalIoUnmap((void *)hwdt->regBase); - OsalMemFree(hwdt); - return ret; - } - return HDF_SUCCESS; + int32_t ret; + struct Hi35xxWatchdog *hwdt = NULL; + ... + hwdt = (struct Hi35xxWatchdog *)OsalMemCalloc(sizeof(*hwdt)); //Hi35xxWatchdog 结构体指针的内存申请 + ... + hwdt->regBase = OsalIoRemap(hwdt->phyBase, hwdt->regStep); //地址映射 + ... + hwdt->wdt.priv = (void *)device->property; // 【必要】此处是将设备属性的内容赋值给priv成员,但后续没有调用 priv 成员, + // 如果需要用到priv成员,需要额外实例化WatchdogMethod的getPriv和releasePriv成员函数 + hwdt->wdt.ops = &g_method; // 【必要】WatchdogMethod实例化对象的挂载 + hwdt->wdt.device = device; // 【必要】这是为了方便HdfDeviceObject与WatchdogcCntlr相互转化 + ret = WatchdogCntlrAdd(&hwdt->wdt); // 【必要】调用此函数初始化核心层结构体,返回成功信号后驱动才完全接入平台核心层 + if (ret != HDF_SUCCESS) { // 不成功的话,需要去除映射并释放Init函数申请的资源 + OsalIoUnmap((void *)hwdt->regBase); + OsalMemFree(hwdt); + return ret; + } + return HDF_SUCCESS; } ``` - - Release函数参考: + + - Release函数开发参考: 入参: @@ -236,26 +260,29 @@ Watchdog模块适配HDF框架的四个环节是实例化驱动入口,配置属 函数说明: - 该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。 + 该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。 - - ``` + ```c static void Hi35xxWatchdogRelease(struct HdfDeviceObject *device) { - struct WatchdogCntlr *wdt = NULL; - struct Hi35xxWatchdog *hwdt = NULL; - ... - wdt = WatchdogCntlrFromDevice(device); // 这里会通过service成员将HdfDeviceObject转化为WatchdogCntlr - // return (device == NULL) ? NULL : (struct WatchdogCntlr *)device->service; - if (wdt == NULL) { - return; - } - WatchdogCntlrRemove(wdt); // 核心层函数,实际执行wdt->device->service = NULL以及cntlr->lock的释放 - hwdt = (struct Hi35xxWatchdog *)wdt; // 这里将WatchdogCntlr转化为HimciHost - if (hwdt->regBase != NULL) { // 解除地址映射 - OsalIoUnmap((void *)hwdt->regBase); - hwdt->regBase = NULL; - } - OsalMemFree(hwdt); // 释放厂商自定义对象占用的内存 + struct WatchdogCntlr *wdt = NULL; + struct Hi35xxWatchdog *hwdt = NULL; + ... + wdt = WatchdogCntlrFromDevice(device); // 【必要】通过device获取WatchdogCntlr + ... + if (wdt == NULL) { + return; + } + WatchdogCntlrRemove(wdt); // 【必要】调用WatchdogCntlrRemove函数来释放WatchdogCntlr对象的内容 + hwdt = (struct Hi35xxWatchdog *)wdt; // 这里将WatchdogCntlr转化为Hi35xxWatchdog + if (hwdt->regBase != NULL) { // 【必要】解除地址映射 + OsalIoUnmap((void *)hwdt->regBase); + hwdt->regBase = NULL; + } + OsalMemFree(hwdt); // 【必要】释放驱动适配者自定义对象占用的内存 } ``` + +4. 驱动调试。 + + 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。 \ No newline at end of file diff --git "a/zh-cn/device-dev/driver/figures/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" "b/zh-cn/device-dev/driver/figures/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" index 3fa26eb23a059deb997ae31f292a6fe5fc8e75b7..b1f2dd5cc0e8ba606118923b25cc456139efdcb9 100755 Binary files "a/zh-cn/device-dev/driver/figures/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" and "b/zh-cn/device-dev/driver/figures/\347\234\213\351\227\250\347\213\227\344\275\277\347\224\250\346\265\201\347\250\213\345\233\276.png" differ diff --git a/zh-cn/device-dev/reference/hdi-apis/Readme-CN.md b/zh-cn/device-dev/reference/hdi-apis/Readme-CN.md index eff04082dae1a611a07b61a2abadd589d061f604..2bd9d277227ef129572b18b0def810169c77b548 100644 --- a/zh-cn/device-dev/reference/hdi-apis/Readme-CN.md +++ b/zh-cn/device-dev/reference/hdi-apis/Readme-CN.md @@ -107,7 +107,7 @@ - [AudioDeviceDescriptor](_audio_device_descriptor.md) - [AudioManager](_audio_manager.md) - [AudioMixExtInfo](_audio_mix_ext_info.md) - - [AudioMmapBufferDescripter](_audio_mmap_buffer_descripter.md) + - [AudioMmapBufferDescriptor](_audio_mmap_buffer_descriptor.md) - [AudioPort](_audio_port.md) - [AudioPortCap](audio_portcap.md) - [AudioPortCapability](_audio_port_capability.md) diff --git a/zh-cn/device-dev/reference/hdi-apis/_audio.md b/zh-cn/device-dev/reference/hdi-apis/_audio.md index 722ca8820dcac1d8a751e0c3ef62b966607e7f5e..9dde93d0d7f47911dc97740ccf20f51b7a7ad570 100644 --- a/zh-cn/device-dev/reference/hdi-apis/_audio.md +++ b/zh-cn/device-dev/reference/hdi-apis/_audio.md @@ -54,7 +54,7 @@ Audio模块接口定义。 | [AudioTimeStamp](_audio_time_stamp.md) | 音频时间戳 | | [AudioSubPortCapability](_audio_sub_port_capability.md) | 音频子端口的支持能力 | | [AudioPortCapability](_audio_port_capability.md) | 音频端口的支持能力 | -| [AudioMmapBufferDescripter](_audio_mmap_buffer_descripter.md) | mmap缓冲区描述符 | +| [AudioMmapBufferDescriptor](_audio_mmap_buffer_descriptor.md) | mmap缓冲区描述符 | | [AudioDevExtInfo](_audio_dev_ext_info.md) | 音频设备拓展信息 | | [AudioMixExtInfo](_audio_mix_ext_info.md) | 音轨拓展信息 | | [AudioSessionExtInfo](_audio_session_ext_info.md) | 会话拓展信息 | @@ -145,11 +145,11 @@ Audio模块接口定义。 | [AudioPortCapability::subPorts](#subports) | 支持的子端口列表。 | | [AudioPortCapability::supportSampleFormatNum](#supportsampleformatnum) | 支持的音频样本格式数量。 | | [AudioPortCapability::supportSampleFormats](#supportsampleformats) | 支持的音频样本格式。 | -| [AudioMmapBufferDescripter::memoryAddress](#memoryaddress) | 指向mmap缓冲区的指针。 | -| [AudioMmapBufferDescripter::memoryFd](#memoryfd) | mmap缓冲区的文件描述符。 | -| [AudioMmapBufferDescripter::totalBufferFrames](#totalbufferframes) | 缓冲区总大小,单位:帧。 | -| [AudioMmapBufferDescripter::transferFrameSize](#transferframesize) | 传输大小,单位:帧。 | -| [AudioMmapBufferDescripter::isShareable](#isshareable) | mmap缓冲区是否可以在进程间共享。 | +| [AudioMmapBufferDescriptor::memoryAddress](#memoryaddress) | 指向mmap缓冲区的指针。 | +| [AudioMmapBufferDescriptor::memoryFd](#memoryfd) | mmap缓冲区的文件描述符。 | +| [AudioMmapBufferDescriptor::totalBufferFrames](#totalbufferframes) | 缓冲区总大小,单位:帧。 | +| [AudioMmapBufferDescriptor::transferFrameSize](#transferframesize) | 传输大小,单位:帧。 | +| [AudioMmapBufferDescriptor::isShareable](#isshareable) | mmap缓冲区是否可以在进程间共享。 | | [AudioDevExtInfo::moduleId](#moduleid-12) | 音频流绑定的模块ID。 | | [AudioDevExtInfo::type](#type-23) | 音频端口上的PIN脚(输出、输入)。 | | [AudioDevExtInfo::desc](#desc-55) | 地址描述。 | @@ -797,7 +797,7 @@ bool AudioSampleAttributes::isBigEndian ``` -int32_t AudioMmapBufferDescripter::isShareable +int32_t AudioMmapBufferDescriptor::isShareable ``` **描述:** @@ -833,7 +833,7 @@ enum AudioPortPassthroughMode AudioSubPortCapability::mask ``` -void* AudioMmapBufferDescripter::memoryAddress +void* AudioMmapBufferDescriptor::memoryAddress ``` **描述:** @@ -845,7 +845,7 @@ void* AudioMmapBufferDescripter::memoryAddress ``` -int32_t AudioMmapBufferDescripter::memoryFd +int32_t AudioMmapBufferDescriptor::memoryFd ``` **描述:** @@ -1229,7 +1229,7 @@ enum AudioSampleFormat* AudioPortCapability::supportSampleFormats ``` -int32_t AudioMmapBufferDescripter::totalBufferFrames +int32_t AudioMmapBufferDescriptor::totalBufferFrames ``` **描述:** @@ -1241,7 +1241,7 @@ int32_t AudioMmapBufferDescripter::totalBufferFrames ``` -int32_t AudioMmapBufferDescripter::transferFrameSize +int32_t AudioMmapBufferDescriptor::transferFrameSize ``` **描述:** diff --git a/zh-cn/device-dev/reference/hdi-apis/_audio_attribute.md b/zh-cn/device-dev/reference/hdi-apis/_audio_attribute.md index 32fb2917b206ae9297f47d920e61a9c1cac27323..2281b389b21c0a4c1111e9b1d12490fc9c3070fb 100644 --- a/zh-cn/device-dev/reference/hdi-apis/_audio_attribute.md +++ b/zh-cn/device-dev/reference/hdi-apis/_audio_attribute.md @@ -34,7 +34,7 @@ AudioAttribute音频属性接口。 | ([GetCurrentChannelId](#getcurrentchannelid))(AudioHandle handle, uint32_t \*channelId) | 获取音频的数据通道ID | | ([SetExtraParams](#setextraparams))(AudioHandle handle, const char \*keyValueList) | 设置音频拓展参数 | | ([GetExtraParams](#getextraparams))(AudioHandle handle, char \*keyValueList) | 获取音频拓展参数 | -| ([ReqMmapBuffer](#reqmmapbuffer))(AudioHandle handle, int32_t reqSize, struct AudioMmapBufferDescripter \*desc) | 请求Mmap缓冲区 | +| ([ReqMmapBuffer](#reqmmapbuffer))(AudioHandle handle, int32_t reqSize, struct AudioMmapBufferDescriptor \*desc) | 请求Mmap缓冲区 | | ([GetMmapPosition](#getmmapposition))(AudioHandle handle, uint64_t \*frames, struct AudioTimeStamp \*time) | 获取当前Mmap的读/写位置 | | ([AddAudioEffect](#addaudioeffect))(AudioHandle handle, uint64_t effectid) | 添加音频效果算法实例 | | ([RemoveAudioEffect](#removeaudioeffect))(AudioHandle handle, uint64_t effectid) | 移除音频效果算法实例 | @@ -260,7 +260,7 @@ int32_t (*AudioAttribute::RemoveAudioEffect)(AudioHandle handle, uint64_t effect ``` -int32_t(* AudioAttribute::ReqMmapBuffer) (AudioHandle handle, int32_t reqSize, struct AudioMmapBufferDescripter *desc) +int32_t(* AudioAttribute::ReqMmapBuffer) (AudioHandle handle, int32_t reqSize, struct AudioMmapBufferDescriptor *desc) ``` **描述:** diff --git a/zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descripter.md b/zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descriptor.md similarity index 95% rename from zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descripter.md rename to zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descriptor.md index 93470c6b005a438663e7efd1b8e6ec204701af20..8488a838eff0aaec2b8f565f494ee0f07e88fcbb 100644 --- a/zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descripter.md +++ b/zh-cn/device-dev/reference/hdi-apis/_audio_mmap_buffer_descriptor.md @@ -1,4 +1,4 @@ -# AudioMmapBufferDescripter +# AudioMmapBufferDescriptor ## **概述** diff --git a/zh-cn/device-dev/reference/hdi-apis/_light_types_8idl.md b/zh-cn/device-dev/reference/hdi-apis/_light_types_8idl.md index 14c020c8b3154c2d9296425d9b94edfcba667635..7ba20d9db066445089a3964a8a8e83175583dd9a 100644 --- a/zh-cn/device-dev/reference/hdi-apis/_light_types_8idl.md +++ b/zh-cn/device-dev/reference/hdi-apis/_light_types_8idl.md @@ -39,7 +39,7 @@ | 名称 | 描述 | | -------- | -------- | | [HdfLightId](light.md#hdflightid) { HDF_LIGHT_ID_BATTERY = 1, HDF_LIGHT_ID_NOTIFICATIONS = 2, HDF_LIGHT_ID_ATTENTION = 3, HDF_LIGHT_ID_BUTT = 4 } | 枚举灯类型。 | -| [HdfLightFlashMode](light.md#hdflightflashmode) { HDF_LIGHT_FLASH_NONE = 0, HDF_LIGHT_FLASH_TIMED = 1, HDF_LIGHT_FLASH_GRADIENT = 2, HDF_LIGHT_FLASH_BUTT = 2 } | 枚举灯的模式。 | +| [HdfLightFlashMode](light.md#hdflightflashmode) { HDF_LIGHT_FLASH_NONE = 0, HDF_LIGHT_FLASH_BLINK = 1, HDF_LIGHT_FLASH_GRADIENT = 2, HDF_LIGHT_FLASH_BUTT = 3 } | 枚举灯的模式。 | ### 关键字 diff --git a/zh-cn/device-dev/reference/hdi-apis/annotated.md b/zh-cn/device-dev/reference/hdi-apis/annotated.md index 1b11935d7048c296973c1cfb3958f85c7a849c9e..e415acf8378b78b8e569253222748e5404e3f36b 100644 --- a/zh-cn/device-dev/reference/hdi-apis/annotated.md +++ b/zh-cn/device-dev/reference/hdi-apis/annotated.md @@ -30,7 +30,7 @@ - **[AudioMixExtInfo](_audio_mix_ext_info.md)** -- **[AudioMmapBufferDescripter](_audio_mmap_buffer_descripter.md)** +- **[AudioMmapBufferDescriptor](_audio_mmap_buffer_descriptor.md)** - **[AudioPort](_audio_port.md)** diff --git a/zh-cn/device-dev/reference/hdi-apis/audio__types_8h.md b/zh-cn/device-dev/reference/hdi-apis/audio__types_8h.md index 48baaa842760e3dbae132136694f78d1359052ef..2d61f62b539d810e3c92d314d6c40a19912f47f5 100644 --- a/zh-cn/device-dev/reference/hdi-apis/audio__types_8h.md +++ b/zh-cn/device-dev/reference/hdi-apis/audio__types_8h.md @@ -34,7 +34,7 @@ Audio模块接口定义中使用的自定义数据类型,包括音频端口、 | [AudioTimeStamp](_audio_time_stamp.md) | 音频时间戳 | | [AudioSubPortCapability](_audio_sub_port_capability.md) | 音频子端口的支持能力 | | [AudioPortCapability](_audio_port_capability.md) | 音频端口的支持能力 | -| [AudioMmapBufferDescripter](_audio_mmap_buffer_descripter.md) | mmap缓冲区描述符 | +| [AudioMmapBufferDescriptor](_audio_mmap_buffer_descriptor.md) | mmap缓冲区描述符 | | [AudioDevExtInfo](_audio_dev_ext_info.md) | 音频设备拓展信息. | | [AudioMixExtInfo](_audio_mix_ext_info.md) | 音轨拓展信息 | | [AudioSessionExtInfo](_audio_session_ext_info.md) | 会话拓展信息 | diff --git a/zh-cn/device-dev/reference/hdi-apis/light.md b/zh-cn/device-dev/reference/hdi-apis/light.md index dd499b06f0a262abb527523c1179f53b245a78c7..adab9f4230644c23ae3c35d389ea821bd7b537bf 100644 --- a/zh-cn/device-dev/reference/hdi-apis/light.md +++ b/zh-cn/device-dev/reference/hdi-apis/light.md @@ -46,7 +46,7 @@ | 名称 | 描述 | | -------- | -------- | | [HdfLightId](#hdflightid) { HDF_LIGHT_ID_BATTERY = 1, HDF_LIGHT_ID_NOTIFICATIONS = 2, HDF_LIGHT_ID_ATTENTION = 3, HDF_LIGHT_ID_BUTT = 4 } | 枚举灯类型。 | -| [HdfLightFlashMode](#hdflightflashmode) { HDF_LIGHT_FLASH_NONE = 0, HDF_LIGHT_FLASH_TIMED = 1, HDF_LIGHT_FLASH_GRADIENT = 2, HDF_LIGHT_FLASH_BUTT = 2 } | 枚举灯的模式。 | +| [HdfLightFlashMode](#hdflightflashmode) { HDF_LIGHT_FLASH_NONE = 0, HDF_LIGHT_FLASH_BLINK = 1, HDF_LIGHT_FLASH_GRADIENT = 2, HDF_LIGHT_FLASH_BUTT = 3 } | 枚举灯的模式。 | ### 关键字 @@ -73,7 +73,7 @@ enum HdfLightFlashMode | 枚举值 | 描述 | | -------- | -------- | | HDF_LIGHT_FLASH_NONE | 常亮模式。 | -| HDF_LIGHT_FLASH_TIMED | 闪烁模式。 | +| HDF_LIGHT_FLASH_BLINK | 闪烁模式。 | | HDF_LIGHT_FLASH_GRADIENT | 渐变。 | | HDF_LIGHT_FLASH_BUTT | 无效模式。 | diff --git a/zh-cn/device-dev/subsystems/subsys-build-reference.md b/zh-cn/device-dev/subsystems/subsys-build-reference.md index 17b5add7a489fc05e5865295ba4d58ed4476b357..3279c9bb5db88525830fd336df94124412eec7e6 100644 --- a/zh-cn/device-dev/subsystems/subsys-build-reference.md +++ b/zh-cn/device-dev/subsystems/subsys-build-reference.md @@ -77,7 +77,7 @@ } ``` -**支持的Sanitizer选项** +**支持的Sanitizer类型** 目前支持开启的Sanitizer: @@ -86,11 +86,11 @@ **发布、调测模式** -通过`debug`选项控制使用发布模式还是调测模式,默认为发布模式,使用`debug = true`显式声明开启调测模式,在发布版本的编译中不带此选项。 +通过`debug`选项控制使用发布模式还是调测模式,默认为发布模式,使用`debug = true`显式声明开启调测模式。`debug`选项仅对Sanitizer生效,且与模块是否编译为调试版本无关,但在模块发布版本的编译配置中不应带此选项,或显式地将`debug`设置为`false`,使得Sanitizer处于发布模式。 -- 调试模式:使用Sanitizer在开发时排查问题,与编译的debug版本无关。该模式下会输出产生错误相关的丰富信息来辅助定位错误,并且在发生错误后并不会直接中断程序运行,而是会恢复程序运行进一步识别后续的错误。 +- 调测模式:用于开发时排查问题。该模式下会输出产生错误相关的丰富信息来辅助定位错误,并且在发生错误后并不会直接中断程序运行,而是会恢复程序运行进一步识别后续的错误。 -- 发布模式:保护程序发生错误或被恶意攻击,在产生错误后直接中断程序不会继续执行。 +- 发布模式:保护程序不发生错误或被恶意攻击,在产生错误后直接中断程序不会继续执行。 **屏蔽名单** diff --git a/zh-cn/device-dev/website.md b/zh-cn/device-dev/website.md index 0ece4c28eb5f077f564cae8a07c60d40b5fd68e7..181e52c7768c353051b8e2780a125d79a4dd9128 100644 --- a/zh-cn/device-dev/website.md +++ b/zh-cn/device-dev/website.md @@ -647,7 +647,7 @@ - [AudioDeviceDescriptor](reference/hdi-apis/_audio_device_descriptor.md) - [AudioManager](reference/hdi-apis/_audio_manager.md) - [AudioMixExtInfo](reference/hdi-apis/_audio_mix_ext_info.md) - - [AudioMmapBufferDescripter](reference/hdi-apis/_audio_mmap_buffer_descripter.md) + - [AudioMmapBufferDescriptor](reference/hdi-apis/_audio_mmap_buffer_descriptor.md) - [AudioPort](reference/hdi-apis/_audio_port.md) - [AudioPortCap](reference/hdi-apis/audio_portcap.md) - [AudioPortCapability](reference/hdi-apis/_audio_port_capability.md) diff --git "a/zh-cn/readme/figures/\346\225\260\346\215\256\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\236\266\346\236\204\345\233\276.png" "b/zh-cn/readme/figures/\346\225\260\346\215\256\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\236\266\346\236\204\345\233\276.png" index 74db74f7798c6216f95084ae5acb590c8130980b..7ee06bcc037d95009a4a4b3f3d5055420493ec49 100644 Binary files "a/zh-cn/readme/figures/\346\225\260\346\215\256\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\236\266\346\236\204\345\233\276.png" and "b/zh-cn/readme/figures/\346\225\260\346\215\256\347\256\241\347\220\206\345\255\220\347\263\273\347\273\237\346\236\266\346\236\204\345\233\276.png" differ diff --git a/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md b/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md index 16c8318d068221441622c4b6ac881424c84c6bde..a182e7442718d4e0205aebf6ad07c449a97b3907 100644 --- a/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md +++ b/zh-cn/release-notes/OpenHarmony-v3.2-beta3.md @@ -167,7 +167,7 @@ DeviceProfile适配分布式数据库自动同步策略,以及采集信息补 | 语言编译运行时子系统 | 前端编译性能提升,如es2abc。
运行时性能提升优化,如ISA重构优化、汇编解释器、TSAOT等。
新增功能,如支持严格模式的ES2021、模块化支持、Runtime 调试调优增强、字节码热重载等。
具体如下:
I5MYM9 【新增规格】运行时多模块单abc文件合并适配
I59TAQ【新增规格】支持TSAOT优化编译器标准编译lowering和优化pass(规格)描述
I5OJ8Q【新增规格】IDE属性查看功能补齐已支持的2021规范定义的类型
I5ODV4 【新增特性】 支持字节码补丁文件卸载功能
I5OXSC 【新增特性】 支持字节码补丁文件加载功能
I5HNNZ 【新增特性】使能加载器的命名空间
I5HVQE  【新增特性】线程stacksize根据产品配置,增加stack pageguard保护
I5MCUF【增强特性】libc增加CAPI接口,支持pthread等符号
I5HVNH【新增特性】RM.006.增强动态库符号管理
I5HVQ0 【新增特性】RM.008.musl支持fortify功能
I5KT7X 【新增特性】RM.002.提供API头文件API检测功能
I5TB3Y 【新增特性】ABI默认使用emutls特性
I5R119  【增强特性】拆分加载器与libc内存使用
支持clang工具链的开源构建
I5MYM9【新增规格】前端编译工具链支持模块化编译
I5IKO1【新增规格】前端abc支持commonjs模块
I5RRAJ【新增规格】补丁文件源码识别工具
I5PRFT【新增规格】补丁字节码编译工具
I5RHDH【新增规格】支持方舟字节码热加载
I5RA7C【新增规格】支持strict模式2021
I5HRUY【新增规格】es2abc支持js转换方舟字节码 | NA | | 帐号&程序访问控制子系统 | 帐号服务新增用户身份认证服务;权限服务新增支持精准定位或模糊定位,以及其他能力增强;新增隐私管理服务。
主要涉及如下需求:
I5N90B【新增规格】应用帐号适配沙箱应用
I5N90O【新增规格】帐号子系统新增用户身份认证服务
I5NOQI【新增特性】权限服务支持精准定位或模糊定位
I5NT1X【新增特性】权限使用记录管理增强
I5NU8U【新增特性】权限弹框UX界面增强
I5P4IU【新增特性】新增隐私管理服务
I5P530【新增特性】位置服务使用状态管理 | NA | | 全球化子系统 | 新增支持翻译伪本地化能力。
涉及如下需求:
I4WLSJ 【新增特性】翻译伪本地化能力 | NA | -| Misc服务子系统 | 新增剪贴板、上传下载、锁屏、输入法框架等模块基础特性。
主要涉及如下需求:
I5JPMG 【request部件】【download】后台任务通知
I5NXHK 【input_method_fwk部件】输入法框架支持仅绑定输入法innerkits接口和独立控制软键盘显隐的js接口
I5NG2X 【theme_screenlock部件】支持特定系统应用请求锁定屏幕
I5IU1Z  支持向剪贴板数据增加图片内容的数据项
I5OGA3  支持设备级的跨设备剪贴板开关
I5NMKI 【pasteboard部件】支持向剪贴板数据增加二进制数据
I5MAMN  支持剪贴板数据范围限制在应用内
I5OX20 【input_method_fwk部件】输入法框架支持获取输入法扩展 | NA | +| Misc服务子系统 | 新增剪贴板、上传下载、锁屏、输入法框架等模块基础特性。
主要涉及如下需求:
I5JPMG 【request部件】【download】后台任务通知
I5NXHK 【input_method_fwk部件】输入法框架支持仅绑定输入法innerkits接口和独立控制软键盘显隐的js接口
I5NG2X 【theme_screenlock部件】支持特定系统应用请求锁定屏幕
I5IU1Z  支持向剪贴板数据增加图片内容的数据项
I5OGA3  支持剪贴板插件加载开关
I5NMKI 【pasteboard部件】支持向剪贴板数据增加二进制数据
I5MAMN  支持剪贴板数据范围限制在应用内
I5OX20 【input_method_fwk部件】输入法框架支持获取输入法扩展 | NA | | ArkUI子系统 | ArkUI组件能力增强;资源、媒体查询能力增强;内存、性能优化;DFX能力增强;工具链能力增强。
主要涉及如下需求:
I5IZZ7 【ace_engine_standard部件】panel组件支持单独设置每个角的borderRadius
I5JQ1R 【ace_engine_standard部件】支持图片复制粘贴
I5JQ3F 【ace_engine_standard部件】输入框能力增强
I5JQ3J 【ace_engine_standard部件】stack组件新增事件拓传机制
I5JQ54 【ace_engine_standard部件】指定控件获取焦点
I5MX7J 【ace_engine_standard部件】list列表支持左滑/右滑及回弹效果
I5MWS0 【ace_engine_standard部件】panel组件弹出高度通知给开发者
I5IZVY 【ace_engine_standard部件】键鼠接入时支持组件刷新
I5JQ5Y 【ace_engine_standard部件】走焦能力增强
I5IY7K 【新增需求】【ace_engine_standard部件】主题能力支持
I5MWTB 【ace_engine_standard部件】媒体查询支持vp查询
I5IZU9 【ace_engine_standard部件】ui_service常驻内存优化
I5JQ26 【ace_engine_standard部件】Vsync请求机制流程优化
I5JQ2O 【ace_engine部件】公共资源预加载
I5JQ2D 【ace_engine_standard部件】Move事件重采样优化
I5IZXS 【toolchain部件】DFX打印错误堆栈时支持显示开发者变量名称原文
I5IZYG 【toolchain部件】DFX打印错误堆栈时支持显示开发者变量名称原文
I5IZX0 【toolchain部件】编译支持解析$r新增bundleName和moduleName参数
I5J09I 【toolchain部件】\@Builder 支持export导出 | NA | API变更请参考: @@ -188,7 +188,7 @@ API变更请参考: | -------- | -------- | -------- | -------- | | ArkUI | [HealthyDiet:健康饮食](https://gitee.com/openharmony/applications_app_samples/tree/master/ETSUI/HealthyDiet) | 这是一个记录饮食和查看食物信息的应用,主要用于管理饮食健康。可以添加饮食信息,包括食物的种类、重量以及用餐时间,如早餐、 午餐、晚餐和夜宵,并能统计得到相应用餐时间的总热量值、总蛋白质、总脂肪和总碳水值,并且用柱状图的形式展示出来。 | eTS | | ArkUI | [MusicAlbum:一多音乐专辑主页](https://gitee.com/openharmony/applications_app_samples/tree/master/MultiDeviceAppDev/MusicAlbum) | 本示例展示了音乐专辑主页,使用一次开发多端部署中介绍的自适应布局能力和响应式布局能力进行多设备(或多窗口尺寸)适配,保证应用在不同设备或不同窗口尺寸下可以正常显示。 | eTS | -| 元能力、文件管理 | [Share:分享](https://gitee.com/openharmony/applications_app_samples/tree/master/Share/Share) | 分享的主要工作是实现:发送方将文本,链接,图片文件三种类型分享给三方应用,同时能够在三方应用中分别呈现出来。 | eTS | +| 元能力、文件管理 | [Share:分享](https://gitee.com/openharmony/applications_app_samples/tree/master/Share/CustomShare) | 分享的主要工作是实现:发送方将文本,链接,图片文件三种类型分享给三方应用,同时能够在三方应用中分别呈现出来。 | eTS | | 元能力 | [GalleryForm:图库卡片](https://gitee.com/openharmony/applications_app_samples/tree/master/ability/GalleryForm) | 本示例是模拟图库卡片,实现对图库中的照片在卡片中显示,定时刷新卡片内容等功能。 | eTS | | ArkUI | [AppMarket:一多应用市场首页](https://gitee.com/openharmony/applications_app_samples/tree/master/MultiDeviceAppDev/AppMarket) | 本示例展示了应用市场首页,页面中包括Tab栏、运营横幅、精品应用、精品游戏等。 | eTS | | ArkUI | [Weather:一多天气](https://gitee.com/openharmony/applications_app_samples/tree/master/MultiDeviceAppDev/Weather) | 本示例展示一个天气应用界面,包括首页、城市管理、添加城市、更新时间弹窗,体现一次开发,多端部署的能力。 | eTS |