From 7b05a643b37aaec57f89e81d45d1f3d54cdde0a2 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Mon, 13 Sep 2021 12:59:14 +0000 Subject: [PATCH 1/3] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- OAT.xml | 86 +++ README.en.md | 36 -- README.md | 196 ++++++- README_zh.md | 184 +++++++ figures/en-us_image_0000001152988366.png | Bin 0 -> 12874 bytes figures/zh-cn_image_0000001152988366.png | Bin 0 -> 17135 bytes interfaces/native/vibrator/BUILD.gn | 65 +++ .../native/vibrator/include/vibrator_agent.h | 115 ++++ .../vibrator/include/vibrator_agent_type.h | 35 ++ interfaces/native/vibrator/libvibrator.json | 18 + .../native/vibrator/src/vibrator_agent.cpp | 83 +++ interfaces/native/vibrator/test/BUILD.gn | 53 ++ .../unittest/vibrator_agent_native_test.cpp | 512 ++++++++++++++++++ interfaces/plugin/BUILD.gn | 49 ++ .../vibrate/include/vibrator_napi_utils.h | 35 ++ interfaces/plugin/vibrate/src/vibrate_js.cpp | 167 ++++++ .../vibrate/src/vibrator_napi_utils.cpp | 139 +++++ ohos.build | 32 ++ 18 files changed, 1742 insertions(+), 63 deletions(-) create mode 100755 OAT.xml delete mode 100644 README.en.md mode change 100644 => 100755 README.md create mode 100755 README_zh.md create mode 100755 figures/en-us_image_0000001152988366.png create mode 100755 figures/zh-cn_image_0000001152988366.png create mode 100755 interfaces/native/vibrator/BUILD.gn create mode 100755 interfaces/native/vibrator/include/vibrator_agent.h create mode 100755 interfaces/native/vibrator/include/vibrator_agent_type.h create mode 100755 interfaces/native/vibrator/libvibrator.json create mode 100755 interfaces/native/vibrator/src/vibrator_agent.cpp create mode 100755 interfaces/native/vibrator/test/BUILD.gn create mode 100755 interfaces/native/vibrator/test/unittest/vibrator_agent_native_test.cpp create mode 100755 interfaces/plugin/BUILD.gn create mode 100755 interfaces/plugin/vibrate/include/vibrator_napi_utils.h create mode 100755 interfaces/plugin/vibrate/src/vibrate_js.cpp create mode 100755 interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp create mode 100755 ohos.build diff --git a/OAT.xml b/OAT.xml new file mode 100755 index 0000000..174f952 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 9d31f9b..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# sensors_miscdevice - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 8a76f4c..fb8d2e4 --- a/README.md +++ b/README.md @@ -1,39 +1,181 @@ -# sensors_miscdevice +# Misc Device -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +- [Introduction](#section11660541593) +- [Directory Structure](#section44981327519) +- [Constraints](#section98068674513) +- [Usage](#section1581412211528) + - [Available APIs](#section15684191115524) + - [How to Use](#section79302049192310) -#### 软件架构 -软件架构说明 +- [Repositories Involved](#section96071132185310) +## Introduction -#### 安装教程 +Misc devices, including vibrators and LED indicators, are used to send signals externally. You can call APIs to control the vibration of vibrators and lighting-on and lighting-off of LED indicators. -1. xxxx -2. xxxx -3. xxxx +**Figure 1** Misc device architecture -#### 使用说明 -1. xxxx -2. xxxx -3. xxxx +![](figures/en-us_image_0000001152988366.png) -#### 参与贡献 +## Directory Structure -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +``` +/base/sensors/sensor_miscdevice +├── frameworks # Framework code +│ └── native # Native methods for the client to connect to services +├── interfaces # External APIs +│ ├── native # Native implementation +│ └── plugin # JS APIs +├── sa_profile # Configuration file of system ability names and dynamic libraries +├── services # Code of services +│ └── miscdevice_service # Misc device service, which is used to control the vibration of vibrators and lighting-on and lighting-off of LED lights +└── utils # Common code, including permissions and communication capabilities +``` +## Constraints -#### 特技 +- The APIs are valid only when your hardware is equipped with the required misc devices. +- To use vibrators, you need to request the required permissions. + + **Table 1** Permissions required by misc devices + + + + + + + + + + + + + + +

Misc Device

+

Permission Name

+

Sensitivity

+

Permission Description

+

Vibrator

+

ohos.permission.VIBRATE

+

system_grant

+

Allows an application to use the vibrator.

+
+ + +## Usage + +This section describes the features and usage of the vibrator APIs. + +### Available APIs + +The APIs provided for the vibrator are used to trigger and stop vibration. The following table describes these APIs. + +**Table 2** JS APIs for the vibrator + + + + + + + + + + + + + + + + + + + + + + + + + +

API

+

Description

+

vibrate(duration: number, callback?: AsyncCallback<void>)

+

Triggers vibration based on the duration specified by duration. This API uses a callback to indicate whether the vibration is triggered successfully.

+

vibrate(duration: number): Promise<void>

+

Triggers vibration based on the duration specified by duration. This API uses a promise to indicate whether the vibration is triggered successfully.

+

vibrate(effectId: EffectId, callback?: AsyncCallback<void>)

+

Triggers vibration based on the vibration effect specified by effectId. This API uses a callback to indicate whether the vibration is triggered successfully.

+

vibrate(effectId: EffectId): Promise<void>

+

Triggers vibration based on the vibration effect specified by effectId. This API uses a promise to indicate whether the vibration is triggered successfully.

+

stop(stopMode: VibratorStopMode, callback?: AsyncCallback<void>)

+

Stops vibration based on the mode specified by stopMode. There are two modes: VIBRATOR_STOP_MODE_TIME and VIBRATOR_STOP_MODE_PRESET, which are used to stop vibration triggered by duration and effectId, respectively. This API uses a callback to indicate whether the vibration is stopped successfully.

+

stop(stopMode: VibratorStopMode): Promise<void>

+

Stops vibration based on the mode specified by stopMode. There are two modes: VIBRATOR_STOP_MODE_TIME and VIBRATOR_STOP_MODE_PRESET, which are used to stop vibration triggered by duration and effectId, respectively. This API uses a promise to indicate whether the vibration is stopped successfully.

+
+ +### How to Use + +1. Import the **vibrate** package. +2. Trigger vibration with a specific duration. +3. Stop vibration that is triggered with a specific duration. +4. Trigger vibration with a specific effect. +5. Stop vibration that is triggered with a specific effect. + +The following sample code provides a complete process of using the vibrator APIs: + +``` +//Step 1 Import the vibrate package. +import vibrate from '@ohos.vibrate'; +export default { + onCreate() { + console.info('MiscdeviceJsAPI AceApplication onCreate'); + // Step 2 Trigger vibration with a specific duration. + vibrate.vibrate(100, function(error) { + if (error) { + console.error("Failed to trigger vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in triggering vibration."); + }); + // Step 3 Stop vibration that is triggered with a specific duration. + vibrate.stop(vibrate.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, function(error) { + if (error) { + console.error("Failed to stop vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in stopping vibration."); + }); + // Step 4 Trigger vibration based on with a specific effect. + vibrate.vibrate(vibrate.EffectId.EFFECT_CLOCK_TIMER, function(error) { + if (error) { + console.error("Failed to trigger vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in triggering vibration."); + }); + // Step 54 Stop vibration that is triggered with a specific effect. + vibrate.stop(vibrate.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, function(error) { + if (error) { + console.error("Failed to stop vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in stopping vibration."); + }); + } + onDestroy() { + console.info('AceApplication onDestroy'); + } +} +``` + +## Repositories Involved + +Pan-sensor subsystem + +sensors\_start + +sensors\_sensor + +**sensors\_miscdevice** -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 0000000..0a07299 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,184 @@ +# Miscdevice + +- [简介](#section11660541593) +- [Sensors\_miscdevice组件目录](#section44981327519) +- [约束](#section98068674513) +- [使用](#section1581412211528) + - [接口说明](#section15684191115524) + - [使用说明](#section79302049192310) + +- [相关仓](#section96071132185310) + +>![](public_sys-resources/icon-note.gif) **说明:** +>从API Version 7 开始支持。 + +## 简介 + +小器件是指用于向外传递信号的设备,包括马达和LED灯,本组件对开发者提供控制马达振动和LED灯开关的能力,其架构图如下所示: + +**图 1** 小器件架构图 + + +![](figures/zh-cn_image_0000001152988366.png) + +## Sensors\_miscdevice组件目录 + +``` +/base/sensors/sensor_miscdevice +├── frameworks # 框架代码 +│ └── native # 客户端连接服务的Native方法 +├── interfaces # 对外接口存放目录 +│ ├── native # native 实现 +│ └── plugin # Js API +├── sa_profile # 服务名称和服务的动态库的配置文件 +├── services # 服务的代码目录 +│ └── miscdevice_service # 小器件服务,包含马达和Led灯,控制马达振动和灯的开关 +└── utils # 公共代码,包括权限、通信等能力 +``` + +## 约束 + +- 要使用器件的功能,设备必须具有对应的器件。 +- 针对马达,开发者需要请求相应的权限才能使用。 + + **表 1** 器件权限列表 + + + + + + + + + + + + + + +

器件

+

权限名

+

敏感级别

+

权限描述

+

马达

+

ohos.permission.VIBRATE

+

system_grant

+

允许应用程序使用马达

+
+ + +## 使用 + +本节以马达为例,说明其提供的接口功能以及使用流程。 + +### 接口说明 + +马达主要提供的功能有:触发震动,停止震动。JS API类开放能力如下: + +**表 2** 马达JS API的主要接口 + + + + + + + + + + + + + + + + + + + + + + + + + +

接口名

+

描述

+

vibrate(duration: number, callback?: AsyncCallback<void>)

+

按照指定持续时间触发震动。duration为振动持续时长,callback为触发振动是否成功。

+

vibrate(duration: number): Promise<void>

+

按照指定持续时间触发震动,返回Promise表示触发振动是否成功。

+

vibrate(effectId: EffectId, callback?: AsyncCallback<void>)

+

按照指定振动效果字符串触发震动。effectId表示预置的振动效果串,callback为触发振动是否成功。

+

vibrate(effectId: EffectId): Promise<void>

+

按照指定振动效果字符串触发震动。effectId表示预置的振动效果串,返回Promise表示触发振动是否成功。

+

stop(stopMode: VibratorStopMode, callback?: AsyncCallback<void>)

+

按照指定的要停止的振动模式来停止震动。stopMode为枚举马达两种振动类型,VIBRATOR_STOP_MODE_TIME、VIBRATOR_STOP_MODE_PRESET分别为停止duration模式的振动和停止预置EffectId模式的振动,callback为停止振动是否成功。

+

stop(stopMode: VibratorStopMode): Promise<void>

+

按照指定的要停止的振动模式来停止震动。stopMode为枚举马达两种振动类型,VIBRATOR_STOP_MODE_TIME、VIBRATOR_STOP_MODE_PRESET分别为停止duration模式的振动和停止预置EffectId模式的振动,返回Promise表示触发振动是否成功。

+
+ +### 使用说明 + +1. 导入vibrate包。 +2. 触发马达按照指定持续时间振动。 +3. 停止马达按照指定持续时间振动。 +4. 触发按照指定振动效果字符串振动。 +5. 停止按照指定振动效果字符串振动。 + +下述的代码示例中,提供了马达震动使用的完整流程。 + +``` +//步骤1 导包 +import vibrate from '@ohos.vibrate'; +export default { + onCreate() { + console.info('MiscdeviceJsAPI AceApplication onCreate'); + //步骤2 触发马达按照指定持续的时间振动 + vibrate.vibrate(100, function(error) { + if (error) { + console.error("Failed to trigger vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in triggering vibration."); + }); + //步骤3 停止马达按照指定持续的时间振动 + vibrate.stop(vibrate.VibratorStopMode.VIBRATOR_STOP_MODE_TIME, function(error) { + if (error) { + console.error("Failed to stop vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in stopping vibration."); + }); + //步骤4 触发马达按照指定的字符串效果振动 + vibrate.vibrate(vibrate.EffectId.EFFECT_CLOCK_TIMER, function(error) { + if (error) { + console.error("Failed to trigger vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in triggering vibration."); + }); + //步骤5 停止马达按照指定的字符串效果振动 + vibrate.stop(vibrate.VibratorStopMode.VIBRATOR_STOP_MODE_PRESET, function(error) { + if (error) { + console.error("Failed to stop vibration. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in stopping vibration."); + }); + } + onDestroy() { + console.info('AceApplication onDestroy'); + } +} +``` + +## 相关仓 + +泛Sensor子系统 + +sensors\_start + +sensors\_sensor + +**sensors\_miscdevice** + diff --git a/figures/en-us_image_0000001152988366.png b/figures/en-us_image_0000001152988366.png new file mode 100755 index 0000000000000000000000000000000000000000..d8fc97aff647af303b6dc5882d22a5e870b880a2 GIT binary patch literal 12874 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

jek5Q%7%WP zQ*8K=E5eh@7;|iA`w{G;>!&5RywK~N>QLJrc~g=1Y*(N1 zIo=azLzt7p!NWifZ!=Mj_!>@oH+HpM?VRvNxMOg4vis=$p%+6*PvFqs=QAXF%Fh_{i%)`~#8(`l?e%u7}eSZG;xJcYZC>{w%j^MpI zA2T02!5+eVA{E?MHS;(W+%_orAo2Gr9d|CtxhzPdba=t@RX+e)hSVb4=3X=43OTw> zQtNg{1%qMM&xWsb6ZEpf zT94sq#r|pnPq*oDmRsyR`6eKXa}W9Nm>Y$MF-qcXrhI_Ew*B2&=fg8+mmBB29QGns-M0f(qUWhM=( z+QQ|Zc)F9Z!}aO*bA2JvOE=lI{HU7JZ1VFYp5Oazfnq!qpc%B)!sx95D|Ev!C~}Wi zUpn!s<#+Jnc1K2Ms^ggj;a)X&mNVI&1n{Jvi~7C2=IFWzqt_uXp|Zoif}mTt9p`AK z6U;|P;e2mg)q-4I@HtcPZC2l=KuUmxYvlHd`EwpRT_e`4?fVf4g3dB|KE`KY<2Emr z0Zh-mJpOuOa=8`YHufQxLYNtBfxtsO%zd=f1AfE*4az$`D3PbTG#Vqhzt31)3S6dp z1u^bAZ66GUs9kpSx*|9~+aJF7`oL&q51Oa4sU;5KWAy!xS4dUD!X(xt7>0H0aLE%_ zMLj|@>+24S6i|ge-%U3v{bwl9(`H*ejV2L&T-@tx}|9gK&GXx#p6X?A7t|n zzlgM!s@uK+>CY$IHB4YvDhGXQad3+-rk?5IzGx%0-JZJ8PoWulnMa&NU8SRM(Ko;d zY$(!?mQr$N+?SdyRW^fRik}JL0DH|$3 z5Dst{4rt{`xk0v zI|Ed0+*m3Is#-nlH@8Opq}Xu*0P8_a(OtY;=}kUZ`}y4Q@(8HZg9NElk{3%t#>l2N zF}w%F_k=<#obX0H&8><&jZIohUdvch5tclQq_kQLD@vutTT6CD(D)LOjOfpnV`a5o z-}cyGByR0DYiK%Fp1TO0NLtH_v}hZMQQ1GkE&jXAtat8*iW^V*zj)jIf$zL*QdVDF3b&4#o~QnkkLs~R-g=#&zls5t9~gHk&HZF{62B+Ywk&58O48-aM^Zbp#5TE(*t;1ShbPvu66SR`IW zv3001otNr2?o)!(-=p#&)RWTFB~=Y)XJeBPJ7y9Wy68(I0j`1labFdBuO*D@D;*Cz zq4(`>(v32fP_3G*ZestiQGu=`fNI3)J|GD0wuS^-Rp}|du^{rL0zgPca*{$-L73Yh z;G5D7S(=ELay;R>0h!(S{`ETmWkJP)*|S&62SR2(Bv-o}E)ex05e(Xc`|BxdW+mV# z1vGG|8j&|WW#xC!uhw=S z=TV%$-4}2K0C`br{mG)z9#@NULDwik`G`qKSUIeE_P$9st;}evXTFTIxXcsKY%`z8 zW|Vs^Bm~=zSG_4bX?iW*yl?t;W3RnGE!T>AlW4O!(a|fVPRo~hL|edd)J>ch; zIxahu*%R}Oztk7oWRH;DbVgn%#8qsDRlbG3SbOa`LVd39Kj7NHaqtR{6 zm;y|fgI=EhwB)Hh7ApZHP0KUsi4_tkZN!>c|D`9DpO)a(EN literal 0 HcmV?d00001 diff --git a/figures/zh-cn_image_0000001152988366.png b/figures/zh-cn_image_0000001152988366.png new file mode 100755 index 0000000000000000000000000000000000000000..491f4bc189892a5d319b61c46b2967533eda1b76 GIT binary patch literal 17135 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 literal 0 HcmV?d00001 diff --git a/interfaces/native/vibrator/BUILD.gn b/interfaces/native/vibrator/BUILD.gn new file mode 100755 index 0000000..76eb7fe --- /dev/null +++ b/interfaces/native/vibrator/BUILD.gn @@ -0,0 +1,65 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +SUBSYSTEM_DIR = "//base/sensors/sensors_miscdevice" +ohos_ndk_library("libvibrator_ndk") { + output_name = "vibrator" + ndk_description_file = "./libvibrator.json" + min_compact_version = "6" +} + +ohos_ndk_headers("vibrator_ndk_header") { + dest_dir = "$ndk_headers_out_dir/sensors" + sources = [ + "./include/vibrator_agent.h", + "./include/vibrator_agent_type.h", + ] +} + +config("vibrator_config") { + include_dirs = [ "include" ] +} + +ohos_shared_library("vibrator_interface_native") { + output_name = "vibrator" + sources = [ "src/vibrator_agent.cpp" ] + + include_dirs = [ + "include", + "//utils/native/base/include", + "//base/sensors/sensors_miscdevice/utils/include", + "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + ] + + cflags = [ "-Wno-error=inconsistent-missing-override" ] + + deps = [ + "$SUBSYSTEM_DIR/frameworks/native/miscdevice:libvibrator_native", + "$SUBSYSTEM_DIR/interfaces/native/vibrator:libvibrator_ndk", + "//utils/native/base:utils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core" + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + public_configs = [ ":vibrator_config" ] + part_name = "sensors_miscdevice" + subsystem_name = "sensors" +} + +group("vibrator_target") { + deps = [ ":vibrator_interface_native" ] +} diff --git a/interfaces/native/vibrator/include/vibrator_agent.h b/interfaces/native/vibrator/include/vibrator_agent.h new file mode 100755 index 0000000..2b68e5b --- /dev/null +++ b/interfaces/native/vibrator/include/vibrator_agent.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup vibrator + * @{ + * + * @brief Provides functions for managing vibrators. + * @since 6 + */ + +/** + * @file vibrator_agent.h + * + * @brief Declares the functions for starting or stopping a vibrator. + * @since 6 + */ +#ifndef VIBRATOR_AGENT_H +#include +#define VIBRATOR_AGENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Indicates the mode of stopping a one-shot vibration effect. + * + * @since 6 + */ +const char *VIBRATOR_STOP_MODE_TIME = "time"; + + +/** + * @brief Indicates the mode of stopping a preset vibration effect. + * + * @since 6 + */ +const char *VIBRATOR_STOP_MODE_PRESET = "preset"; + +/** + * @brief Controls this vibrator to perform a vibration with a preset vibration effect. + * + * @param effectId Indicates the preset vibration effect, which is described in {@link vibrator_agent_type.h}, for + * example: + * {@link VIBRATOR_TYPE_CAMERA_LONG_PRESS}: describes the vibration effect of the vibrator when a user touches and holds + * the viewfinder. + * {@link VIBRATOR_TYPE_CAMERA_FOCUS}: describes the vibration effect of the vibrator when the camera is focusing. + * {@link VIBRATOR_TYPE_CONTROL_TEXT_EDIT}: describes the vibration effect of the vibrator when a user touches and holds + * the editing text. + * @return Returns 0 if the vibrator vibrates as expected; returns -1 otherwise, for example, the preset + * vibration effect is not supported. + * + * @since 6 + */ +int32_t StartVibrator(const char *effectId); + + +/** + * @brief Controls this vibrator to perform a one-shot vibration at a given duration. + * + * @param duration Indicates the duration that the one-shot vibration lasts, in milliseconds. + * @return Returns 0 if the vibrator vibrates as expected; returns -1 otherwise, for example, the given + * duration for the one-shot vibration is invalid. + * + * @since 6 + */ +int32_t StartVibratorOnce(uint32_t duration); + + +/** + * @brief Enables this vibrator to perform a periodic vibration. + * @since 6 + */ +void EnableLooping(); + + +/** + * @brief Disables this vibrator from performing a periodic vibration. + * + * @return Returns 0 if the periodic vibration is stopped as expected; returns -1 otherwise. + * + * @since 6 + */ +int32_t DisableLooping(); + + +/** + * @brief Stops the vibration of this vibrator. + * + * @param mode Indicates the mode of the vibration to stop. The values can be time and preset, + * respectively representing a one-shot vibration effect and a preset vibration effect. + * @return Returns 0 if the vibration is stopped as expected; returns -1 otherwise. + * @since 6 + */ +int32_t StopVibrator(const char *mode); + +#ifdef __cplusplus +}; +#endif + +/** @} */ +#endif // endif VIBRATOR_AGENT_H \ No newline at end of file diff --git a/interfaces/native/vibrator/include/vibrator_agent_type.h b/interfaces/native/vibrator/include/vibrator_agent_type.h new file mode 100755 index 0000000..b056672 --- /dev/null +++ b/interfaces/native/vibrator/include/vibrator_agent_type.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIBRATOR_AGENT_TYPE_H +#define VIBRATOR_AGENT_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Describes the vibration effect of the vibrator when a user adjusts the timer. + * + * @since 1 + */ +const char *VIBRATOR_TYPE_CLOCK_TIMER = "haptic.clock.timer"; + +/** @} */ +#ifdef __cplusplus +}; +#endif + +#endif // endif VIBRATOR_AGENT_TYPE_H \ No newline at end of file diff --git a/interfaces/native/vibrator/libvibrator.json b/interfaces/native/vibrator/libvibrator.json new file mode 100755 index 0000000..376816e --- /dev/null +++ b/interfaces/native/vibrator/libvibrator.json @@ -0,0 +1,18 @@ +[ + { + "first_introduced": "6", + "name": "StartVibrator" + }, + { + "name": "StartVibratorOnce" + }, + { + "name": "EnableLooping" + }, + { + "name": "DisableLooping" + }, + { + "name": "StopVibrator" + } +] diff --git a/interfaces/native/vibrator/src/vibrator_agent.cpp b/interfaces/native/vibrator/src/vibrator_agent.cpp new file mode 100755 index 0000000..a491e48 --- /dev/null +++ b/interfaces/native/vibrator/src/vibrator_agent.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "vibrator_agent.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "vibrator_service_client.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; +using OHOS::Sensors::VibratorServiceClient; + +static const HiLogLabel LABEL = { LOG_CORE, OHOS::SensorsLogDomain::MISCDEVICE_VIBRATOR_INTERFACE, "VibratorNDK" }; +static const int32_t DEFAULT_VIBRATOR_ID = 123; +static int32_t g_loopingFlag = 0; + +void EnableLooping() +{ + g_loopingFlag = 1; +} + +int32_t DisableLooping() +{ + g_loopingFlag = 0; + return StopVibrator(VIBRATOR_STOP_MODE_PRESET); +} + +int32_t StartVibrator(const char *effectId) +{ + if (effectId == NULL) { + HiLog::Error(LABEL, "%{public}s effectId is null", __func__); + return OHOS::Sensors::ERROR; + } + bool isLooping = (g_loopingFlag == 1) ? true : false; + auto &client = VibratorServiceClient::GetInstance(); + int32_t ret = client.Vibrate(DEFAULT_VIBRATOR_ID, effectId, isLooping); + if (ret != OHOS::ERR_OK) { + HiLog::Error(LABEL, "%{public}s vibrator effectId failed, ret: %{public}d", __func__, ret); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} + +int32_t StartVibratorOnce(uint32_t duration) +{ + if (duration <= 0) { + HiLog::Error(LABEL, "%{public}s duration is invalid", __func__); + return OHOS::Sensors::ERROR; + } + auto &client = VibratorServiceClient::GetInstance(); + int32_t ret = client.Vibrate(DEFAULT_VIBRATOR_ID, duration); + if (ret != OHOS::ERR_OK) { + HiLog::Error(LABEL, "%{public}s vibrator duration failed, ret: %{public}d", __func__, ret); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} + +int32_t StopVibrator(const char *mode) +{ + if (strcmp(mode, "time") != 0 && strcmp(mode, "preset") != 0) { + HiLog::Error(LABEL, "%{public}s mode is invalid, mode is %{public}s", __func__, mode); + return OHOS::Sensors::ERROR; + } + auto &client = VibratorServiceClient::GetInstance(); + int32_t ret = client.Stop(DEFAULT_VIBRATOR_ID, mode); + if (ret != OHOS::ERR_OK) { + HiLog::Error(LABEL, "%{public}s is failed, ret: %{public}d", __func__, ret); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} \ No newline at end of file diff --git a/interfaces/native/vibrator/test/BUILD.gn b/interfaces/native/vibrator/test/BUILD.gn new file mode 100755 index 0000000..dc47e7a --- /dev/null +++ b/interfaces/native/vibrator/test/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") + +SUBSYSTEM_DIR = "//base/sensors" +module_output_path = "sensors/miscdevice/interfaces" + +####################################################### +ohos_unittest("VibratorNDKTest") { + module_out_path = module_output_path + sources = [ "unittest/vibrator_agent_native_test.cpp" ] + + include_dirs = [ + "../include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "$SUBSYSTEM_DIR/sensors_miscdevice/utils/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensors_miscdevice/interfaces/native/vibrator:vibrator_interface_native", + "$SUBSYSTEM_DIR/sensors_miscdevice/utils:libmiscdevice_utils", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] +} + +####################################################### +group("unittest") { + testonly = true + if (is_phone_product || is_wearable_product) { + deps = [ ":VibratorNDKTest" ] + } +} diff --git a/interfaces/native/vibrator/test/unittest/vibrator_agent_native_test.cpp b/interfaces/native/vibrator/test/unittest/vibrator_agent_native_test.cpp new file mode 100755 index 0000000..1c7c413 --- /dev/null +++ b/interfaces/native/vibrator/test/unittest/vibrator_agent_native_test.cpp @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "jni.h" + +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "vibrator_agent.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::MISCDEVICE_VIBRATOR_INTERFACE, "VibratorAgentNativeTest" }; +} + +class VibratorAgentNativeTest : public testing::Test { +public: + void SetUp(); + void TearDown(); +}; + +void VibratorAgentNativeTest::SetUp() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); +} + +void VibratorAgentNativeTest::TearDown() +{ + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +/* + * @tc.name: PlayVibratorEffect_001 + * @tc.desc: perform vibrator short effect + * @tc.type: FUNC + * @tc.require: SR000F5A2Q AR000F8QO2 + * @tc.author: houpengfei + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorEffect_001, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Bounce"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: PlayVibratorEffect_002 + * @tc.desc: perform vibrator short effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorEffect_002, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: PlayVibratorEffect_003 + * @tc.desc: perform vibrator short effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorEffect_003, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.effect"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: PlayVibratorDuration_001 + * @tc.desc: perform vibrator duration + * @tc.type: FUNC + * @tc.require: + * @tc.author: houpengfei + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorDuration_001, TestSize.Level1) +{ + int32_t ret = StartVibratorOnce(1000); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: PlayVibratorDuration_002 + * @tc.desc: perform vibrator duration + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorDuration_002, TestSize.Level1) +{ + int32_t ret = StartVibratorOnce(5000); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: PlayVibratorDuration_003 + * @tc.desc: perform vibrator duration + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, PlayVibratorDuration_003, TestSize.Level1) +{ + int32_t ret = StartVibratorOnce(50000); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StopVibrator_001 + * @tc.desc: stop vibrator duration + * @tc.type: FUNC + * @tc.require: AR000F8QO2 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StopVibrator_001, TestSize.Level1) +{ + int32_t ret = StartVibratorOnce(5000); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); + ret = StopVibrator(VIBRATOR_STOP_MODE_TIME); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StopVibrator_002 + * @tc.desc: stop vibrator preset effect + * @tc.type: FUNC + * @tc.require: AR000F8QO2 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StopVibrator_002, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Bounce"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, ERROR); + ret = StopVibrator(VIBRATOR_STOP_MODE_PRESET); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StopVibrator_003 + * @tc.desc: perform vibrator duration + * @tc.type: FUNC + * @tc.require: AR000F8QO2 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StopVibrator_003, TestSize.Level1) +{ + int32_t ret = StartVibratorOnce(5000); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); + ret = StopVibrator(VIBRATOR_STOP_MODE_PRESET); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: StopVibrator_004 + * @tc.desc: perform vibrator duration + * @tc.type: FUNC + * @tc.require: AR000F8QO2 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StopVibrator_004, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Bounce"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, ERROR); + ret = StopVibrator(VIBRATOR_STOP_MODE_TIME); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: StopVibrator_005 + * @tc.desc: stop vibrator preset effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, StopVibrator_005, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + ASSERT_EQ(ret, NO_ERROR); + ret = StopVibrator(VIBRATOR_STOP_MODE_PRESET); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: EnableLooping_001 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, EnableLooping_001, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Dream"; + EnableLooping(); + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + ASSERT_EQ(ret, NO_ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: EnableLooping_002 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, EnableLooping_002, TestSize.Level1) +{ + const char *supportString = "haptic.common.click"; + EnableLooping(); + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: EnableLooping_003 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, EnableLooping_003, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Cartoon"; + EnableLooping(); + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: EnableLooping_004 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, EnableLooping_004, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + EnableLooping(); + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + ASSERT_EQ(ret, ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: EnableLooping_005 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, EnableLooping_005, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + EnableLooping(); + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StartVibrator_001 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_001, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Cartoon"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); + EnableLooping(); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StartVibrator_002 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_002, TestSize.Level1) +{ + const char *supportString = "haptic.common.click"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + if (ret == ERROR) { + ASSERT_EQ(ret, ERROR); + EnableLooping(); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); + } +} + +/* + * @tc.name: StartVibrator_003 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_003, TestSize.Level1) +{ + const char *supportString = "haptic.ringtone.Cartoon"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StartVibrator_004 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_004, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, NO_ERROR); + EnableLooping(); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: StartVibrator_005 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_005, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + if (ret == 0) { + ASSERT_EQ(ret, NO_ERROR); + EnableLooping(); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); + } +} + +/* + * @tc.name: StartVibrator_006 + * @tc.desc: enable vibrator with effect + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, StartVibrator_006, TestSize.Level1) +{ + const char *supportString = "vibrator.haptic.default.time"; + int32_t ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, NO_ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: DisableLooping_001 + * @tc.desc: disable vibrator + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, DisableLooping_001, TestSize.Level1) +{ + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); +} + +/* + * @tc.name: DisableLooping_002 + * @tc.desc: disable vibrator + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, DisableLooping_002, TestSize.Level1) +{ + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + const char *supportString = "haptic.ringtone.Cartoon"; + ret = StartVibrator(supportString); + EnableLooping(); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: DisableLooping_003 + * @tc.desc: disable vibrator + * @tc.type: FUNC + * @tc.require: AR000FLCJ3 + * @tc.author: guofuqiang + */ +HWTEST_F(VibratorAgentNativeTest, DisableLooping_003, TestSize.Level1) +{ + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + EnableLooping(); + const char *supportString = "haptic.ringtone.Cartoon"; + ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, NO_ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: DisableLooping_004 + * @tc.desc: disable vibrator + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, DisableLooping_004, TestSize.Level1) +{ + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + const char *supportString = "vibrator.haptic.default.time"; + ret = StartVibrator(supportString); + EnableLooping(); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, NO_ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, NO_ERROR); +} + +/* + * @tc.name: DisableLooping_005 + * @tc.desc: disable vibrator + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangcaiyi + */ +HWTEST_F(VibratorAgentNativeTest, DisableLooping_005, TestSize.Level1) +{ + int32_t ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); + EnableLooping(); + const char *supportString = "vibrator.haptic.default.time"; + ret = StartVibrator(supportString); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ASSERT_EQ(ret, ERROR); + ret = DisableLooping(); + ASSERT_EQ(ret, ERROR); +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn new file mode 100755 index 0000000..ca7a472 --- /dev/null +++ b/interfaces/plugin/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#import("//build/config/ohos/rules.gni") +import("//build/ohos.gni") + +ohos_shared_library("vibrator_js") { + include_dirs = [ + "//third_party/node/src", + "//native_engine", + "../native/vibrator/include", + "./include", + "./vibrate/include", + "//utils/native/base/include" + ] + defines = [ + "APP_LOG_TAG = \"vibrateJs\"", + "LOG_DOMAIN = 0xD002700", + ] + + sources = [ + "./vibrate/src/vibrate_js.cpp", + "./vibrate/src/vibrator_napi_utils.cpp" + ] + + deps = [ + "//foundation/ace/napi:ace_napi", + "../native/vibrator:vibrator_interface_native", + "//utils/native/base:utils", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + relative_install_dir = "module" + part_name = "sensors_miscdevice" + subsystem_name = "sensors" +} + +group("vibrator_js_target") { + deps = [ ":vibrator_js" ] +} diff --git a/interfaces/plugin/vibrate/include/vibrator_napi_utils.h b/interfaces/plugin/vibrate/include/vibrator_napi_utils.h new file mode 100755 index 0000000..f072049 --- /dev/null +++ b/interfaces/plugin/vibrate/include/vibrator_napi_utils.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include + +struct AsyncCallbackInfo { + napi_env env; + napi_async_work asyncWork; + napi_deferred deferred; + napi_ref callback[1] = { 0 }; + int32_t status; +}; + +bool IsMatchType(napi_value value, napi_valuetype type, napi_env env); +napi_value GetNapiInt32(int32_t number, napi_env env); +int32_t GetCppInt32(napi_value value, napi_env env); +void EmitAsyncCallbackWork(AsyncCallbackInfo *async_callback_info); +int64_t GetCppInt64(napi_value value, napi_env env); +napi_value NapiGetNamedProperty(napi_value jsonObject, std::string name, napi_env env); +void EmitPromiseWork(AsyncCallbackInfo *asyncCallbackInfo); +std::string GetCppString(napi_value value, napi_env env); \ No newline at end of file diff --git a/interfaces/plugin/vibrate/src/vibrate_js.cpp b/interfaces/plugin/vibrate/src/vibrate_js.cpp new file mode 100755 index 0000000..29a192c --- /dev/null +++ b/interfaces/plugin/vibrate/src/vibrate_js.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "hilog/log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "vibrator_agent.h" +#include "vibrator_napi_utils.h" + +using namespace OHOS::HiviewDFX; +static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002757, "VibrateJsAPI" }; +constexpr int32_t ARGS_LENGTH = 2; + +static napi_value Vibrate(napi_env env, napi_callback_info info) +{ + size_t argc; + napi_value args[2]; + napi_value thisArg; + napi_value result; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr)); + if (argc == ARGS_LENGTH) { + if (!IsMatchType(args[1], napi_function, env) || + (!IsMatchType(args[0], napi_number, env) && !IsMatchType(args[0], napi_string, env))) { + HiLog::Error(LABEL, "%{public}s input parameter type does not match", __func__); + napi_get_undefined(env, &result); + return result; + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + if (IsMatchType(args[0], napi_number, env)) { + int32_t duration = GetCppInt32(args[0], env); + asyncCallbackInfo->status = StartVibratorOnce(duration); + } else if (IsMatchType(args[0], napi_string, env)) { + size_t bufLength = 0; + napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &bufLength); + char *buff = (char *)malloc((bufLength + 1) * sizeof(char)); + status = napi_get_value_string_utf8(env, args[0], buff, bufLength + 1, &bufLength); + asyncCallbackInfo->status = StartVibrator(buff); + } + EmitAsyncCallbackWork(asyncCallbackInfo); + } else if (argc == 1) { + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_deferred deferred; + napi_value promise; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + if (IsMatchType(args[0], napi_number, env)) { + int32_t duration = GetCppInt32(args[0], env); + asyncCallbackInfo->status = StartVibratorOnce(duration); + } else if (IsMatchType(args[0], napi_string, env)) { + size_t bufLength = 0; + napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &bufLength); + char *buff = (char *)malloc((bufLength + 1) * sizeof(char)); + status = napi_get_value_string_utf8(env, args[0], buff, bufLength + 1, &bufLength); + asyncCallbackInfo->status = StartVibrator(buff); + } else { + HiLog::Error(LABEL, "%{public}s input parameter type does not match", __func__); + return nullptr; + } + EmitPromiseWork(asyncCallbackInfo); + return promise; + } else { + HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__); + } + napi_get_undefined(env, &result); + return result; +} + +static napi_value Stop(napi_env env, napi_callback_info info) +{ + size_t argc; + napi_value args[2]; + napi_value thisArg; + napi_value result; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr)); + if (argc == ARGS_LENGTH) { + if (!IsMatchType(args[1], napi_function, env) || !IsMatchType(args[0], napi_string, env)) { + HiLog::Error(LABEL, "%{public}s input parameter type does not match", __func__); + napi_get_undefined(env, &result); + return result; + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + const char *mode = GetCppString(args[0], env).c_str(); + asyncCallbackInfo->status = StopVibrator(mode); + EmitAsyncCallbackWork(asyncCallbackInfo); + } else if (argc == 1) { + if (!IsMatchType(args[0], napi_string, env)) { + HiLog::Error(LABEL, "%{public}s input parameter type does not match", __func__); + return nullptr; + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_deferred deferred; + napi_value promise; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + const char *mode = GetCppString(args[0], env).c_str(); + asyncCallbackInfo->status = StopVibrator(mode); + EmitPromiseWork(asyncCallbackInfo); + return promise; + } else { + HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__); + } + napi_get_undefined(env, &result); + return result; +} + +EXTERN_C_START + +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("vibrate", Vibrate), + DECLARE_NAPI_FUNCTION("stop", Stop) + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc)); + return exports; +} +EXTERN_C_END + +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = NULL, + .nm_register_func = Init, + .nm_modname = "vibrator", + .nm_priv = ((void *)0), + .reserved = {0} +}; + +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} diff --git a/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp b/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp new file mode 100755 index 0000000..d6b6508 --- /dev/null +++ b/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "vibrator_napi_utils.h" +#include +#include "hilog/log.h" + + +using namespace OHOS::HiviewDFX; +static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "VibrateJsAPI"}; +constexpr int32_t BUF_LENGTH = 256; + +bool IsMatchType(napi_value value, napi_valuetype type, napi_env env) +{ + napi_valuetype paramType; + napi_typeof(env, value, ¶mType); + if (paramType != type) { + HiLog::Error(LABEL, "%{public}s failed!", __func__); + return false; + } + return true; +} + +napi_value GetNapiInt32(int32_t number, napi_env env) +{ + napi_value value; + napi_create_int32(env, number, &value); + return value; +} + +napi_value NapiGetNamedProperty(napi_value jsonObject, std::string name, napi_env env) +{ + napi_value value; + napi_get_named_property(env, jsonObject, name.c_str(), &value); + return value; +} + +int32_t GetCppInt32(napi_value value, napi_env env) +{ + int32_t number; + napi_get_value_int32(env, value, &number); + return number; +} + +std::string GetCppString(napi_value value, napi_env env) +{ + size_t bufLength = 0; + napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength); + char *buff = (char *)malloc((bufLength + 1) * sizeof(char)); + if (buff == nullptr) { + HiLog::Error(LABEL, "js obj to str malloc failed"); + } + status = napi_get_value_string_utf8(env, value, buff, bufLength + 1, &bufLength); + return buff; +} + +int64_t GetCppInt64(napi_value value, napi_env env) +{ + int64_t number; + napi_get_value_int64(env, value, &number); + return number; +} + +void EmitAsyncCallbackWork(AsyncCallbackInfo *asyncCallbackInfo) +{ + HiLog::Debug(LABEL, "%s begin", __func__); + if (asyncCallbackInfo == nullptr) { + HiLog::Error(LABEL, "%s asyncCallbackInfo is nullptr!", __func__); + return; + } + napi_value resourceName; + napi_create_string_latin1(asyncCallbackInfo->env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName); + napi_create_async_work( + asyncCallbackInfo->env, nullptr, resourceName, [](napi_env env, void* data) {}, + [](napi_env env, napi_status status, void* data) { + AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + napi_value callback; + napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback); + napi_value result = nullptr; + napi_value callResult = nullptr; + if (asyncCallbackInfo->status < 0) { + napi_value code = nullptr; + napi_value message = nullptr; + napi_create_string_utf8(env, "-1", NAPI_AUTO_LENGTH, &code); + napi_create_string_utf8(env, "failed", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, code, message, &result); + } else { + napi_get_undefined(env, &result); + } + napi_call_function(env, nullptr, callback, 2, &result, &callResult); + napi_delete_reference(env, asyncCallbackInfo->callback[0]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + }, + asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork); + HiLog::Debug(LABEL, "%{public}s end", __func__); +} + +void EmitPromiseWork(AsyncCallbackInfo *asyncCallbackInfo) +{ + if (asyncCallbackInfo == nullptr) { + HiLog::Error(LABEL, "%s asyncCallbackInfo is nullptr!", __func__); + return; + } + napi_value resourceName; + napi_create_string_latin1(asyncCallbackInfo->env, "Promise", NAPI_AUTO_LENGTH, &resourceName); + napi_create_async_work( + asyncCallbackInfo->env, nullptr, resourceName, [](napi_env env, void* data) {}, + [](napi_env env, napi_status status, void* data) { + AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + napi_value message = nullptr; + if (asyncCallbackInfo->status == 0) { + napi_get_undefined(env, &message); + napi_resolve_deferred(env, asyncCallbackInfo->deferred, message); + } else { + napi_create_int32(env, asyncCallbackInfo->status, &message); + napi_reject_deferred(env, asyncCallbackInfo->deferred, message); + } + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + }, + (void*)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork); +} \ No newline at end of file diff --git a/ohos.build b/ohos.build new file mode 100755 index 0000000..0ee758e --- /dev/null +++ b/ohos.build @@ -0,0 +1,32 @@ +{ + "subsystem": "sensors", + "parts": { + "sensors_miscdevice": { + "module_list": [ + "//base/sensors/sensors_miscdevice/interfaces/native/vibrator:vibrator_target", + "//base/sensors/sensors_miscdevice/interfaces/plugin:vibrator_js_target", + "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice:miscdevice_native_target", + "//base/sensors/sensors_miscdevice/services/miscdevice_service:miscdevice_service_target", + "//base/sensors/sensors_miscdevice/sa_profile:sensors_sa_profiles", + "//base/sensors/sensors_miscdevice/utils:miscdevice_utils_target" + ], + "inner_kits": [ + { + "header": { + "header_files": [ + "vibrator_agent.h", + "vibrator_agent_type.h" + ], + "header_base": "//base/sensors/sensors_miscdevice/interfaces/native/vibrator/include" + }, + "name": "//base/sensors/sensors_miscdevice/interfaces/native/vibrator:vibrator_interface_native" + } + ], + "test_list": [ + "//base/sensors/sensors_miscdevice/interfaces/native/vibrator/test:unittest", + "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice/test:unittest", + "//base/sensors/sensors_miscdevice/services/miscdevice_service/test:unittest" + ] + } + } +} -- Gitee From 343b98116b9bca864354a6cdc4a216f645e6bf8f Mon Sep 17 00:00:00 2001 From: h00514358 Date: Tue, 14 Sep 2021 02:32:38 +0000 Subject: [PATCH 2/3] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- interfaces/native/vibrator/BUILD.gn | 8 ++++---- interfaces/native/vibrator/test/BUILD.gn | 6 +++--- interfaces/plugin/BUILD.gn | 15 +++++++-------- ohos.build | 22 +++++++++++----------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/interfaces/native/vibrator/BUILD.gn b/interfaces/native/vibrator/BUILD.gn index 76eb7fe..578fad4 100755 --- a/interfaces/native/vibrator/BUILD.gn +++ b/interfaces/native/vibrator/BUILD.gn @@ -13,7 +13,7 @@ import("//build/ohos.gni") -SUBSYSTEM_DIR = "//base/sensors/sensors_miscdevice" +SUBSYSTEM_DIR = "//base/sensors/miscdevice" ohos_ndk_library("libvibrator_ndk") { output_name = "vibrator" ndk_description_file = "./libvibrator.json" @@ -39,8 +39,8 @@ ohos_shared_library("vibrator_interface_native") { include_dirs = [ "include", "//utils/native/base/include", - "//base/sensors/sensors_miscdevice/utils/include", - "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice/include", + "//base/sensors/miscdevice/utils/include", + "//base/sensors/miscdevice/frameworks/native/miscdevice/include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", ] @@ -49,8 +49,8 @@ ohos_shared_library("vibrator_interface_native") { deps = [ "$SUBSYSTEM_DIR/frameworks/native/miscdevice:libvibrator_native", "$SUBSYSTEM_DIR/interfaces/native/vibrator:libvibrator_ndk", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", "//utils/native/base:utils", - "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core" ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/interfaces/native/vibrator/test/BUILD.gn b/interfaces/native/vibrator/test/BUILD.gn index dc47e7a..04df433 100755 --- a/interfaces/native/vibrator/test/BUILD.gn +++ b/interfaces/native/vibrator/test/BUILD.gn @@ -25,12 +25,12 @@ ohos_unittest("VibratorNDKTest") { "../include", "//utils/native/base/include", "//utils/system/safwk/native/include", - "$SUBSYSTEM_DIR/sensors_miscdevice/utils/include", + "$SUBSYSTEM_DIR/miscdevice/utils/include", ] deps = [ - "$SUBSYSTEM_DIR/sensors_miscdevice/interfaces/native/vibrator:vibrator_interface_native", - "$SUBSYSTEM_DIR/sensors_miscdevice/utils:libmiscdevice_utils", + "$SUBSYSTEM_DIR/miscdevice/interfaces/native/vibrator:vibrator_interface_native", + "$SUBSYSTEM_DIR/miscdevice/utils:libmiscdevice_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//utils/native/base:utils", diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn index ca7a472..f0491d4 100755 --- a/interfaces/plugin/BUILD.gn +++ b/interfaces/plugin/BUILD.gn @@ -13,7 +13,6 @@ #import("//build/config/ohos/rules.gni") import("//build/ohos.gni") - ohos_shared_library("vibrator_js") { include_dirs = [ "//third_party/node/src", @@ -21,21 +20,21 @@ ohos_shared_library("vibrator_js") { "../native/vibrator/include", "./include", "./vibrate/include", - "//utils/native/base/include" + "//utils/native/base/include", + ] + defines = [ + "APP_LOG_TAG = \"vibrateJs\"", + "LOG_DOMAIN = 0xD002700", ] - defines = [ - "APP_LOG_TAG = \"vibrateJs\"", - "LOG_DOMAIN = 0xD002700", - ] sources = [ "./vibrate/src/vibrate_js.cpp", - "./vibrate/src/vibrator_napi_utils.cpp" + "./vibrate/src/vibrator_napi_utils.cpp", ] deps = [ - "//foundation/ace/napi:ace_napi", "../native/vibrator:vibrator_interface_native", + "//foundation/ace/napi:ace_napi", "//utils/native/base:utils", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/ohos.build b/ohos.build index 0ee758e..0013fbc 100755 --- a/ohos.build +++ b/ohos.build @@ -3,12 +3,12 @@ "parts": { "sensors_miscdevice": { "module_list": [ - "//base/sensors/sensors_miscdevice/interfaces/native/vibrator:vibrator_target", - "//base/sensors/sensors_miscdevice/interfaces/plugin:vibrator_js_target", - "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice:miscdevice_native_target", - "//base/sensors/sensors_miscdevice/services/miscdevice_service:miscdevice_service_target", - "//base/sensors/sensors_miscdevice/sa_profile:sensors_sa_profiles", - "//base/sensors/sensors_miscdevice/utils:miscdevice_utils_target" + "//base/sensors/miscdevice/interfaces/native/vibrator:vibrator_target", + "//base/sensors/miscdevice/interfaces/plugin:vibrator_js_target", + "//base/sensors/miscdevice/frameworks/native/miscdevice:miscdevice_native_target", + "//base/sensors/miscdevice/services/miscdevice_service:miscdevice_service_target", + "//base/sensors/miscdevice/sa_profile:sensors_sa_profiles", + "//base/sensors/miscdevice/utils:miscdevice_utils_target" ], "inner_kits": [ { @@ -17,15 +17,15 @@ "vibrator_agent.h", "vibrator_agent_type.h" ], - "header_base": "//base/sensors/sensors_miscdevice/interfaces/native/vibrator/include" + "header_base": "//base/sensors/miscdevice/interfaces/native/vibrator/include" }, - "name": "//base/sensors/sensors_miscdevice/interfaces/native/vibrator:vibrator_interface_native" + "name": "//base/sensors/miscdevice/interfaces/native/vibrator:vibrator_interface_native" } ], "test_list": [ - "//base/sensors/sensors_miscdevice/interfaces/native/vibrator/test:unittest", - "//base/sensors/sensors_miscdevice/frameworks/native/miscdevice/test:unittest", - "//base/sensors/sensors_miscdevice/services/miscdevice_service/test:unittest" + "//base/sensors/miscdevice/interfaces/native/vibrator/test:unittest", + "//base/sensors/miscdevice/frameworks/native/miscdevice/test:unittest", + "//base/sensors/miscdevice/services/miscdevice_service/test:unittest" ] } } -- Gitee From 951782274ba5f4ce56447ee0091e78857e4dd53f Mon Sep 17 00:00:00 2001 From: h00514358 Date: Tue, 14 Sep 2021 12:27:33 +0000 Subject: [PATCH 3/3] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp b/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp index d6b6508..ce5e980 100755 --- a/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp +++ b/interfaces/plugin/vibrate/src/vibrator_napi_utils.cpp @@ -20,7 +20,6 @@ using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "VibrateJsAPI"}; -constexpr int32_t BUF_LENGTH = 256; bool IsMatchType(napi_value value, napi_valuetype type, napi_env env) { -- Gitee