From 80f30e29241e4c59298053f9bff019efbcf23182 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Mon, 13 Sep 2021 13:02:55 +0000 Subject: [PATCH 1/5] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- OAT.xml | 82 +++ README.en.md | 36 -- README.md | 215 ++++++- README_zh.md | 200 ++++++ figures/en-us_image_0000001199027515.png | Bin 0 -> 22250 bytes figures/zh-cn_image_0000001199027515.png | Bin 0 -> 24260 bytes frameworks/native/sensor/BUILD.gn | 65 ++ .../native/sensor/include/i_sensor_client.h | 33 + .../native/sensor/include/i_sensor_service.h | 65 ++ .../native/sensor/include/my_event_handler.h | 37 ++ .../include/my_file_descriptor_listener.h | 52 ++ .../sensor/include/sensor_agent_proxy.h | 56 ++ .../sensor/include/sensor_client_proxy.h | 39 ++ .../sensor/include/sensor_client_stub.h | 36 ++ .../sensor/include/sensor_data_channel.h | 55 ++ .../sensor/include/sensor_service_client.h | 59 ++ .../include/sensor_service_proxy copy.h | 45 ++ .../sensor/include/sensor_service_proxy.h | 46 ++ .../native/sensor/src/my_event_handler.cpp | 35 ++ .../src/my_file_descriptor_listener.cpp | 95 +++ .../native/sensor/src/sensor_agent_proxy.cpp | 351 +++++++++++ .../native/sensor/src/sensor_data_channel.cpp | 198 ++++++ .../sensor/src/sensor_service_client.cpp | 220 +++++++ .../sensor/src/sensor_service_proxy.cpp | 234 +++++++ frameworks/native/sensor/test/BUILD.gn | 25 + .../sensor/test/unittest/common/BUILD.gn | 95 +++ .../test/unittest/common/sensor_dfx_test.cpp | 131 ++++ .../unittest/common/sensor_native_test.cpp | 185 ++++++ .../sensor/test/unittest/phone/BUILD.gn | 58 ++ .../unittest/phone/sensor_native_test.cpp | 110 ++++ interfaces/native/BUILD.gn | 55 ++ interfaces/native/include/sensor_agent.h | 137 ++++ interfaces/native/include/sensor_agent_type.h | 464 ++++++++++++++ interfaces/native/libsensor.json | 24 + interfaces/native/src/sensor_agent.cpp | 120 ++++ interfaces/native/test/BUILD.gn | 49 ++ .../test/unittest/sensor_agent_test.cpp | 95 +++ interfaces/plugin/BUILD.gn | 47 ++ interfaces/plugin/include/sensor_js.h | 20 + interfaces/plugin/include/sensor_napi_utils.h | 41 ++ interfaces/plugin/src/sensor_js.cpp | 294 +++++++++ interfaces/plugin/src/sensor_napi_utils.cpp | 172 +++++ interfaces/plugin/test/unittest/BUILD.gn | 61 ++ .../plugin/test/unittest/sensor_js_test.cpp | 595 ++++++++++++++++++ ohos.build | 39 ++ sa_profile/3601.xml | 24 + sa_profile/BUILD.gn | 19 + utils/BUILD.gn | 59 ++ utils/include/app_thread_info.h | 29 + utils/include/death_recipient_template.h | 38 ++ utils/include/dmd_report.h | 52 ++ utils/include/miscdevice_common.h | 46 ++ utils/include/permission_util.h | 57 ++ utils/include/report_data_callback.h | 48 ++ utils/include/sensor.h | 71 +++ utils/include/sensor_basic_data_channel.h | 64 ++ utils/include/sensor_basic_info.h | 47 ++ utils/include/sensor_catalog.h | 91 +++ utils/include/sensor_channel_info.h | 52 ++ utils/include/sensor_data_event.h | 53 ++ utils/include/sensors_errors.h | 127 ++++ utils/include/sensors_log_domain.h | 34 + utils/src/dmd_report.cpp | 102 +++ utils/src/miscdevice_common.cpp | 59 ++ utils/src/permission_util.cpp | 123 ++++ utils/src/report_data_callback.cpp | 102 +++ utils/src/sensor.cpp | 232 +++++++ utils/src/sensor_basic_data_channel.cpp | 216 +++++++ utils/src/sensor_basic_info.cpp | 53 ++ utils/src/sensor_channel_info.cpp | 83 +++ 70 files changed, 6889 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_0000001199027515.png create mode 100755 figures/zh-cn_image_0000001199027515.png create mode 100755 frameworks/native/sensor/BUILD.gn create mode 100755 frameworks/native/sensor/include/i_sensor_client.h create mode 100755 frameworks/native/sensor/include/i_sensor_service.h create mode 100755 frameworks/native/sensor/include/my_event_handler.h create mode 100755 frameworks/native/sensor/include/my_file_descriptor_listener.h create mode 100755 frameworks/native/sensor/include/sensor_agent_proxy.h create mode 100755 frameworks/native/sensor/include/sensor_client_proxy.h create mode 100755 frameworks/native/sensor/include/sensor_client_stub.h create mode 100755 frameworks/native/sensor/include/sensor_data_channel.h create mode 100755 frameworks/native/sensor/include/sensor_service_client.h create mode 100755 frameworks/native/sensor/include/sensor_service_proxy copy.h create mode 100755 frameworks/native/sensor/include/sensor_service_proxy.h create mode 100755 frameworks/native/sensor/src/my_event_handler.cpp create mode 100755 frameworks/native/sensor/src/my_file_descriptor_listener.cpp create mode 100755 frameworks/native/sensor/src/sensor_agent_proxy.cpp create mode 100755 frameworks/native/sensor/src/sensor_data_channel.cpp create mode 100755 frameworks/native/sensor/src/sensor_service_client.cpp create mode 100755 frameworks/native/sensor/src/sensor_service_proxy.cpp create mode 100755 frameworks/native/sensor/test/BUILD.gn create mode 100755 frameworks/native/sensor/test/unittest/common/BUILD.gn create mode 100755 frameworks/native/sensor/test/unittest/common/sensor_dfx_test.cpp create mode 100755 frameworks/native/sensor/test/unittest/common/sensor_native_test.cpp create mode 100755 frameworks/native/sensor/test/unittest/phone/BUILD.gn create mode 100755 frameworks/native/sensor/test/unittest/phone/sensor_native_test.cpp create mode 100755 interfaces/native/BUILD.gn create mode 100755 interfaces/native/include/sensor_agent.h create mode 100755 interfaces/native/include/sensor_agent_type.h create mode 100755 interfaces/native/libsensor.json create mode 100755 interfaces/native/src/sensor_agent.cpp create mode 100755 interfaces/native/test/BUILD.gn create mode 100755 interfaces/native/test/unittest/sensor_agent_test.cpp create mode 100755 interfaces/plugin/BUILD.gn create mode 100755 interfaces/plugin/include/sensor_js.h create mode 100755 interfaces/plugin/include/sensor_napi_utils.h create mode 100755 interfaces/plugin/src/sensor_js.cpp create mode 100755 interfaces/plugin/src/sensor_napi_utils.cpp create mode 100755 interfaces/plugin/test/unittest/BUILD.gn create mode 100755 interfaces/plugin/test/unittest/sensor_js_test.cpp create mode 100755 ohos.build create mode 100755 sa_profile/3601.xml create mode 100755 sa_profile/BUILD.gn create mode 100755 utils/BUILD.gn create mode 100755 utils/include/app_thread_info.h create mode 100755 utils/include/death_recipient_template.h create mode 100755 utils/include/dmd_report.h create mode 100755 utils/include/miscdevice_common.h create mode 100755 utils/include/permission_util.h create mode 100755 utils/include/report_data_callback.h create mode 100755 utils/include/sensor.h create mode 100755 utils/include/sensor_basic_data_channel.h create mode 100755 utils/include/sensor_basic_info.h create mode 100755 utils/include/sensor_catalog.h create mode 100755 utils/include/sensor_channel_info.h create mode 100755 utils/include/sensor_data_event.h create mode 100755 utils/include/sensors_errors.h create mode 100755 utils/include/sensors_log_domain.h create mode 100755 utils/src/dmd_report.cpp create mode 100755 utils/src/miscdevice_common.cpp create mode 100755 utils/src/permission_util.cpp create mode 100755 utils/src/report_data_callback.cpp create mode 100755 utils/src/sensor.cpp create mode 100755 utils/src/sensor_basic_data_channel.cpp create mode 100755 utils/src/sensor_basic_info.cpp create mode 100755 utils/src/sensor_channel_info.cpp diff --git a/OAT.xml b/OAT.xml new file mode 100755 index 00000000..9c356f7c --- /dev/null +++ b/OAT.xml @@ -0,0 +1,82 @@ + + + + + + LICENSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index fbdac5fb..00000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# sensors_sensor - -#### 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 6a0d19f0..ce59576b --- a/README.md +++ b/README.md @@ -1,39 +1,200 @@ -# sensors_sensor +# Sensor -#### 介绍 -{**以下是 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](#section1543714111810) -#### 软件架构 -软件架构说明 +- [Repositories Involved](#section96071132185310) +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The APIs of this module are supported since API version 7. -#### 安装教程 +## Introduction -1. xxxx -2. xxxx -3. xxxx +A sensor is a device to detect events or changes in an environment and send messages about the events or changes to another device \(for example, a CPU\). Generally, a sensor is composed of sensitive components and conversion components. Sensors are the cornerstone of the IoT. A unified sensor management framework is required to achieve data sensing at a low latency and low power consumption, thereby keeping up with requirements of "1+8+N" products or business in the Seamless AI Life Strategy. Based on the usage, sensors are divided into the following categories: -#### 使用说明 +- Motion: acceleration sensors, gyroscope sensors, gravity sensors, linear acceleration sensors, etc. +- Orientation: rotation vector sensors, orientation sensors, etc. +- Environment: magnetic field sensors, barometric pressure sensors, humidity sensors, etc. +- Light: ambient light sensors, proximity sensors, color temperature sensors, etc. +- Body: heart rate sensors, heartbeat sensors, etc. +- Other: Hall effect sensors, grip detection sensors, etc. -1. xxxx -2. xxxx -3. xxxx +The following figure shows the sensor architecture. -#### 参与贡献 +**Figure 1** Sensor architecture -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +![](figures/en-us_image_0000001199027515.png) -#### 特技 +## Directory Structure + +The sample code for importing the sensor module is as follows: + +``` +/base/sensors/sensors_sensor +├── frameworks # Framework code +│ └── native # Sensor client code +├── interfaces # External APIs +│ ├── native # Native Implementation for sensors +│ └── plugin # JS APIs +├── sa_profile # Configuration file of system ability names and dynamic libraries +├── services # Code of services +│ └── sensor # Sensor service for reporting data about sensors, such as the acceleration and gyroscope sensors +└── utils # Common code, including permissions and communication capabilities +``` + +## Constraints + +- To use sensor functions, ensure that the device where your application runs has the required sensor components. + +- To obtain data of some sensors, you need to request the required permissions. + + **Table 1** Permissions required by sensors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Sensor

+

Permission Name

+

Sensitivity

+

Permission Description

+

Acceleration sensor, uncalibrated acceleration sensor, and linear acceleration sensor

+

ohos.permission.ACCELEROMETER

+

system_grant

+

Allows an application to subscribe to data of these acceleration-related sensors.

+

Gyroscope sensor and uncalibrated gyroscope sensor

+

ohos.permission.GYROSCOPE

+

system_grant

+

Allows an application to subscribe to data of these gyroscope-related sensors.

+

Pedometer sensor

+

ohos.permission.ACTIVITY_MOTION

+

user_grant

+

Allows an application to subscribe to the motion status.

+

Heart rate sensor

+

ohos.permission.READ_HEALTH_DATA

+

user_grant

+

Allows an application to read health data.

+
+ + +## Usage + +This section uses the sensor JS APIs as an example to describe their functionalities and usage. + +### Available APIs + +The sensor JS APIs listen for sensor data changes. If an API is called multiple times, the last call takes effect. The following table describes these APIs. + +**Table 2** Sensor JS APIs + + + + + + + + + + + + + + + + +

API

+

Description

+

on(type: SensorType, callback: AsyncCallback<Response>, options?: Options)

+

Subscribes to a type of sensor that listens for changes of sensor data. SensorType indicates the type of the sensor that can be subscribed to. callback specifies whether the subscription is successful. options indicates the interval for reporting sensor data.

+

once(type: SensorType, callback: AsyncCallback<Response>)

+

Subscribes to a type of sensor that listens for the sensor data change once. SensorType indicates the type of the sensor that can be subscribed to. callback specifies whether the subscription is successful.

+

off(type: SensorType, callback: AsyncCallback<void>)

+

Unsubscribes from a type of sensor that listens for data changes. SensorType indicates the type of the sensor that can be unsubscribed from. callback specifies whether the unsubscription is successful.

+
+ +### How to Use + +1. Import the sensor package. +2. Subscribe to and listen for data changes of an acceleration sensor. +3. Unsubscribe from data changes of the acceleration sensor. +4. Subscribe to and listen for a data change of a gravity sensor. + +Example: + +``` +// Step 1 Import the sensor package. +import sensor from '@ohos.sensor'; +export default { + onCreate() { + // Step 2 Subscribe to and listen for data changes of a type of sensor. + sensor.on(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (error, data) => { + if (error) { + console.error("Failed to subscribe to acceleration data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Acceleration data obtained. x: " + data.x + "; y: " + data.y + "; z: " + data.z); + }, {'interval':200000000}); + // Step 3 Unsubscribe from data changes of the sensor 10 seconds later. + setTimeout(function(){ + sensor.off(SensorType.SENSOR_TYPE_ID_ACCELEROMETER, function(error) { + if (error) { + console.error("Failed to unsubscribe from acceleration data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in unsubscribe from sensor data"); + }); + } ,10000); + // Step 4 Subscribe to and listen for a data change of a type of sensor. + sensor.once(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (error, data) => { + if (error) { + console.error("Failed to subscribe to gravity data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Gravity data obtained. x: " + data.x + "; y: " + data.y + "; z: " + data.z); + }); + } + 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 00000000..93dc535d --- /dev/null +++ b/README_zh.md @@ -0,0 +1,200 @@ +# Sensor组件 + +- [简介](#section11660541593) +- [目录](#section44981327519) +- [约束](#section98068674513) +- [使用](#section1581412211528) + - [接口说明](#section15684191115524) + - [使用说明](#section1543714111810) + +- [相关仓](#section96071132185310) + +>![](public_sys-resources/icon-note.gif) **说明:** +>从API Version 7 开始支持。 + +## 简介 + +传感器是指用于侦测环境中所发生事件或变化,并将此消息发送至其他电子设备(如中央处理器)的设备,通常由敏感组件和转换组件组成。传感器是实现物联网智能化的重要基石,为实现全场景智慧化战略,支撑“1+8+N”产品需求,需要构筑统一的传感器管理框架,达到为各产品/业务提供低时延、低功耗的感知数据的目的。根据用途可分为以下六大类: + +- 运动类:加速度、陀螺仪、重力、线性加速度传感器等 +- 姿态类:旋转矢量、方向传感器等 +- 环境类:磁力计、气压、湿度传感器等 +- 光线类:环境光、接近光、色温传感器等 +- 健康类:心率、心跳传感器等 +- 其它:霍尔传感器、手握传感器等 + +传感器架构图如下所示: + +**图 1** Sensor架构图 + + +![](figures/zh-cn_image_0000001199027515.png) + +## 目录 + +sensor导入模块的示例代码如下: + +``` +/base/sensors/sensors_sensor +├── frameworks # 框架代码 +│ └── native # sensor客户端代码 +├── interfaces # 对外接口存放目录 +│ ├── native # sensor native实现 +│ └── plugin # Js API +├── sa_profile # 服务名称和服务的动态库的配置文件 +├── services # 服务的代码目录 +│ └── sensor # 传感器服务,包括加速度、陀螺仪等,上报传感器数据 +└── utils # 公共代码,包括权限、通信等能力 +``` + +## 约束 + +- 要使用传感器的功能,设备必须具有对应的传感器器件。 + +- 针对某些传感器,开发者需要请求相应的权限,才能获取到相应传感器的数据。 + + **表 1** 传感器权限列表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

传感器

+

权限名

+

敏感级别

+

权限描述

+

加速度传感器、加速度未校准传感器、线性加速度传感器

+

ohos.permission.ACCELEROMETER

+

system_grant

+

允许订阅加速度传感器的数据。

+

陀螺仪传感器、陀螺仪未校准传感器

+

ohos.permission.GYROSCOPE

+

system_grant

+

允许订阅陀螺仪传感器的数据。

+

计步器

+

ohos.permission.ACTIVITY_MOTION

+

user_grant

+

允许订阅运动状态。

+

心率传感器

+

ohos.permission.READ_HEALTH_DATA

+

user_grant

+

允许读取健康数据。

+
+ + +## 使用 + +本节以传感器 JS API为例,说明其提供的具体功能以及使用流程。 + +### 接口说明 + +传感器 JS API:监听传感器数据变化,如果多次调用该接口,则最后一次调用生效。JS API开放的能力如下: + +**表 2** JS API的主要接口 + + + + + + + + + + + + + + + + +

接口名

+

描述

+

on(type: SensorType, callback: AsyncCallback<Response>, options?: Options)

+

监听传感器数据变化。SensorType为支持订阅的传感器类型,callback表示订阅传感器的回调函数,options为设置传感器数据上报的时间间隔。

+

once(type: SensorType, callback: AsyncCallback<Response>)

+

监听传感器数据变化一次。SensorType为支持订阅的传感器类型,callback表示订阅传感器的回调函数。

+

off(type: SensorType, callback: AsyncCallback<void>)

+

取消订阅传感器数据。SensorType为支持的取消订阅的传感器类型,callback表示取消订阅传感器是否成功。

+
+ +### 使用说明 + +1. 导包。 +2. 注册并监听加速度传感器数据的变化。 +3. 取消订阅加速度传感器数据的变化。 +4. 注册并监听重力传感器数据的变化一次。 + +示例代码: + +``` +//步骤1 导包 +import sensor from '@ohos.sensor'; +export default { + onCreate() { + //步骤2 监听传感器数据变化,并注册传感器类型 + sensor.on(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (error, data) => { + if (error) { + console.error("Failed to subscribe to acceleration data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Acceleration data obtained. x: " + data.x + "; y: " + data.y + "; z: " + data.z); + }, {'interval':200000000}); + //步骤3 设置10秒后取消订阅传感器数据 + setTimeout(function(){ + sensor.off(SensorType.SENSOR_TYPE_ID_ACCELEROMETER, function(error) { + if (error) { + console.error("Failed to unsubscribe from acceleration data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Succeeded in unsubscribe from sensor data"); + }); + } ,10000); + //步骤4 监听传感器数据变化一次,并注册传感器类型 + sensor.once(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (error, data) => { + if (error) { + console.error("Failed to subscribe to gravity data. Error code: " + error.code + "; message: " + error.message); + return; + } + console.info("Gravity data obtained. x: " + data.x + "; y: " + data.y + "; z: " + data.z); + }); + } + onDestroy() { + console.info('AceApplication onDestroy'); + } +} +``` + +## 相关仓 + +泛Sensor服务子系统 + +sensors\_start + +**sensors\_sensor** + +sensors\_miscdevice + diff --git a/figures/en-us_image_0000001199027515.png b/figures/en-us_image_0000001199027515.png new file mode 100755 index 0000000000000000000000000000000000000000..0466444dc0f6c126b0e1c7e2a2e673f77ea04611 GIT binary patch literal 22250 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⩔zyo&e(SCuviInE-wO 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 V!04+T2l{D$voNtSt~YXj@L#9Qwj%%l literal 0 HcmV?d00001 diff --git a/figures/zh-cn_image_0000001199027515.png b/figures/zh-cn_image_0000001199027515.png new file mode 100755 index 0000000000000000000000000000000000000000..8ee23421356979ef07df9202ca9225036c841407 GIT binary patch literal 24260 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 + +#include "errors.h" +#include "i_sensor_client.h" +#include "iremote_broker.h" +#include "sensor.h" +#include "sensor_basic_data_channel.h" + +namespace OHOS { +namespace Sensors { +class ISensorService : public IRemoteBroker { +public: + ISensorService() = default; + + virtual ~ISensorService() = default; + + DECLARE_INTERFACE_DESCRIPTOR(u"ISensorService"); + + virtual ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, + int64_t maxReportDelayNs) = 0; + + virtual ErrCode DisableSensor(uint32_t sensorId) = 0; + + virtual int32_t GetSensorState(uint32_t sensorId) = 0; + + virtual ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) = 0; + + virtual std::vector GetSensorList() = 0; + + virtual ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) = 0; + + virtual ErrCode DestroySensorChannel(sptr sensorClient) = 0; + + enum { + ENABLE_SENSOR = 0, + DISABLE_SENSOR, + GET_SENSOR_STATE, + RUN_COMMAND, + GET_SENSOR_LIST, + TRANSFER_DATA_CHANNEL, + DESTROY_SENSOR_CHANNEL, + }; +}; +} // namespace Sensors +} // namespace OHOS +#endif // I_SENSOR_SERVICE_H diff --git a/frameworks/native/sensor/include/my_event_handler.h b/frameworks/native/sensor/include/my_event_handler.h new file mode 100755 index 00000000..3b89c93b --- /dev/null +++ b/frameworks/native/sensor/include/my_event_handler.h @@ -0,0 +1,37 @@ +/* + * 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 MY_EVENT_HANDLER_H +#define MY_EVENT_HANDLER_H + +#include "event_handler.h" +#include "event_runner.h" + +namespace OHOS { +namespace Sensors { +class MyEventHandler : public AppExecFwk::EventHandler { +public: + explicit MyEventHandler(const std::shared_ptr &runner); + ~MyEventHandler() = default; + + /** + * Function: Process the event. Override the method of base class. + * @param event The event need to be processed. + */ + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; +}; +} // namespace Sensors +} // namespace OHOS +#endif // MY_EVENT_HANDLER_H \ No newline at end of file diff --git a/frameworks/native/sensor/include/my_file_descriptor_listener.h b/frameworks/native/sensor/include/my_file_descriptor_listener.h new file mode 100755 index 00000000..fc7f16d5 --- /dev/null +++ b/frameworks/native/sensor/include/my_file_descriptor_listener.h @@ -0,0 +1,52 @@ +/* + * 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 MY_FILE_DESCRIPTOR_LISTENER_H +#define MY_FILE_DESCRIPTOR_LISTENER_H + +#include +#include +#include + +#include "event_handler.h" +#include "event_runner.h" +#include "file_descriptor_listener.h" +#include "sensor_agent_type.h" +#include "sensor_data_channel.h" + +namespace OHOS { +namespace Sensors { +class MyFileDescriptorListener : public AppExecFwk::FileDescriptorListener { +public: + explicit MyFileDescriptorListener(); + + ~MyFileDescriptorListener() = default; + + void OnReadable(int32_t fileDescriptor) override; + + void OnWritable(int32_t fileDescriptor) override; + + void OnShutdown(int32_t fileDescriptor) override; + + void OnException(int32_t fileDescriptor) override; + + void SetChannel(SensorDataChannel* channel); + +private: + SensorDataChannel* channel_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // MY_FILE_DESCRIPTOR_LISTENER_H diff --git a/frameworks/native/sensor/include/sensor_agent_proxy.h b/frameworks/native/sensor/include/sensor_agent_proxy.h new file mode 100755 index 00000000..9cfe1169 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_agent_proxy.h @@ -0,0 +1,56 @@ +/* + * 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 SENSOR_PROXY_H +#define SENSOR_PROXY_H + +#include +#include "sensor_agent_type.h" +#include "refbase.h" +#include "sensor_data_channel.h" + +struct SensorNativeData; +struct SensorIdList; +typedef int32_t (*SensorDataCallback)(struct SensorNativeData *events, uint32_t num); + +struct SensorAgentProxy : public OHOS::RefBase { +public: + SensorAgentProxy(); + ~SensorAgentProxy(); + static const SensorAgentProxy *GetSensorsObj(); + int32_t CreateSensorDataChannel(const SensorUser *user) const; + int32_t DestroySensorDataChannel() const; + int32_t GetSensorId(struct SensorIdList *sensorId, uint32_t sensorGroup, uint32_t sensorType) const; + int32_t GetDefaultSensorId(uint32_t sensorGroup, uint32_t sensorType) const; + int64_t GetSensorMinSamplePeriod(uint32_t sensorId) const; + int32_t ChanageSensorInterval(uint32_t sensorId, int64_t sampingPeriodNs, int64_t maxReportDelay) const; + int32_t ActivateSensor(int32_t sensorId, const SensorUser *user) const; + int32_t DeactivateSensor(int32_t sensorId, const SensorUser *user) const; + int32_t SetBatch(int32_t sensorId, const SensorUser *user, int64_t samplingInterval, int64_t reportInterval) const; + int32_t SubscribeSensor(int32_t sensorId, const SensorUser *user) const; + int32_t UnsubscribeSensor(int32_t sensorId, const SensorUser *user) const; + int32_t SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) const; + int32_t SetOption(int32_t sensorId, const SensorUser *user, int32_t option) const; + int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count) const; + +private: + static void HandleSensorData(SensorEvent *events, int32_t num, void *data); + static void FillSensorAccuracy(struct SensorNativeData &data, SensorEvent &event); + static OHOS::sptr sensorObj_; + OHOS::sptr dataChannel_; + static SensorUser *user_; + static const std::map g_sensorDataLenthMap; +}; +#endif // endif SENSOR_PROXY_H diff --git a/frameworks/native/sensor/include/sensor_client_proxy.h b/frameworks/native/sensor/include/sensor_client_proxy.h new file mode 100755 index 00000000..006c28c3 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_client_proxy.h @@ -0,0 +1,39 @@ +/* + * 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 SENSOR_CLIENT_PROXY_H +#define SENSOR_CLIENT_PROXY_H + +#include "i_sensor_client.h" +#include "iremote_proxy.h" +#include "sensor_agent_type.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Sensors { +class SensorClientProxy : public IRemoteProxy { +public: + explicit SensorClientProxy(const sptr &impl) : IRemoteProxy(impl) + {} + + virtual ~SensorClientProxy() = default; + +private: + DISALLOW_COPY_AND_MOVE(SensorClientProxy); + static inline BrokerDelegator delegator_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_CLIENT_PROXY_H diff --git a/frameworks/native/sensor/include/sensor_client_stub.h b/frameworks/native/sensor/include/sensor_client_stub.h new file mode 100755 index 00000000..39e749d9 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_client_stub.h @@ -0,0 +1,36 @@ +/* + * 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 SENSOR_CLIENT_STUB_H +#define SENSOR_CLIENT_STUB_H + +#include "i_sensor_client.h" +#include "iremote_stub.h" +#include "message_parcel.h" + +namespace OHOS { +namespace Sensors { +class SensorClientStub : public IRemoteStub { +public: + SensorClientStub() = default; + + virtual ~SensorClientStub() = default; + + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_CLIENT_STUB_H diff --git a/frameworks/native/sensor/include/sensor_data_channel.h b/frameworks/native/sensor/include/sensor_data_channel.h new file mode 100755 index 00000000..51e2c7a1 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_data_channel.h @@ -0,0 +1,55 @@ +/* + * 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 SENSOR_DATA_CHANNEL_H +#define SENSOR_DATA_CHANNEL_H + +#include +#include +#include "sensor_basic_data_channel.h" +#include "sensor_agent_type.h" +#include "my_event_handler.h" + +namespace OHOS { +namespace Sensors { +typedef void (*DataChannelCB)(struct SensorEvent *events, int32_t num, void *data); +class SensorDataChannel : public SensorBasicDataChannel { +public: + SensorDataChannel(); + ~SensorDataChannel(); + static int32_t HandleEvent(int32_t fd, int32_t events, void *data); + int32_t CreateSensorDataChannel(DataChannelCB callBack, void *data); + int32_t DestroySensorDataChannel(); + bool IsThreadExit(); + bool IsThreadStart(); + int32_t RestoreSensorDataChannel(); + int32_t test = 10; + DataChannelCB dataCB_; + void *privateData_ = nullptr; + +private: + static void threadProcessTask(SensorDataChannel *sensorChannel); + int32_t InnerSensorDataChannel(); + bool threadStop_ = true; + std::mutex treadMutex_; + std::thread sensorDataThread_; + struct SensorEvent *receiveDataBuff_ = nullptr; + static std::shared_ptr eventHandler_; + static std::shared_ptr eventRunner_; + static int32_t receiveFd_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_DATA_CHANNEL_H diff --git a/frameworks/native/sensor/include/sensor_service_client.h b/frameworks/native/sensor/include/sensor_service_client.h new file mode 100755 index 00000000..2a2ac290 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_service_client.h @@ -0,0 +1,59 @@ +/* + * 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 SENSOR_SERVICE_CLIENT_H +#define SENSOR_SERVICE_CLIENT_H + +#include +#include +#include "iservice_registry.h" +#include "sensor.h" +#include "sensor_basic_data_channel.h" +#include "sensor_basic_info.h" +#include "sensor_client_stub.h" +#include "sensor_data_channel.h" +#include "sensor_service_proxy.h" +#include "singleton.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceClient : public Singleton { +public: + std::vector GetSensorList(); + int32_t EnableSensor(uint32_t sensorId, int64_t samplingPeroid, int64_t maxReportDelay); + int32_t DisableSensor(uint32_t sensorId); + int32_t RunCommand(uint32_t sensorId, int32_t cmdType, int32_t parms); + int32_t TransferDataChannel(sptr sensorDataChannel); + int32_t DestroyDataChannel(); + void ProcessDeathObserver(const wptr &object); + +private: + int32_t InitServiceClient(); + void UpdateSensorInfoMap(uint32_t sensorId, int64_t samplingPeroid, int64_t maxReportDelay); + void DeleteSensorInfoItem(uint32_t sensorId); + std::mutex clientMutex_; + sptr serviceDeathObserver_; + sptr sensorServer_; + std::vector sensorList_; + sptr dataChannel_; + sptr sensorClientStub_; + std::mutex mapMutex_; + std::map sensorInfoMap_; +}; +} // namespace Sensors +} // namespace OHOS + +#endif // SENSOR_SERVICE_CLIENT_H diff --git a/frameworks/native/sensor/include/sensor_service_proxy copy.h b/frameworks/native/sensor/include/sensor_service_proxy copy.h new file mode 100755 index 00000000..65a60bf3 --- /dev/null +++ b/frameworks/native/sensor/include/sensor_service_proxy copy.h @@ -0,0 +1,45 @@ +/* + * 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 SENSOR_SERVICE_PROXY_H +#define SENSOR_SERVICE_PROXY_H + +#include "errors.h" +#include "i_sensor_service.h" +#include "iremote_proxy.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceProxy : public IRemoteProxy { +public: + explicit SensorServiceProxy(const sptr &impl); + virtual ~SensorServiceProxy() = default; + ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override; + ErrCode DisableSensor(uint32_t sensorId) override; + int32_t GetSensorState(uint32_t sensorId) override; + ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override; + std::vector GetSensorList() override; + ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) override; + ErrCode DestroySensorChannel(sptr sensorClient) override; + +private: + DISALLOW_COPY_AND_MOVE(SensorServiceProxy); + static inline BrokerDelegator delegator_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_SERVICE_PROXY_H diff --git a/frameworks/native/sensor/include/sensor_service_proxy.h b/frameworks/native/sensor/include/sensor_service_proxy.h new file mode 100755 index 00000000..a694ca2d --- /dev/null +++ b/frameworks/native/sensor/include/sensor_service_proxy.h @@ -0,0 +1,46 @@ +/* + * 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 SENSOR_SERVICE_PROXY_H +#define SENSOR_SERVICE_PROXY_H + +#include "errors.h" +#include "i_sensor_service.h" +#include "iremote_proxy.h" +#include "nocopyable.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceProxy : public IRemoteProxy { +public: + explicit SensorServiceProxy(const sptr &impl); + virtual ~SensorServiceProxy() = default; + ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override; + ErrCode DisableSensor(uint32_t sensorId) override; + int32_t GetSensorState(uint32_t sensorId) override; + ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override; + std::vector GetSensorList() override; + ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) override; + ErrCode DestroySensorChannel(sptr sensorClient) override; + +private: + DISALLOW_COPY_AND_MOVE(SensorServiceProxy); + static inline BrokerDelegator delegator_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_SERVICE_PROXY_H diff --git a/frameworks/native/sensor/src/my_event_handler.cpp b/frameworks/native/sensor/src/my_event_handler.cpp new file mode 100755 index 00000000..802c1286 --- /dev/null +++ b/frameworks/native/sensor/src/my_event_handler.cpp @@ -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 "my_event_handler.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +using namespace OHOS::AppExecFwk; + +namespace { +} // namespace + +MyEventHandler::MyEventHandler(const std::shared_ptr &runner):EventHandler(runner){} + +/** + * Function: Process the event. Override the method of base class. + * @param event The event need to be processed. + */ +void MyEventHandler::ProcessEvent(const InnerEvent::Pointer &event){} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/sensor/src/my_file_descriptor_listener.cpp b/frameworks/native/sensor/src/my_file_descriptor_listener.cpp new file mode 100755 index 00000000..1a778835 --- /dev/null +++ b/frameworks/native/sensor/src/my_file_descriptor_listener.cpp @@ -0,0 +1,95 @@ +/* + * 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 "my_file_descriptor_listener.h" +#include +#include +#include +#include +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +using namespace OHOS::AppExecFwk; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "MyFileDescriptorListener" }; +constexpr int32_t RECEIVE_DATA_SIZE = 100; +} // namespace + +MyFileDescriptorListener::MyFileDescriptorListener() +{} + +void MyFileDescriptorListener::OnReadable(int32_t fileDescriptor) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + if (fileDescriptor < 0) { + HiLog::Error(LABEL, "%{public}s fileDescriptor: %{public}d", __func__, fileDescriptor); + return; + } + + FileDescriptorListener::OnReadable(fileDescriptor); + + struct TransferSensorEvents *receiveDataBuff_ = + new (std::nothrow) TransferSensorEvents[sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE]; + int32_t len = recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE, NULL); + while (len > 0) { + int32_t eventSize = sizeof(struct TransferSensorEvents); + int32_t num = len / eventSize; + for (int i = 0; i < num; i++) { + SensorEvent event = { + .sensorTypeId = receiveDataBuff_[i].sensorTypeId, + .version = receiveDataBuff_[i].version, + .timestamp = receiveDataBuff_[i].timestamp, + .option = receiveDataBuff_[i].option, + .mode = receiveDataBuff_[i].mode, + .dataLen = receiveDataBuff_[i].dataLen, + .data = receiveDataBuff_[i].data + }; + channel_->dataCB_(&event, 1, channel_->privateData_); + } + len = recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferSensorEvents) * RECEIVE_DATA_SIZE, NULL); + } +} + +void MyFileDescriptorListener::OnWritable(int32_t fileDescriptor){} + +void MyFileDescriptorListener::SetChannel(SensorDataChannel* channel) +{ + channel_ = channel; +} + +void MyFileDescriptorListener::OnShutdown(int32_t fileDescriptor) +{ + if (fileDescriptor < 0) { + HiLog::Error(LABEL, "%{public}s param is error: %{public}d", __func__, fileDescriptor); + return; + } + + FileDescriptorListener::OnShutdown(fileDescriptor); +} + +void MyFileDescriptorListener::OnException(int32_t fileDescriptor) +{ + if (fileDescriptor < 0) { + HiLog::Error(LABEL, "%{public}s param is error: %{public}d", __func__, fileDescriptor); + return; + } + + FileDescriptorListener::OnException(fileDescriptor); +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/sensor/src/sensor_agent_proxy.cpp b/frameworks/native/sensor/src/sensor_agent_proxy.cpp new file mode 100755 index 00000000..5bfb89dc --- /dev/null +++ b/frameworks/native/sensor/src/sensor_agent_proxy.cpp @@ -0,0 +1,351 @@ +/* + * 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 "sensor_agent_proxy.h" + +#include + +#include "securec.h" +#include "sensor_catalog.h" +#include "sensor_service_client.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, OHOS::SensorsLogDomain::SENSORS_IMPLEMENT, "SensorAgentProxy" }; + +using OHOS::ERR_OK; +using OHOS::Sensors::BODY; +using OHOS::Sensors::DEVICE_MOTION; +using OHOS::Sensors::ENVIRONMENT; +using OHOS::Sensors::INVALID_POINTER; +using OHOS::Sensors::LIGHT; +using OHOS::Sensors::ORIENTATION; +using OHOS::Sensors::OTHER; +using OHOS::Sensors::SENSOR_TYPE_6DOF_ATTITUDE; +using OHOS::Sensors::SENSOR_TYPE_ACCELEROMETER; +using OHOS::Sensors::SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED; +using OHOS::Sensors::SENSOR_TYPE_AMBIENT_LIGHT; +using OHOS::Sensors::SENSOR_TYPE_AMBIENT_TEMPERATURE; +using OHOS::Sensors::SENSOR_TYPE_BAROMETER; +using OHOS::Sensors::SENSOR_TYPE_DEVICE_ORIENTATION; +using OHOS::Sensors::SENSOR_TYPE_GAME_ROTATION_VECTOR; +using OHOS::Sensors::SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR; +using OHOS::Sensors::SENSOR_TYPE_GRAVITY; +using OHOS::Sensors::SENSOR_TYPE_GYROSCOPE; +using OHOS::Sensors::SENSOR_TYPE_GYROSCOPE_UNCALIBRATED; +using OHOS::Sensors::SENSOR_TYPE_HEART_RATE_DETECTOR; +using OHOS::Sensors::SENSOR_TYPE_HUMIDITY; +using OHOS::Sensors::SENSOR_TYPE_LINEAR_ACCELERATION; +using OHOS::Sensors::SENSOR_TYPE_MAGNETIC_FIELD; +using OHOS::Sensors::SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED; +using OHOS::Sensors::SENSOR_TYPE_ORIENTATION; +using OHOS::Sensors::SENSOR_TYPE_PRESSURE_DETECTOR; +using OHOS::Sensors::SENSOR_TYPE_PROXIMITY; +using OHOS::Sensors::SENSOR_TYPE_ROTATION_VECTOR; +using OHOS::Sensors::SENSOR_TYPE_SIGNIFICANT_MOTION; +using OHOS::Sensors::SENSOR_TYPE_STEP_COUNTER; +using OHOS::Sensors::SENSOR_TYPE_STEP_DETECTOR; +using OHOS::Sensors::SENSOR_TYPE_WEAR_DETECTOR; +using OHOS::Sensors::SensorDataChannel; +using OHOS::Sensors::SensorServiceClient; +} // namespace + +OHOS::sptr SensorAgentProxy::sensorObj_ = nullptr; +static bool g_isChannelCreated = false; +static int64_t g_samplingInterval = -1; +static int64_t g_reportInterval = -1; +static std::map g_subscribeMap; +static std::map g_unsubscribeMap; + +const std::map SensorAgentProxy::g_sensorDataLenthMap = { + { SENSOR_TYPE_ID_ACCELEROMETER, sizeof(AccelData)}, + { SENSOR_TYPE_ID_LINEAR_ACCELERATION, sizeof(LinearAccelData)}, + { SENSOR_TYPE_ID_GRAVITY, sizeof(GravityData)}, + { SENSOR_TYPE_ID_GYROSCOPE, sizeof(GyroscopeData)}, + { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, sizeof(AccelUncalibratedData)}, + { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, sizeof(GyroUncalibratedData)}, + { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, sizeof(SignificantMotionData)}, + { SENSOR_TYPE_ID_PEDOMETER_DETECTION, sizeof(PedometerDetectData)}, + { SENSOR_TYPE_ID_PEDOMETER, sizeof(PedometerData)}, + + { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, sizeof(AmbientTemperatureData)}, + { SENSOR_TYPE_ID_HUMIDITY, sizeof(HumidityData)}, + { SENSOR_TYPE_ID_MAGNETIC_FIELD, sizeof(MagneticFieldData)}, + { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, sizeof(MagneticFieldUncalibratedData)}, + { SENSOR_TYPE_ID_BAROMETER, sizeof(BarometerData)}, + + { SENSOR_TYPE_ID_DEVICE_ORIENTATION, sizeof(DeviceOrientationData)}, + { SENSOR_TYPE_ID_ORIENTATION, sizeof(OrientationData)}, + { SENSOR_TYPE_ID_ROTATION_VECTOR, sizeof(RotationVectorData)}, + { SENSOR_TYPE_ID_GAME_ROTATION_VECTOR, sizeof(GameRotationVectorData)}, + { SENSOR_TYPE_ID_GEOMAGNETIC_ROTATION_VECTOR, sizeof(GeomagneticRotaVectorData)}, + + { SENSOR_TYPE_ID_PROXIMITY, sizeof(ProximityData)}, + { SENSOR_TYPE_ID_AMBIENT_LIGHT, sizeof(AmbientLightData)}, + + { SENSOR_TYPE_ID_HEART_RATE, sizeof(HeartRateData)}, + { SENSOR_TYPE_ID_WEAR_DETECTION, sizeof(WearDetectionData)} +}; + +SensorAgentProxy::SensorAgentProxy() : dataChannel_(new (std::nothrow) SensorDataChannel()) +{} + +SensorAgentProxy::~SensorAgentProxy() +{} + +const SensorAgentProxy *SensorAgentProxy::GetSensorsObj() +{ + HiLog::Debug(LABEL, "%{public}s", __func__); + + if (sensorObj_ == nullptr) { + sensorObj_ = new (std::nothrow) SensorAgentProxy(); + } + return sensorObj_; +} + +void SensorAgentProxy::HandleSensorData(struct SensorEvent *events, int32_t num, void *data) +{ + if (events == nullptr || num <= 0) { + HiLog::Error(LABEL, "%{public}s events is null or num is invalid", __func__); + return; + } + struct SensorEvent eventStream; + for (int32_t i = 0; i < num; ++i) { + eventStream = events[i]; + if (eventStream.data == nullptr || g_subscribeMap[eventStream.sensorTypeId] == nullptr) { + HiLog::Error(LABEL, "%{public}s data or sensorUser is nullptr", __func__); + return; + } + if (g_subscribeMap.find(eventStream.sensorTypeId) == g_subscribeMap.end()) { + HiLog::Error(LABEL, "%{public}s sensorTypeId not in g_subscribeMap", __func__); + return; + } + g_subscribeMap[eventStream.sensorTypeId]->callback(&eventStream); + } +} + +int32_t SensorAgentProxy::CreateSensorDataChannel(const SensorUser *user) const +{ + HiLog::Debug(LABEL, "%{public}s", __func__); + if (dataChannel_ == nullptr) { + HiLog::Error(LABEL, "%{public}s data channel cannot be null", __func__); + return INVALID_POINTER; + } + auto ret = dataChannel_->CreateSensorDataChannel(HandleSensorData, nullptr); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s create data channel failed, ret : %{public}d", __func__, ret); + return ret; + } + auto &client = SensorServiceClient::GetInstance(); + ret = client.TransferDataChannel(dataChannel_); + if (ret != ERR_OK) { + auto destoryRet = dataChannel_->DestroySensorDataChannel(); + HiLog::Error(LABEL, "%{public}s transfer data channel failed, ret : %{public}d, destoryRet : %{public}d", + __func__, ret, destoryRet); + return ret; + } + return ERR_OK; +} + +int32_t SensorAgentProxy::DestroySensorDataChannel() const +{ + int32_t ret; + if (dataChannel_ != nullptr) { + ret = dataChannel_->DestroySensorDataChannel(); + } + SensorServiceClient &client = SensorServiceClient::GetInstance(); + ret = client.DestroyDataChannel(); + return ret; +} + +int32_t SensorAgentProxy::ActivateSensor(int32_t sensorId, const SensorUser *user) const +{ + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if (g_samplingInterval < 0 || g_reportInterval < 0) { + HiLog::Error(LABEL, "%{public}s samplingPeroid or g_reportInterval is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { + HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + SensorServiceClient &client = SensorServiceClient::GetInstance(); + int32_t ret = client.EnableSensor(sensorId, g_samplingInterval, g_reportInterval); + g_samplingInterval = -1; + g_reportInterval = -1; + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s enable sensor failed, ret: %{public}d", __func__, ret); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::DeactivateSensor(int32_t sensorId, const SensorUser *user) const +{ + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if (g_subscribeMap.find(sensorId) != g_subscribeMap.end()) { + HiLog::Error(LABEL, "%{public}s unsubscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + + if (g_unsubscribeMap.find(sensorId) == g_unsubscribeMap.end() || g_unsubscribeMap[sensorId] != user) { + HiLog::Error(LABEL, "%{public}s unsubscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + SensorServiceClient &client = SensorServiceClient::GetInstance(); + int32_t ret = client.DisableSensor(sensorId); + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s disable sensor failed, ret: %{public}d", __func__, ret); + return OHOS::Sensors::ERROR; + } + g_unsubscribeMap.erase(sensorId); + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::SetBatch(int32_t sensorId, const SensorUser *user, int64_t samplingInterval, + int64_t reportInterval) const +{ + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if (samplingInterval < 0 || reportInterval < 0) { + HiLog::Error(LABEL, "%{public}s samplingInterval or reportInterval is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { + HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + g_samplingInterval = samplingInterval; + g_reportInterval = reportInterval; + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::SubscribeSensor(int32_t sensorId, const SensorUser *user) const +{ + HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId); + if (user == nullptr || sensorId < 0 || user->callback == nullptr) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if (!g_isChannelCreated) { + HiLog::Info(LABEL, "%{public}s channel created", __func__); + g_isChannelCreated = true; + CreateSensorDataChannel(user); + } + g_subscribeMap[sensorId] = user; + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::UnsubscribeSensor(int32_t sensorId, const SensorUser *user) const +{ + HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId); + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { + HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + g_subscribeMap.erase(sensorId); + g_unsubscribeMap[sensorId] = user; + if (g_subscribeMap.empty()) { + DestroySensorDataChannel(); + g_isChannelCreated = false; + HiLog::Info(LABEL, "%{public}s channel has been destroyed", __func__); + } + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) const +{ + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { + HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::SetOption(int32_t sensorId, const SensorUser *user, int32_t option) const +{ + if (user == NULL || sensorId < 0) { + HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__); + return OHOS::Sensors::ERROR; + } + if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) { + HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__); + return OHOS::Sensors::ERROR; + } + return OHOS::Sensors::SUCCESS; +} + +int32_t SensorAgentProxy::GetAllSensors(SensorInfo **sensorInfo, int32_t *count) const +{ + if (sensorInfo == NULL || count == NULL) { + HiLog::Error(LABEL, "%{public}s sensorInfo or count is null", __func__); + return OHOS::Sensors::ERROR; + } + SensorServiceClient &client = SensorServiceClient::GetInstance(); + std::vector sensorList_ = client.GetSensorList(); + if (sensorList_.empty()) { + HiLog::Error(LABEL, "%{public}s get sensor lists failed", __func__); + return OHOS::Sensors::ERROR; + } + *count = sensorList_.size(); + *sensorInfo = (SensorInfo *)malloc(sizeof(SensorInfo) * (*count)); + if (*sensorInfo == nullptr) { + HiLog::Error(LABEL, "%{public}s malloc sensorInfo failed", __func__); + return OHOS::Sensors::ERROR; + } + for (int32_t index = 0; index < *count; index++) { + errno_t ret = strcpy_s((*sensorInfo + index)->sensorName, SENSOR_NAME_MAX_LEN2, + sensorList_[index].GetName().c_str()); + if (ret != EOK) { + HiLog::Error(LABEL, "%{public}s strcpy sensorName failed", __func__); + return OHOS::Sensors::ERROR; + } + ret = strcpy_s((*sensorInfo + index)->vendorName, SENSOR_NAME_MAX_LEN2, sensorList_[index].GetVendor().c_str()); + if (ret != EOK) { + HiLog::Error(LABEL, "%{public}s strcpy vendorName failed", __func__); + return OHOS::Sensors::ERROR; + } + const char *version = std::to_string(sensorList_[index].GetVersion()).c_str(); + ret = strcpy_s((*sensorInfo + index)->hardwareVersion, SENSOR_NAME_MAX_LEN2, version); + if (ret != EOK) { + HiLog::Error(LABEL, "%{public}s strcpy hardwareVersion failed", __func__); + return OHOS::Sensors::ERROR; + } + (*sensorInfo + index)->sensorId = sensorList_[index].GetSensorId(); + (*sensorInfo + index)->sensorTypeId = sensorList_[index].GetSensorId(); + (*sensorInfo + index)->maxRange = sensorList_[index].GetMaxRange(); + (*sensorInfo + index)->precision = sensorList_[index].GetResolution(); + (*sensorInfo + index)->power = 0.0f; + } + return OHOS::Sensors::SUCCESS; +} diff --git a/frameworks/native/sensor/src/sensor_data_channel.cpp b/frameworks/native/sensor/src/sensor_data_channel.cpp new file mode 100755 index 00000000..b6693aa9 --- /dev/null +++ b/frameworks/native/sensor/src/sensor_data_channel.cpp @@ -0,0 +1,198 @@ +/* + * 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 "sensor_data_channel.h" + +#include +#include + +#include +#include + +#include "my_file_descriptor_listener.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "string_ex.h" + +#ifndef O_NONBLOCK +# define O_NONBLOCK 04000 +#endif + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +using namespace OHOS::AppExecFwk; +std::shared_ptr SensorDataChannel::eventHandler_; +std::shared_ptr SensorDataChannel::eventRunner_; +int32_t SensorDataChannel::receiveFd_ = 0; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_NATIVE, "SensorDataChannel" }; +// max 100 data in cache buffer +constexpr int32_t SENSOR_READ_DATA_SIZE = sizeof(struct SensorEvent) * 100; +const uint32_t STOP_EVENT_ID = 0; +} // namespace + +SensorDataChannel::SensorDataChannel() + : dataCB_(nullptr), + privateData_(nullptr), + threadStop_(true) +{ + receiveDataBuff_ = new (std::nothrow) SensorEvent[SENSOR_READ_DATA_SIZE]; + if (receiveDataBuff_ == nullptr) { + HiLog::Error(LABEL, "%{public}s receiveDataBuff_ cannot be null", __func__); + return; + } +} + +int32_t SensorDataChannel::HandleEvent(int32_t fd, int32_t events, void *data) +{ + HiLog::Debug(LABEL, "%{public}s fd : %{public}d", __func__, fd); + constexpr int32_t allowSkip = 1; + if (data == nullptr) { + HiLog::Error(LABEL, "%{public}s data cannot be null", __func__); + return allowSkip; + } + SensorDataChannel *channel = reinterpret_cast(data); + if (channel->receiveDataBuff_ == nullptr) { + HiLog::Error(LABEL, "%{public}s channel receiveDataBuff_ cannot be null", __func__); + return allowSkip; + } + int32_t len = channel->ReceiveData(channel->receiveDataBuff_, SENSOR_READ_DATA_SIZE); + while (len > 0) { + int32_t eventSize = sizeof(SensorEvent); + if (eventSize > 0) { + int32_t num = len / eventSize; + HiLog::Debug(LABEL, "%{public}s num : %{public}d", __func__, num); + channel->dataCB_(channel->receiveDataBuff_, num, channel->privateData_); + len = channel->ReceiveData(channel->receiveDataBuff_, SENSOR_READ_DATA_SIZE); + } + } + return allowSkip; +} + +int32_t SensorDataChannel::CreateSensorDataChannel(DataChannelCB callBack, void *data) +{ + if (callBack == nullptr) { + HiLog::Error(LABEL, "%{public}s callBack cannot be null", __func__); + return SENSOR_NATIVE_REGSITER_CB_ERR; + } + dataCB_ = callBack; + privateData_ = data; + return InnerSensorDataChannel(); +} + +int32_t SensorDataChannel::RestoreSensorDataChannel() +{ + if (dataCB_ == nullptr) { + HiLog::Error(LABEL, "%{public}s dataCB_ cannot be null", __func__); + return SENSOR_CHANNEL_RESTORE_CB_ERR; + } + if (GetReceiveDataFd() != INVALID_FD) { + HiLog::Error(LABEL, "%{public}s fd not close", __func__); + return SENSOR_CHANNEL_RESTORE_FD_ERR; + } + if (sensorDataThread_.joinable()) { + HiLog::Error(LABEL, "%{public}s thread exit", __func__); + return SENSOR_CHANNEL_RESTORE_THREAD_ERR; + } + return InnerSensorDataChannel(); +} + +int32_t SensorDataChannel::InnerSensorDataChannel() +{ + std::lock_guard threadLock(treadMutex_); + + // create basic data channel + int32_t ret = CreateSensorBasicChannel(SENSOR_READ_DATA_SIZE, SENSOR_READ_DATA_SIZE); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s create basic channel failed, ret : %{public}d", __func__, ret); + return ret; + } + auto listener = std::make_shared(); + listener->SetChannel(this); + auto myRunner = AppExecFwk::EventRunner::Create(true); + if (myRunner == nullptr) { + HiLog::Error(LABEL, "%{public}s myRunner is null", __func__); + return -1; + } + auto handler = std::make_shared(myRunner); + if (handler == nullptr) { + HiLog::Error(LABEL, "%{public}s handler is null", __func__); + return -1; + } + + receiveFd_ = GetReceiveDataFd(); + auto inResult = handler->AddFileDescriptorListener(receiveFd_, AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, listener); + if (inResult != 0) { + HiLog::Error(LABEL, "%{public}s AddFileDescriptorListener fail", __func__); + return -1; + } + eventHandler_ = handler; + eventRunner_ = myRunner; + int64_t delayTime = 100; + int64_t param = 0; + bool sendEventResult = eventHandler_->SendEvent(STOP_EVENT_ID, param, delayTime); + if (!sendEventResult) { + HiLog::Error(LABEL, "%{public}s EventHandler SendEvent fail", __func__); + return -1; + } + int32_t runResult = eventRunner_->Run(); + if (!runResult) { + HiLog::Error(LABEL, "%{public}s EventRunner run fail", __func__); + return -1; + } + return ERR_OK; +} + +int32_t SensorDataChannel::DestroySensorDataChannel() +{ + std::lock_guard threadLock(treadMutex_); + // send wakeup signal to sensor_fwk_read_data thread + + if (eventHandler_ == nullptr) { + HiLog::Error(LABEL, "%{public}s handler is null", __func__); + return -1; + } + int32_t fd = GetReceiveDataFd(); + eventHandler_->RemoveFileDescriptorListener(fd); + + threadStop_ = true; + + if (sensorDataThread_.joinable()) { + sensorDataThread_.join(); + } + // destroy sensor basic channel + return DestroySensorBasicChannel(); +} +bool SensorDataChannel::IsThreadExit() +{ + return (!sensorDataThread_.joinable()) && (threadStop_); +} + +bool SensorDataChannel::IsThreadStart() +{ + return (sensorDataThread_.joinable()) && (!threadStop_); +} + +SensorDataChannel::~SensorDataChannel() +{ + DestroySensorDataChannel(); + if (receiveDataBuff_ != nullptr) { + delete[] receiveDataBuff_; + } +} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/src/sensor_service_client.cpp b/frameworks/native/sensor/src/sensor_service_client.cpp new file mode 100755 index 00000000..9460cba8 --- /dev/null +++ b/frameworks/native/sensor/src/sensor_service_client.cpp @@ -0,0 +1,220 @@ +/* + * 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 "sensor_service_client.h" + +#include +#include +#include +#include + +#include "death_recipient_template.h" +#include "dmd_report.h" +#include "ipc_skeleton.h" +#include "sensor_service_proxy.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_NATIVE, "SensorServiceClient" }; +constexpr int32_t GET_SERVICE_MAX_COUNT = 30; +constexpr uint32_t WAIT_MS = 200; +} // namespace + +int32_t SensorServiceClient::InitServiceClient() +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard clientLock(clientMutex_); + if (sensorServer_ != nullptr) { + HiLog::Debug(LABEL, "%{public}s already init", __func__); + return ERR_OK; + } + if (sensorClientStub_ == nullptr) { + sensorClientStub_ = new (std::nothrow) SensorClientStub(); + } + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + HiLog::Error(LABEL, "%{public}s systemAbilityManager cannot be null", __func__); + return SENSOR_NATIVE_SAM_ERR; + } + int32_t retry = 0; + while (retry < GET_SERVICE_MAX_COUNT) { + sensorServer_ = iface_cast(systemAbilityManager->GetSystemAbility(SENSOR_SERVICE_ABILITY_ID)); + if (sensorServer_ != nullptr) { + HiLog::Debug(LABEL, "%{public}s get service success, retry : %{public}d", __func__, retry); + serviceDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast(this)); + if (serviceDeathObserver_ != nullptr) { + sensorServer_->AsObject()->AddDeathRecipient(serviceDeathObserver_); + } + sensorList_ = sensorServer_->GetSensorList(); + return ERR_OK; + } + HiLog::Warn(LABEL, "%{public}s get service failed, retry : %{public}d", __func__, retry); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS)); + retry++; + } + DmdReport::ReportException(SENSOR_SERVICE_EXCEPTION, "InitServiceClient", SENSOR_NATIVE_GET_SERVICE_ERR); + HiLog::Error(LABEL, "%{public}s get service failed", __func__); + return SENSOR_NATIVE_GET_SERVICE_ERR; +} + +int32_t SensorServiceClient::EnableSensor(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return ret; + } + ret = sensorServer_->EnableSensor(sensorId, samplingPeriod, maxReportDelay); + if (ret == ERR_OK) { + UpdateSensorInfoMap(sensorId, samplingPeriod, maxReportDelay); + } + return ret; +} + +int32_t SensorServiceClient::DisableSensor(uint32_t sensorId) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return ret; + } + ret = sensorServer_->DisableSensor(sensorId); + if (ret == ERR_OK) { + DeleteSensorInfoItem(sensorId); + } + return ret; +} + +int32_t SensorServiceClient::RunCommand(uint32_t sensorId, int32_t cmdType, int32_t params) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return ret; + } + ret = sensorServer_->RunCommand(sensorId, cmdType, params); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s RunCommand failed", __func__); + return ret; + } + return ret; +} + +std::vector SensorServiceClient::GetSensorList() +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return {}; + } + if (sensorList_.empty()) { + HiLog::Error(LABEL, "%{public}s sensorList_ cannot be empty", __func__); + } + return sensorList_; +} + +int32_t SensorServiceClient::TransferDataChannel(sptr sensorDataChannel) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + dataChannel_ = sensorDataChannel; + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return ret; + } + return sensorServer_->TransferDataChannel(sensorDataChannel, sensorClientStub_); +} + +int32_t SensorServiceClient::DestroyDataChannel() +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + return ret; + } + return sensorServer_->DestroySensorChannel(sensorClientStub_); +} + +void SensorServiceClient::ProcessDeathObserver(const wptr &object) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + (void)object; + if (dataChannel_ == nullptr) { + HiLog::Error(LABEL, "%{public}s dataChannel_ cannot be null", __func__); + return; + } + // STEP1 : Destroy revious data channel + dataChannel_->DestroySensorDataChannel(); + + // STEP2 : Restore data channel + dataChannel_->RestoreSensorDataChannel(); + + // STEP3 : Clear sensorlist and sensorServer_ + sensorList_.clear(); + sensorServer_ = nullptr; + + // STEP4 : ReGet hsensors 3601 service + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret); + dataChannel_->DestroySensorDataChannel(); + return; + } + + // STEP5 : Retransfer new channel to hsensors + sensorServer_->TransferDataChannel(dataChannel_, sensorClientStub_); + + // STEP6 : Restore Sensor status + std::lock_guard mapLock(mapMutex_); + for (const auto &it : sensorInfoMap_) { + sensorServer_->EnableSensor(it.first, it.second.GetSamplingPeriodNs(), it.second.GetMaxReportDelayNs()); + } +} + +void SensorServiceClient::UpdateSensorInfoMap(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard mapLock(mapMutex_); + SensorBasicInfo sensorInfo; + sensorInfo.SetSamplingPeriodNs(samplingPeriod); + sensorInfo.SetMaxReportDelayNs(maxReportDelay); + sensorInfo.SetSensorState(SensorState::SENSOR_ENABLED); + sensorInfoMap_[sensorId] = sensorInfo; + return; +} + +void SensorServiceClient::DeleteSensorInfoItem(uint32_t sensorId) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard mapLock(mapMutex_); + auto it = sensorInfoMap_.find(sensorId); + if (it != sensorInfoMap_.end()) { + sensorInfoMap_.erase(it); + } + return; +} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/src/sensor_service_proxy.cpp b/frameworks/native/sensor/src/sensor_service_proxy.cpp new file mode 100755 index 00000000..da794bc9 --- /dev/null +++ b/frameworks/native/sensor/src/sensor_service_proxy.cpp @@ -0,0 +1,234 @@ +/* + * 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 "sensor_service_proxy.h" + +#include + +#include "dmd_report.h" +#include "message_parcel.h" +#include "sensor_client_proxy.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorServiceProxy" }; +constexpr int32_t MAX_SENSOR_COUNT = 200; +enum { + FLUSH = 0, + SET_MODE, + RESERVED, +}; +} // namespace + +SensorServiceProxy::SensorServiceProxy(const sptr &impl) : IRemoteProxy(impl) +{} + +ErrCode SensorServiceProxy::EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(sensorId)) { + HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteInt64(samplingPeriodNs)) { + HiLog::Error(LABEL, "%{public}s write samplingPeriodNs failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteInt64(maxReportDelayNs)) { + HiLog::Error(LABEL, "%{public}s write maxReportDelayNs failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::ENABLE_SENSOR, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "EnableSensor", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::DisableSensor(uint32_t sensorId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(sensorId)) { + HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::DISABLE_SENSOR, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "DisableSensor", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + return static_cast(ret); +} + +int32_t SensorServiceProxy::GetSensorState(uint32_t sensorId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(sensorId)) { + HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::GET_SENSOR_STATE, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "GetSensorState", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) +{ + if (cmdType > RESERVED) { + HiLog::Error(LABEL, "%{public}s failed, cmdType : %{public}u", __func__, cmdType); + return CMD_TYPE_ERR; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(sensorId)) { + HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(cmdType)) { + HiLog::Error(LABEL, "%{public}s write cmdType failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteUint32(params)) { + HiLog::Error(LABEL, "%{public}s write params failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::RUN_COMMAND, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "RunCommand", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + return static_cast(ret); +} + +std::vector SensorServiceProxy::GetSensorList() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + std::vector sensors; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return sensors; + } + int32_t ret = Remote()->SendRequest(ISensorService::GET_SENSOR_LIST, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "GetSensorList", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + return sensors; + } + + int32_t sensorCount = reply.ReadInt32(); + HiLog::Debug(LABEL, "%{public}s sensorCount : %{public}d", __func__, sensorCount); + if (sensorCount > MAX_SENSOR_COUNT) { + sensorCount = MAX_SENSOR_COUNT; + } + Sensor sensor; + for (int32_t i = 0; i < sensorCount; i++) { + auto tmpSensor = sensor.Unmarshalling(reply); + if (tmpSensor == nullptr) { + continue; + } + sensors.push_back(*tmpSensor); + } + return sensors; +} + +ErrCode SensorServiceProxy::TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) +{ + HiLog::Debug(LABEL, "%{public}s sendFd: %{public}d", __func__, sensorBasicDataChannel->GetSendDataFd()); + if (sensorBasicDataChannel == nullptr || sensorClient == nullptr) { + HiLog::Error(LABEL, "%{public}s sensorBasicDataChannel or sensorClient cannot be null", __func__); + return OBJECT_NULL; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + sensorBasicDataChannel->SendToBinder(data); + if (!data.WriteRemoteObject(sensorClient)) { + HiLog::Error(LABEL, "%{public}s write sensorClient failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::TRANSFER_DATA_CHANNEL, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "TransferDataChannel", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + sensorBasicDataChannel->CloseSendFd(); + return static_cast(ret); +} + +ErrCode SensorServiceProxy::DestroySensorChannel(sptr sensorClient) +{ + if (sensorClient == nullptr) { + HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__); + return OBJECT_NULL; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__); + return WRITE_MSG_ERR; + } + if (!data.WriteRemoteObject(sensorClient)) { + HiLog::Error(LABEL, "%{public}s write sensorClient failed", __func__); + return WRITE_MSG_ERR; + } + int32_t ret = Remote()->SendRequest(ISensorService::DESTROY_SENSOR_CHANNEL, data, reply, option); + if (ret != NO_ERROR) { + DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "DestroySensorChannel", ret); + HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret); + } + return static_cast(ret); +} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/test/BUILD.gn b/frameworks/native/sensor/test/BUILD.gn new file mode 100755 index 00000000..b0ee5461 --- /dev/null +++ b/frameworks/native/sensor/test/BUILD.gn @@ -0,0 +1,25 @@ +# 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") + +############################################################################### +group("unittest") { + testonly = true + if (is_phone_product || is_wearable_product) { + deps = [ "unittest/common:unittest" ] + } + if (is_phone_product) { + deps += [ "unittest/phone:unittest" ] + } +} diff --git a/frameworks/native/sensor/test/unittest/common/BUILD.gn b/frameworks/native/sensor/test/unittest/common/BUILD.gn new file mode 100755 index 00000000..a574087a --- /dev/null +++ b/frameworks/native/sensor/test/unittest/common/BUILD.gn @@ -0,0 +1,95 @@ +# 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/sensors_sensor/frameworks/sensor" + +####################################################### +ohos_unittest("SensorNativeCommonTest") { + module_out_path = module_output_path + + sources = [ "./sensor_native_test.cpp" ] + + include_dirs = [ + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensors_sensor/utils/include", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/common/include", + "//utils/native/base/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_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", + ] +} + +####################################################### +ohos_unittest("SensorDfxTest") { + module_out_path = module_output_path + + sources = [ "./sensor_dfx_test.cpp" ] + + include_dirs = [ + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensors_sensor/utils/include", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", + "//utils/native/base/include", + ] + + deps = [ + #"$SUBSYSTEM_DIR/sensors_sensor/adapter/frameworks:libsensor_fwk_adapter", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] +} + +########################################################################### +group("unittest") { + testonly = true + if (is_phone_product || is_wearable_product) { + deps = [ + ":SensorDfxTest", + ":SensorNativeCommonTest", + ] + } +} diff --git a/frameworks/native/sensor/test/unittest/common/sensor_dfx_test.cpp b/frameworks/native/sensor/test/unittest/common/sensor_dfx_test.cpp new file mode 100755 index 00000000..8514047c --- /dev/null +++ b/frameworks/native/sensor/test/unittest/common/sensor_dfx_test.cpp @@ -0,0 +1,131 @@ +/* + * 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 + +#include +#include "sensor_data_channel.h" +#include "sensor_data_event.h" +#include "sensor_service_client.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "string_ex.h" + + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorDFXTest" }; +const std::string CMD_LINE = "ps -ef | grep 'hsensors' | grep -v grep | awk '{print $2}'"; +constexpr int32_t BUFFER_SIZE = 8; +constexpr pid_t INVALID_PID = -1; +} // namespace + +class SensorDFXTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + pid_t GetSensorServicePid(); + static void HandleEvent(struct SensorEvent *events, int32_t num, void *data); + static std::vector g_sensorsList; + static sptr g_sensorDataChannel; + static std::unique_ptr g_sensorServiceClient; + static bool g_dataReport; +}; + +std::vector SensorDFXTest::g_sensorsList; +sptr SensorDFXTest::g_sensorDataChannel = nullptr; +bool SensorDFXTest::g_dataReport = false; +std::unique_ptr SensorDFXTest::g_sensorServiceClient = nullptr; + +pid_t SensorDFXTest::GetSensorServicePid() +{ + pid_t pid = INVALID_PID; + char buf[BUFFER_SIZE] = { 0 }; + FILE *fp = popen(CMD_LINE.c_str(), "r"); + if (fp == nullptr) { + HiLog::Error(LABEL, "get error when getting sensor service process id"); + return pid; + } + + fgets(buf, sizeof(buf) - 1, fp); + pclose(fp); + fp = nullptr; + HiLog::Info(LABEL, "process is : %{public}s", buf); + + std::string pidStr(buf); + pidStr = TrimStr(pidStr, '\n'); + HiLog::Info(LABEL, "pidStr is : %{public}s", pidStr.c_str()); + if (pidStr.empty()) { + return pid; + } + + if (IsNumericStr(pidStr)) { + pid = std::stoi(pidStr); + } + return pid; +} + +void SensorDFXTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data) +{ + HiLog::Info(LABEL, "%{public}s HandleEvent", __func__); + for (int32_t i = 0; i < num; i++) { + g_dataReport = true; + } + return; +} + +void SensorDFXTest::SetUpTestCase() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + g_sensorDataChannel = new (std::nothrow) SensorDataChannel(); + ASSERT_NE(g_sensorDataChannel, nullptr); + g_sensorServiceClient = std::make_unique(); + ASSERT_NE(g_sensorServiceClient, nullptr); + g_sensorsList = g_sensorServiceClient->GetSensorList(); + ASSERT_NE(g_sensorsList.size(), 0UL); + auto ret = g_sensorDataChannel->CreateSensorDataChannel(HandleEvent, nullptr); + HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + ret = g_sensorServiceClient->TransferDataChannel(g_sensorDataChannel); + HiLog::Info(LABEL, "TransferDataChannel ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + g_dataReport = false; +} + +void SensorDFXTest::TearDownTestCase() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + g_sensorServiceClient->DestroyDataChannel(); + g_sensorDataChannel->DestroySensorDataChannel(); +} + +void SensorDFXTest::SetUp() +{} + +void SensorDFXTest::TearDown() +{} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/test/unittest/common/sensor_native_test.cpp b/frameworks/native/sensor/test/unittest/common/sensor_native_test.cpp new file mode 100755 index 00000000..ff427ccb --- /dev/null +++ b/frameworks/native/sensor/test/unittest/common/sensor_native_test.cpp @@ -0,0 +1,185 @@ +/* + * 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 "sensor_agent_type.h" +#include "sensor_data_channel.h" +#include "sensor_service_client.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorNativeTest" }; +} + +class SensorNativeTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + static void HandleEvent(struct SensorEvent *events, int32_t num, void *data); + std::vector sensorsList_; + uint32_t sensorId_; + sptr sensorDataChannel_; + std::unique_ptr sensorServiceClient_; + bool dataReport_; +}; +void SensorNativeTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data) +{ + ASSERT_NE(events, nullptr); + HiLog::Info(LABEL, "%{public}s start,num : %{public}d", __func__, num); + SensorNativeTest *test = reinterpret_cast(data); + ASSERT_NE(test, nullptr); + for (int32_t i = 0; i < num; i++) { + if (events[i].sensorTypeId == (int32_t)test->sensorId_) { + test->dataReport_ = true; + } + } + return; +} +void SensorNativeTest::SetUpTestCase() +{} + +void SensorNativeTest::TearDownTestCase() +{} + +void SensorNativeTest::SetUp() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + sensorDataChannel_ = new (std::nothrow) SensorDataChannel(); + ASSERT_NE(sensorDataChannel_, nullptr); + sensorServiceClient_ = std::make_unique(); + ASSERT_NE(sensorServiceClient_, nullptr); + sensorsList_ = sensorServiceClient_->GetSensorList(); + ASSERT_NE(sensorsList_.size(), 0UL); + sensorId_ = sensorsList_[0].GetSensorId(); + int32_t ret = sensorDataChannel_->CreateSensorDataChannel(HandleEvent, this); + HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + sensorServiceClient_->TransferDataChannel(sensorDataChannel_); + dataReport_ = false; +} + +void SensorNativeTest::TearDown() +{ + sensorServiceClient_->DestroyDataChannel(); + sensorDataChannel_->DestroySensorDataChannel(); +} + +/* + * @tc.name: GetSensorList_001 + * @tc.desc: get sensor list + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, GetSensorList_001, TestSize.Level0) +{ + bool ret = sensorsList_.empty(); + HiLog::Info(LABEL, "GetSensorList_001,count : %{public}d!", int{ sensorsList_.size() }); + ASSERT_EQ(ret, false); +} + +/* + * @tc.name: GetSensorList_002 + * @tc.desc: Judge sensor info + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, GetSensorList_002, TestSize.Level0) +{ + for (const auto &it : sensorsList_) { + ASSERT_EQ(it.GetSensorId() == 0, true); + ASSERT_EQ(it.GetName().empty(), false); + ASSERT_EQ(it.GetVendor().empty(), false); + } + HiLog::Info(LABEL, "GetSensorList_002"); +} + +/* + * @tc.name: ClientSensorDataChannel_001 + * @tc.desc: do client sensor send data channel close + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, ClientSensorDataChannel_001, TestSize.Level0) +{ + int32_t ret = sensorDataChannel_->GetSendDataFd(); + HiLog::Info(LABEL, "ClientSensorDataChannel_001,ret : %{public}d!", ret); + ASSERT_EQ(ret, -1); +} + +/* + * @tc.name: ClientSensorDataChannel_002 + * @tc.desc: judge channel fd when create channel + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, ClientSensorDataChannel_002, TestSize.Level0) +{ + int32_t ret = sensorDataChannel_->GetReceiveDataFd(); + ASSERT_EQ((ret >= 0), true); +} + +/* + * @tc.name: ClientSensorDataChannel_003 + * @tc.desc: Judge read thread status when Destroy Channel + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, ClientSensorDataChannel_003, TestSize.Level0) +{ + int32_t ret = sensorDataChannel_->DestroySensorDataChannel(); + ASSERT_EQ(ret, ERR_OK); + bool result = false; + result = sensorDataChannel_->IsThreadExit(); + ASSERT_EQ(result, true); +} + +/* + * @tc.name: ClientSensorDataChannel_004 + * @tc.desc: Destroy ClientSensorDataChannel + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, ClientSensorDataChannel_004, TestSize.Level0) +{ + int32_t ret = sensorDataChannel_->DestroySensorDataChannel(); + ASSERT_EQ(ret, ERR_OK); + ret = sensorDataChannel_->GetSendDataFd(); + ASSERT_EQ(ret, -1); + ret = sensorDataChannel_->GetReceiveDataFd(); + ASSERT_EQ(ret, -1); +} + +/* + * @tc.name: SensorOperation_001 + * @tc.desc: disable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, SensorOperation_001, TestSize.Level1) +{ + auto sensorId = sensorsList_[0].GetSensorId(); + auto ret = sensorServiceClient_->DisableSensor(sensorId); + HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + dataReport_ = false; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ASSERT_EQ(dataReport_, false); +} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/test/unittest/phone/BUILD.gn b/frameworks/native/sensor/test/unittest/phone/BUILD.gn new file mode 100755 index 00000000..4e65b9b7 --- /dev/null +++ b/frameworks/native/sensor/test/unittest/phone/BUILD.gn @@ -0,0 +1,58 @@ +# 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/sensors_sensor/frameworks/sensor" + +####################################################### +ohos_unittest("SensorNativeTest") { + module_out_path = module_output_path + + sources = [ "./sensor_native_test.cpp" ] + + include_dirs = [ + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensors_sensor/utils/include", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/common/include", + "//utils/native/base/include", + ] + + deps = [ + #"$SUBSYSTEM_DIR/sensors_sensor/adapter/frameworks:libsensor_fwk_adapter", + "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] +} + +########################################################################### +group("unittest") { + testonly = true + deps = [ ":SensorNativeTest" ] +} diff --git a/frameworks/native/sensor/test/unittest/phone/sensor_native_test.cpp b/frameworks/native/sensor/test/unittest/phone/sensor_native_test.cpp new file mode 100755 index 00000000..f6621e5d --- /dev/null +++ b/frameworks/native/sensor/test/unittest/phone/sensor_native_test.cpp @@ -0,0 +1,110 @@ +/* + * 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 "sensor_agent_type.h" +#include "sensor_data_channel.h" +#include "sensor_service_client.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorNativeTest" }; +} + +class SensorNativeTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + static void HandleEvent(struct SensorEvent *events, int32_t num, void *data); + std::vector sensorsList_; + uint32_t sensorId_; + sptr sensorDataChannel_; + std::unique_ptr sensorServiceClient_; + bool dataReport_; +}; +void SensorNativeTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data) +{ + ASSERT_NE(events, nullptr); + HiLog::Info(LABEL, "%{public}s start,num : %{public}d", __func__, num); + SensorNativeTest *test = reinterpret_cast(data); + ASSERT_NE(test, nullptr); + for (int32_t i = 0; i < num; i++) { + if (events[i].sensorTypeId == (int32_t)test->sensorId_) { + test->dataReport_ = true; + } + } + return; +} +void SensorNativeTest::SetUpTestCase() +{} + +void SensorNativeTest::TearDownTestCase() +{} + +void SensorNativeTest::SetUp() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + sensorDataChannel_ = new (std::nothrow) SensorDataChannel(); + ASSERT_NE(sensorDataChannel_, nullptr); + sensorServiceClient_ = std::make_unique(); + ASSERT_NE(sensorServiceClient_, nullptr); + sensorsList_ = sensorServiceClient_->GetSensorList(); + ASSERT_NE(sensorsList_.size(), 0UL); + sensorId_ = sensorsList_[0].GetSensorId(); + auto ret = sensorDataChannel_->CreateSensorDataChannel(HandleEvent, this); + HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + sensorServiceClient_->TransferDataChannel(sensorDataChannel_); + dataReport_ = false; +} + +void SensorNativeTest::TearDown() +{ + sensorServiceClient_->DestroyDataChannel(); + sensorDataChannel_->DestroySensorDataChannel(); +} + +/* + * @tc.name: SensorOperation_001 + * @tc.desc: enable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorNativeTest, SensorOperation_001, TestSize.Level1) +{ + HiLog::Info(LABEL, "SensorOperation_001 begin"); + uint64_t samplingPeriodNs = 10000000; + uint64_t maxReportDelayNs = 0; + auto sensorId = sensorsList_[0].GetSensorId(); + auto ret = sensorServiceClient_->EnableSensor(sensorId, samplingPeriodNs, maxReportDelayNs); + HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + dataReport_ = false; + // wait evennt + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + ASSERT_EQ(dataReport_, true); +} +} // namespace Sensors +} // namespace OHOS diff --git a/interfaces/native/BUILD.gn b/interfaces/native/BUILD.gn new file mode 100755 index 00000000..8972d418 --- /dev/null +++ b/interfaces/native/BUILD.gn @@ -0,0 +1,55 @@ +# 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_sensor" + +############################################## +ohos_ndk_library("libsensor_ndk") { + output_name = "sensor" + ndk_description_file = "./libsensor.json" + min_compact_version = "6" +} + +ohos_shared_library("sensor_interface_native") { + output_name = "sensor_agent" + sources = [ "src/sensor_agent.cpp" ] + + include_dirs = [ + "include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "$SUBSYSTEM_DIR/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/utils/include", + #"//drivers/peripheral/sensor/interfaces/include", + "$SUBSYSTEM_DIR/interfaces/native/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + ] + deps = [ + "$SUBSYSTEM_DIR/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/utils:libsensor_utils", + "//utils/native/base:utils", + "$SUBSYSTEM_DIR/interfaces/native:libsensor_ndk", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + part_name = "sensors_sensor" + subsystem_name = "sensors" +} + +############################################## +group("sensor_ndk_target") { + deps = [ ":sensor_interface_native" ] +} diff --git a/interfaces/native/include/sensor_agent.h b/interfaces/native/include/sensor_agent.h new file mode 100755 index 00000000..ead362c9 --- /dev/null +++ b/interfaces/native/include/sensor_agent.h @@ -0,0 +1,137 @@ +/* + * 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 PanSensor + * @{ + * + * @brief Provides standard open APIs for you to use common capabilities of sensors. + * + * For example, you can call these APIs to obtain sensor information, + * subscribe to or unsubscribe from sensor data, enable or disable a sensor, + * and set the sensor data reporting mode. + * + * @since 5 + */ + +/** + * @file sensor_agent.h + * + * @brief Declares common APIs for sensor management, such as APIs for subscribing to + * and obtaining sensor data, enabling a sensor, and setting the sensor data reporting mode. + * + * @since 5 + */ + +#ifndef SENSOR_AGENT_H +#define SENSOR_AGENT_H + +#include "sensor_agent_type.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** + * @brief Obtains information about all sensors in the system. + * + * @param sensorInfo Indicates the double pointer to the information about all sensors in the system. + * For details, see {@link SensorInfo}. + * @param count Indicates the pointer to the total number of sensors in the system. + * @return Returns 0 if the information is obtained; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count); +/** + * @brief Subscribes to sensor data. The system will report the obtained sensor data to the subscriber. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. For details, + * see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @return Returns 0 if the subscription is successful; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t SubscribeSensor(int32_t sensorTypeId, const SensorUser *user); +/** + * @brief Unsubscribes from sensor data. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. + * For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @return Returns 0 if the unsubscription is successful; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t UnsubscribeSensor(int32_t sensorTypeId, const SensorUser *user); +/** + * @brief Sets the data sampling interval and data reporting interval for the specified sensor. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. + * For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @param samplingInterval Indicates the sensor data sampling interval to set, in nanoseconds. + * @param reportInterval Indicates the sensor data reporting interval, in nanoseconds. + * @return Returns 0 if the setting is successful; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t SetBatch(int32_t sensorTypeId, const SensorUser *user, int64_t samplingInterval, int64_t reportInterval); +/** + * @brief Enables the sensor that has been subscribed to. The subscriber can obtain the sensor data + * only after the sensor is enabled. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. + * For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @return Returns 0 if the sensor is successfully enabled; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t ActivateSensor(int32_t sensorTypeId, const SensorUser *user); +/** + * @brief Disables an enabled sensor. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. + * For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @return Returns 0 if the sensor is successfully disabled; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t DeactivateSensor(int32_t sensorTypeId, const SensorUser *user); +/** + * @brief Sets the data reporting mode for the specified sensor. + * + * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}. + * @param user Indicates the pointer to the sensor subscriber that requests sensor data. + * For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor. + * @param mode Indicates the data reporting mode to set. For details, see {@link SensorMode}. + * @return Returns 0 if the sensor data reporting mode is successfully set; returns a non-zero value otherwise. + * + * @since 5 + */ +int32_t SetMode(int32_t sensorTypeId, const SensorUser *user, int32_t mode); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif /* SENSOR_AGENT_H */ +/** @} */ \ No newline at end of file diff --git a/interfaces/native/include/sensor_agent_type.h b/interfaces/native/include/sensor_agent_type.h new file mode 100755 index 00000000..ca2455e7 --- /dev/null +++ b/interfaces/native/include/sensor_agent_type.h @@ -0,0 +1,464 @@ +/* + * 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 PanSensor + * @{ + * + * @brief Provides standard open APIs for you to use common capabilities of sensors. + * + * For example, you can call these APIs to obtain sensor information, + * subscribe to or unsubscribe from sensor data, enable or disable a sensor, + * and set the sensor data reporting mode. + * + * @since 5 + */ + +/** + * @file sensor_agent_type.h + * + * @brief Defines the basic data used by the sensor agent to manage sensors. + * + * @since 5 + */ + +#ifndef SENSOR_AGENT_TYPE_H +#define SENSOR_AGENT_TYPE_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** Maximum length of the sensor name */ +#ifndef SENSOR_NAME_MAX_LEN2 +#define SENSOR_NAME_MAX_LEN2 48 +#endif /* SENSOR_NAME_MAX_LEN */ +/** Size of sensor data */ +#ifndef SENSOR_USER_DATA_SIZE +#define SENSOR_USER_DATA_SIZE 104 +#endif /* SENSOR_USER_DATA_SIZE */ +/** Maximum length of the sensor version */ +#ifndef VERSION_MAX_LEN +#define VERSION_MAX_LEN 16 +#endif /* SENSOR_USER_DATA_SIZE */ + +/** + * @brief Enumerates sensor types. + * + * @since 5 + */ +typedef enum SensorTypeId { + SENSOR_TYPE_ID_NONE = 0, /**< None */ + SENSOR_TYPE_ID_ACCELEROMETER = 1, /**< Acceleration sensor */ + SENSOR_TYPE_ID_GYROSCOPE = 2, /**< Gyroscope sensor */ + SENSOR_TYPE_ID_PHOTOPLETHYSMOGRAPH = 3, /**< Photoplethysmography sensor */ + SENSOR_TYPE_ID_ELECTROCARDIOGRAPH = 4, /**< Electrocardiogram (ECG) sensor */ + SENSOR_TYPE_ID_AMBIENT_LIGHT = 5, /**< Ambient light sensor */ + SENSOR_TYPE_ID_MAGNETIC_FIELD = 6, /**< Magnetic field sensor */ + SENSOR_TYPE_ID_CAPACITIVE = 7, /**< Capacitive sensor */ + SENSOR_TYPE_ID_BAROMETER = 8, /**< Barometric pressure sensor */ + SENSOR_TYPE_ID_TEMPERATURE = 9, /**< Temperature sensor */ + SENSOR_TYPE_ID_HALL = 10, /**< Hall effect sensor */ + SENSOR_TYPE_ID_GESTURE = 11, /**< Gesture sensor */ + SENSOR_TYPE_ID_PROXIMITY = 12, /**< Proximity sensor */ + SENSOR_TYPE_ID_HUMIDITY = 13, /**< Humidity sensor */ + SENSOR_TYPE_ID_PHYSICAL_MAX = 0xFF, /**< Maximum type ID of a physical sensor */ + SENSOR_TYPE_ID_ORIENTATION = 256, /**< Orientation sensor */ + SENSOR_TYPE_ID_GRAVITY = 257, /**< Gravity sensor */ + SENSOR_TYPE_ID_LINEAR_ACCELERATION = 258, /**< Linear acceleration sensor */ + SENSOR_TYPE_ID_ROTATION_VECTOR = 259, /**< Rotation vector sensor */ + SENSOR_TYPE_ID_AMBIENT_TEMPERATURE = 260, /**< Ambient temperature sensor */ + SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED = 261, /**< Uncalibrated magnetic field sensor */ + SENSOR_TYPE_ID_GAME_ROTATION_VECTOR = 262, /**< Game rotation vector sensor */ + SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED = 263, /**< Uncalibrated gyroscope sensor */ + SENSOR_TYPE_ID_SIGNIFICANT_MOTION = 264, /**< Significant motion sensor */ + SENSOR_TYPE_ID_PEDOMETER_DETECTION = 265, /**< Pedometer detection sensor */ + SENSOR_TYPE_ID_PEDOMETER = 266, /**< Pedometer sensor */ + SENSOR_TYPE_ID_GEOMAGNETIC_ROTATION_VECTOR = 277, /**< Geomagnetic rotation vector sensor */ + SENSOR_TYPE_ID_HEART_RATE = 278, /**< Heart rate sensor */ + SENSOR_TYPE_ID_DEVICE_ORIENTATION = 279, /**< Device orientation sensor */ + SENSOR_TYPE_ID_WEAR_DETECTION = 280, /**< Wear detection sensor */ + SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED = 281, /**< Uncalibrated acceleration sensor */ + SENSOR_TYPE_ID_MAX = 30, /**< Maximum number of sensor type IDs*/ +} SensorTypeId; + +/** + * @brief Defines sensor information. + * + * @since 5 + */ +typedef struct SensorInfo { + char sensorName[SENSOR_NAME_MAX_LEN2]; /**< Sensor name */ + char vendorName[SENSOR_NAME_MAX_LEN2]; /**< Sensor vendor */ + char firmwareVersion[VERSION_MAX_LEN]; /**< Sensor firmware version */ + char hardwareVersion[VERSION_MAX_LEN]; /**< Sensor hardware version */ + int32_t sensorTypeId; /**< Sensor type ID */ + int32_t sensorId; /**< Sensor ID */ + float maxRange; /**< Maximum measurement range of the sensor */ + float precision; /**< Sensor accuracy */ + float power; /**< Sensor power */ +} SensorInfo; + +/** + * @brief Defines the data reported by the sensor. + * + * @since 5 + */ +typedef struct SensorEvent { + int32_t sensorTypeId; /**< Sensor type ID */ + int32_t version; /**< Sensor algorithm version */ + int64_t timestamp; /**< Time when sensor data was reported */ + uint32_t option; /**< Sensor data options, including the measurement range and accuracy */ + int32_t mode; /**< Sensor data reporting mode (described in {@link SensorMode}) */ + uint8_t *data; /**< Sensor data */ + uint32_t dataLen; /**< Sensor data length */ +} SensorEvent; + +struct Test { +char ip[30]; +char name[30]; +int32_t *data; +}; + +/** + * @brief Defines the callback for data reporting by the sensor agent. + * + * @since 5 + */ +typedef void (*RecordSensorCallback)(SensorEvent *event); + +/** + * @brief Defines a reserved field for the sensor data subscriber. + * + * @since 5 + */ +typedef struct UserData { + char userData[SENSOR_USER_DATA_SIZE]; /**< Reserved for the sensor data subscriber */ +} UserData; + +/** + * @brief Defines information about the sensor data subscriber. + * + * @since 5 + */ +typedef struct SensorUser { + char name[SENSOR_NAME_MAX_LEN2]; /**< Name of the sensor data subscriber */ + RecordSensorCallback callback; /**< Callback for reporting sensor data */ + UserData *userData; /**< Reserved field for the sensor data subscriber */ +} SensorUser; + +/** + * @brief Enumerates data reporting modes of sensors. + * + * @since 5 + */ +typedef enum SensorMode { + SENSOR_DEFAULT_MODE = 0, /**< Default data reporting mode */ + SENSOR_REALTIME_MODE = 1, /**< Real-time data reporting mode to report a group of data each time */ + SENSOR_ON_CHANGE = 2, /**< Real-time data reporting mode to report data upon status changes */ + SENSOR_ONE_SHOT = 3, /**< Real-time data reporting mode to report data only once */ + SENSOR_FIFO_MODE = 4, /**< FIFO-based data reporting mode to report data based on the BatchCnt setting */ + SENSOR_MODE_MAX2, /**< Maximum sensor data reporting mode */ +} SensorMode; + +/** + * @brief 加速度传感器的数据结构 + */ +typedef struct AccelData { + /**< 加速度X轴 */ + int32_t axisX; + /**< 加速度Y轴 */ + int32_t axisY; + /**< 加速度Z轴 */ + int32_t axisZ; + /**< 校准精度 */ + int32_t accuracy; +} AccelData; + +/** + * @brief 线性加速度传感器的数据结构 + */ +typedef struct LinearAccelData { + /**< 线性加速度X轴 */ + int32_t axisX; + /**< 线性加速度Y轴 */ + int32_t axisY; + /**< 线性加速度Z轴 */ + int32_t axisZ; + /**< 校准精度 */ + int32_t accuracy; +} LineraAccelData; + +/** + * @brief 陀螺仪传感器的数据结构 + */ +typedef struct GyroscopeData { + /**< 加速度X轴 */ + int32_t axisX; + /**< 加速度Y轴 */ + int32_t axisY; + /**< 加速度Z轴 */ + int32_t axisZ; + /**< 校准精度 */ + int32_t accuracy; +} GyroscopeData; + +/** + * @brief 重力传感器的数据结构 + */ +typedef struct GravityData { + /**< 重力加速度X轴 */ + int32_t axisX; + /**< 重力加速度Y轴 */ + int32_t axisY; + /**< 重力加速度Z轴 */ + int32_t axisZ; + /**< 校准精度 */ + int32_t accuracy; +} GravityData; + +/** + * @brief 未校准加速度传感器的数据结构 + */ +typedef struct AccelUncalibratedData { + /**< 未校准加速度X轴 */ + int32_t axisX; + /**< 未校准加速度Y轴 */ + int32_t axisY; + /**< 未校准加速度Z轴 */ + int32_t axisZ; + /**< 未校准加速度X轴偏量 */ + int32_t axisBiasX; + /**< 未校准加速度Y轴偏量 */ + int32_t axisBiasY; + /**< 未校准加速度Z轴偏量 */ + int32_t axisBiasZ; +} AccelUncalibratedData; + +/** + * @brief 未校准陀螺仪传感器的数据结构 + */ +typedef struct GyroUncalibratedData { + /**< 未校准加速度X轴 */ + int32_t axisX; + /**< 未校准加速度Y轴 */ + int32_t axisY; + /**< 未校准加速度Z轴 */ + int32_t axisZ; + /**< 未校准加速度X轴偏量 */ + int32_t axisBiasX; + /**< 未校准加速度Y轴偏量 */ + int32_t axisBiasY; + /**< 未校准加速度Z轴偏量 */ + int32_t axisBiasZ; +} GyroUncalibratedData; + +/** + * @brief 大幅度动作传感器的数据结构 + */ +typedef struct SignificantMotionData { + /**< 标量 */ + int32_t scalar; +} SignificantMotionData; + +/** + * @brief 计步器检测传感器的数据结构 + */ +typedef struct PedometerDetectData { + /**< 标量 */ + int32_t scalar; +} PedometerDetectData; + +/** + * @brief 计步器传感器的数据结构 + */ +typedef struct PedometerData { + /**< 标量 */ + int32_t scalar; +} PedometerData; + +/** + * @brief 环境温度传感器的数据结构 + */ +typedef struct AmbientTemperatureData { + /**< 标量 */ + int32_t scalar; +} AmbientTemperatureData; + +/** + * @brief 湿度传感器的数据结构 + */ +typedef struct HumidityData { + /**< 标量 */ + int32_t scalar; +} HumidityData; + +/** + * @brief 磁场传感器的数据结构 + */ +typedef struct MagneticFieldData { + /**< 磁力计X轴 */ + int32_t axisX; + /**< 磁力计Y轴 */ + int32_t axisY; + /**< 磁力计Z轴 */ + int32_t axisZ; + /**< 磁力计数据精度 */ + int32_t accuracy; +} MagneticFieldData; + +/** + * @brief 未校准磁场传感器的数据结构 + */ +typedef struct MagneticFieldUncalibratedData { + /**< 磁力计X轴 */ + int32_t axisX; + /**< 磁力计Y轴 */ + int32_t axisY; + /**< 磁力计Z轴 */ + int32_t axisZ; + /**< 磁力计X轴偏量 */ + int32_t axisBiasX; + /**< 磁力计Y轴偏量 */ + int32_t axisBiasY; + /**< 磁力计Z轴偏量 */ + int32_t axisBiasZ; +} MagneticFieldUncalibratedData; + +/** + * @brief 气压计传感器的数据结构 + */ +typedef struct BarometerData { + /**< 气压值 */ + int32_t pressure; +} BarometerData; + +/** + * @brief 设备方向传感器的数据结构 + */ +typedef struct DeviceOrientationData { + /**< 标量 */ + int32_t scalar; +} DeviceOrientationData; + +/** + * @brief 方向传感器的数据结构 + */ +typedef struct OrientationData { + /**< 方位角(磁北方向与 Y 轴之间的夹角) */ + int32_t axisX; + /**< 俯仰(绕 X 轴旋转,Z 轴向 Y 轴移动时为正值) */ + int32_t axisY; + /**< 滚动(绕 Y 轴旋转,当 X 轴向 Z 轴移动时为正值)*/ + int32_t axisZ; + /**< 校准精度 */ + int32_t accuracy; +} OrientationData; + +/** + * @brief 旋转矢量传感器的数据结构 + */ +typedef struct RotationVectorData { + /**< x分量 */ + int32_t axisX; + /**< y分量 */ + int32_t axisY; + /**< z分量 */ + int32_t axisZ; + /**< w分量 */ + int32_t axisW; +} RotationVectorData; + +/** + * @brief 游戏旋转矢量传感器的数据结构 + */ +typedef struct GameRotationVectorData { + /**< x分量 */ + int32_t axisX; + /**< y分量 */ + int32_t axisY; + /**< z分量 */ + int32_t axisZ; + /**< w分量 */ + int32_t axisW; +} GameRotationVectorData; + +/** + * @brief 地磁旋转矢量传感器的数据结构 + */ +typedef struct GeomagneticRotaVectorData { + /**< x分量 */ + int32_t axisX; + /**< y分量 */ + int32_t axisY; + /**< z分量 */ + int32_t axisZ; + /**< w分量 */ + int32_t axisW; +} GeomagneticRotaVectorData; + +/** + * @brief 接近光传感器的数据结构 + */ +typedef struct ProximityData { + /**< 接近程度 */ + int32_t scalar; +} ProximityData; + +/** + * @brief 环境光传感器的数据结构 + */ +typedef struct AmbientLightData { + /**< 环境强弱 */ + int32_t scalar; +} AmbientLightData; + +/** + * @brief 元数据传感器的数据结构 + */ +typedef struct MetaData { + /**< 标量 */ + int32_t scalar; +} MetaData; + +/** + * @brief 心率传感器的数据结构 + */ +typedef struct HeartRateData { + /**< 心率值,单位bpm */ + int32_t heartRateBpm; + /**< 心率状态 */ + int32_t temperatureStatus; +} HeartRateData; + +/** + * @brief 佩戴检测传感器的数据结构 + */ +typedef struct WearDetectionData { + /**< 标量 */ + int32_t scalar; +} WearDetectionData; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif /* SENSOR_AGENT_TYPE_H */ +/**< @} */ \ No newline at end of file diff --git a/interfaces/native/libsensor.json b/interfaces/native/libsensor.json new file mode 100755 index 00000000..e2d65c4f --- /dev/null +++ b/interfaces/native/libsensor.json @@ -0,0 +1,24 @@ +[ + { + "first_introduced": "6", + "name": "GetAllSensors" + }, + { + "name": "SubscribeSensor" + }, + { + "name": "UnsubscribeSensor" + }, + { + "name": "SetBatch" + }, + { + "name": "ActivateSensor" + }, + { + "name": "DeactivateSensor" + }, + { + "name": "SetMode" + } +] \ No newline at end of file diff --git a/interfaces/native/src/sensor_agent.cpp b/interfaces/native/src/sensor_agent.cpp new file mode 100755 index 00000000..fe8cf6c6 --- /dev/null +++ b/interfaces/native/src/sensor_agent.cpp @@ -0,0 +1,120 @@ +/* + * 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 "sensor_agent.h" + +#include "sensor_agent_proxy.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +static const HiLogLabel LABEL = {LOG_CORE, OHOS::SensorsLogDomain::SENSORS_INTERFACE, "SensorNativeAPI"}; + +static const SensorAgentProxy *GetInstance() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *obj = SensorAgentProxy::GetSensorsObj(); + return obj; +} + +int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->GetAllSensors(sensorInfo, count); +} + +int32_t ActivateSensor(int32_t sensorId, const SensorUser *user) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->ActivateSensor(sensorId, user); +} + +int32_t DeactivateSensor(int32_t sensorId, const SensorUser *user) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->DeactivateSensor(sensorId, user); +} + +int32_t SetBatch(int32_t sensorId, const SensorUser *user, int64_t samplingInterval, int64_t reportInterval) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->SetBatch(sensorId, user, samplingInterval, reportInterval); +} + +int32_t SubscribeSensor(int32_t sensorId, const SensorUser *user) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->SubscribeSensor(sensorId, user); +} + +int32_t UnsubscribeSensor(int32_t sensorId, const SensorUser *user) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->UnsubscribeSensor(sensorId, user); +} + +int32_t SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->SetMode(sensorId, user, mode); +} + +int32_t SetOption(int32_t sensorId, const SensorUser *user, int32_t option) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == NULL) { + HiLog::Error(LABEL, "%s proxy is null", __func__); + return OHOS::Sensors::ERROR; + } + return proxy->SetOption(sensorId, user, option); +} \ No newline at end of file diff --git a/interfaces/native/test/BUILD.gn b/interfaces/native/test/BUILD.gn new file mode 100755 index 00000000..b9f30f3c --- /dev/null +++ b/interfaces/native/test/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/test.gni") + +SUBSYSTEM_DIR = "//base/sensors" +module_output_path = "sensors/sensors_sensor/interfaces" + +###########################SensorAgentTest########################### +ohos_unittest("SensorAgentTest") { + module_out_path = module_output_path + + sources = [ "unittest/sensor_agent_test.cpp" ] + + include_dirs = [ + "//utils/native/base/include", + "$SUBSYSTEM_DIR/sensors_sensor/utils/include", + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native:sensor_ndk_target", + "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", + "ipc:ipc_core", + ] +} + +###########################end########################### +group("unittest") { + testonly = true + deps = [ ":SensorAgentTest" ] +} diff --git a/interfaces/native/test/unittest/sensor_agent_test.cpp b/interfaces/native/test/unittest/sensor_agent_test.cpp new file mode 100755 index 00000000..338e1b31 --- /dev/null +++ b/interfaces/native/test/unittest/sensor_agent_test.cpp @@ -0,0 +1,95 @@ +/* + * 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 "sensor_agent.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorAgentTest" }; +} // namespace + +class SensorAgentTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void SensorAgentTest::SetUpTestCase() +{} + +void SensorAgentTest::TearDownTestCase() +{} + +void SensorAgentTest::SetUp() +{} + +void SensorAgentTest::TearDown() +{} + +void SensorDataCallbackImpl(SensorEvent *event) +{ + if (event == nullptr) { + HiLog::Error(LABEL, "SensorDataCallbackImpl event is null"); + return; + } + float *sensorData = (float *)event[0].data; + HiLog::Info(LABEL, "SensorDataCallbackImpl sensorTypeId: %{public}d, version: %{public}d, dataLen: %{public}d, dataLen: %{public}f\n", + event[0].sensorTypeId, event[0].version, event[0].dataLen, *(sensorData)); +} + +/* + * @tc.name: SensorNativeApiTest_001 + * @tc.desc: sensor native api test + * @tc.type: FUNC + * @tc.author: wuzhihui + */ +HWTEST_F(SensorAgentTest, SensorNativeApiTest_001, TestSize.Level1) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + + int32_t sensorTypeId = 0; + SensorUser user; + + user.callback = SensorDataCallbackImpl; + + int32_t ret = SubscribeSensor(sensorTypeId, &user); + ASSERT_EQ(ret, 0); + + ret = SetBatch(sensorTypeId, &user, 100000000, 100000000); + ASSERT_EQ(ret, 0); + ret = ActivateSensor(sensorTypeId, &user); + ASSERT_EQ(ret, 0); + + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + ASSERT_EQ(ret, 0); + + ret = UnsubscribeSensor(sensorTypeId, &user); + ASSERT_EQ(ret, 0); + ret = DeactivateSensor(sensorTypeId, &user); + ASSERT_EQ(ret, 0); +} +} // namespace Sensors +} // namespace OHOS diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn new file mode 100755 index 00000000..143087c3 --- /dev/null +++ b/interfaces/plugin/BUILD.gn @@ -0,0 +1,47 @@ +# 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("sensor") { + include_dirs = [ + "//third_party/node/src", + "//native_engine", + "../native/include", + "//third_party/libuv/include", + "//utils/native/base/include", + "./include", + ] + defines = [ + "APP_LOG_TAG = \"sensroJs\"", + "LOG_DOMAIN = 0xD002700", + ] + sources = [ + "./src/sensor_js.cpp", + "./src/sensor_napi_utils.cpp", + ] + deps = [ + "//foundation/ace/napi:ace_napi", + "../native:sensor_interface_native", + "//utils/native/base:utils", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + relative_install_dir = "module" + part_name = "sensors_sensor" + subsystem_name = "sensors" +} + +group("sensor_js_target") { + deps = [ ":sensor" ] +} diff --git a/interfaces/plugin/include/sensor_js.h b/interfaces/plugin/include/sensor_js.h new file mode 100755 index 00000000..4d8720d2 --- /dev/null +++ b/interfaces/plugin/include/sensor_js.h @@ -0,0 +1,20 @@ +/* + * 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 "sensor_agent.h" + +static int32_t UnsubscribeSensor(int32_t sensorTypeId); +static void DataCallbackImpl(SensorEvent *event); +static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback); + diff --git a/interfaces/plugin/include/sensor_napi_utils.h b/interfaces/plugin/include/sensor_napi_utils.h new file mode 100755 index 00000000..cc2d8728 --- /dev/null +++ b/interfaces/plugin/include/sensor_napi_utils.h @@ -0,0 +1,41 @@ +/* + * 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 "sensor_agent.h" +#include + +#define EVENT_INVALID_PARAMETER (-1); +#define EVENT_OK 0; +struct AsyncCallbackInfo { + napi_env env; + napi_async_work asyncWork; + napi_deferred deferred; + napi_ref callback[1] = { 0 }; + int32_t sensorTypeId; + int32_t sensorDataLength; + float sensorData[16]; + 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); +bool GetCppBool(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); +napi_value GetUndefined(napi_env env); \ No newline at end of file diff --git a/interfaces/plugin/src/sensor_js.cpp b/interfaces/plugin/src/sensor_js.cpp new file mode 100755 index 00000000..176e19c9 --- /dev/null +++ b/interfaces/plugin/src/sensor_js.cpp @@ -0,0 +1,294 @@ +/* + * 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 "sensor_js.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hilog/log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "sensor_agent.h" +#include "sensor_napi_utils.h" + +#include "refbase.h" +#include "securec.h" + +using namespace OHOS::HiviewDFX; +static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "SensorJsAPI"}; + +static std::map g_onceCallbackInfos; +static std::map g_onCallbackInfos; + +static void DataCallbackImpl(SensorEvent *event) +{ + HiLog::Info(LABEL, "%{public}s in", __func__); + if (event == nullptr) { + HiLog::Error(LABEL, "%{public}s event is null!", __func__); + return; + } + int32_t sensorTypeId = event->sensorTypeId; + float *data = (float *)(event->data); + for (auto &onCallbackInfo: g_onCallbackInfos) { + if ((int32_t)onCallbackInfo.first == sensorTypeId) { + onCallbackInfo.second->sensorTypeId = sensorTypeId; + onCallbackInfo.second->sensorDataLength = event->dataLen; + if (memcpy_s(onCallbackInfo.second->sensorData, sizeof(data), data, sizeof(data)) != EOK) { + HiLog::Error(LABEL, "%{public}s copy data failed", __func__); + return; + } + onCallbackInfo.second->status = 1; + EmitAsyncCallbackWork((struct AsyncCallbackInfo *)(onCallbackInfo.second)); + } + } + if (g_onceCallbackInfos.find(sensorTypeId) == g_onceCallbackInfos.end()) { + HiLog::Debug(LABEL, "%{public}s no subscribe to the sensor data once", __func__); + return; + } + struct AsyncCallbackInfo *onceCallbackInfo = g_onceCallbackInfos[sensorTypeId]; + onceCallbackInfo->sensorTypeId = sensorTypeId; + onceCallbackInfo->sensorDataLength = event->dataLen; + if (memcpy_s(onceCallbackInfo->sensorData, sizeof(data), data, sizeof(data)) != EOK) { + HiLog::Error(LABEL, "%{public}s copy data failed", __func__); + return; + } + onceCallbackInfo->status = 2; + EmitAsyncCallbackWork((struct AsyncCallbackInfo *)(onceCallbackInfo)); + if (g_onCallbackInfos.find(sensorTypeId) == g_onCallbackInfos.end()) { + HiLog::Debug(LABEL, "%{public}s no subscription to change sensor data, need to cancel registration", __func__); + UnsubscribeSensor(sensorTypeId); + } + g_onceCallbackInfos.erase(sensorTypeId); + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +static const SensorUser user = { + .callback = DataCallbackImpl +}; + +static int32_t UnsubscribeSensor(int32_t sensorTypeId) +{ + HiLog::Info(LABEL, "%{public}s in", __func__); + int32_t ret = UnsubscribeSensor(sensorTypeId, &user); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s UnsubscribeSensor failed", __func__); + return ret; + } + ret = DeactivateSensor(sensorTypeId, &user); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s DeactivateSensor failed", __func__); + return ret; + } + HiLog::Info(LABEL, "%{public}s left", __func__); + return 0; +} + +static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) +{ + HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d, interval: %{public}lld ", __func__, + sensorTypeId, interval); + int32_t ret = SubscribeSensor(sensorTypeId, &user); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__); + return ret; + } + ret = SetBatch(sensorTypeId, &user, interval, 0); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s set batch failed", __func__); + return ret; + } + ret = ActivateSensor(sensorTypeId, &user); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s activateSensor failed", __func__); + return ret; + } + return 0; +} + +static napi_value Once(napi_env env, napi_callback_info info) +{ + HiLog::Info(LABEL, "%{public}s in", __func__); + size_t argc; + napi_value args[2]; + napi_value thisVar; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL)); + + if (argc != 2) { + HiLog::Error(LABEL, "%{public}s Invalid input, number of argument should be two", __func__); + return nullptr; + } + if (!IsMatchType(args[0], napi_number, env)) { + HiLog::Error(LABEL, "%{public}s argument should be number type", __func__); + return nullptr; + } + int32_t sensorTypeId = GetCppInt32(args[0], env); + if (!IsMatchType(args[1], napi_function, env)) { + HiLog::Error(LABEL, "%{public}s argument should be function type", __func__); + return nullptr; + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + g_onceCallbackInfos[sensorTypeId] = asyncCallbackInfo; + if (g_onCallbackInfos.find(sensorTypeId) == g_onCallbackInfos.end()) { + HiLog::Debug(LABEL, "%{public}s no subscription to change sensor data, registration is required", __func__); + int32_t ret = SubscribeSensor(sensorTypeId, 200000000, DataCallbackImpl); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s subscribe Sensor failed", __func__); + asyncCallbackInfo->status = -1; + EmitAsyncCallbackWork(asyncCallbackInfo); + g_onceCallbackInfos.erase(sensorTypeId); + return nullptr; + } + } + HiLog::Info(LABEL, "%{public}s left", __func__); + return nullptr; +} + +static napi_value On(napi_env env, napi_callback_info info) +{ + HiLog::Info(LABEL, "%{public}s in", __func__); + size_t argc; + napi_value args[3]; + napi_value thisVar; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL)); + if (argc <= 1 || argc > 3) { + HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__); + return nullptr; + } + if (!IsMatchType(args[0], napi_number, env)) { + HiLog::Error(LABEL, "%{public}s the first parameter should be napi_number type", __func__); + return nullptr; + } + int32_t sensorTypeId = GetCppInt32(args[0], env); + if (!IsMatchType(args[1], napi_function, env)) { + HiLog::Error(LABEL, "%{public}s the second parameter should be napi_function type!", __func__); + return nullptr; + } + int64_t interval = 200000000; + if (argc == 3) { + HiLog::Info(LABEL, "%{public}s argc = 3!", __func__); + napi_value value = NapiGetNamedProperty(args[2], "interval", env); + if (!IsMatchType(value, napi_number, env)) { + HiLog::Error(LABEL, "%{public}s argument should be napi_number type!", __func__); + return nullptr; + } + interval = GetCppInt64(value, env); + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + g_onCallbackInfos[sensorTypeId] = asyncCallbackInfo; + int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl); + if (ret < 0) { + HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__); + asyncCallbackInfo->status = -1; + EmitAsyncCallbackWork(asyncCallbackInfo); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + g_onCallbackInfos.erase(sensorTypeId); + return nullptr; + } + HiLog::Info(LABEL, "%{public}s out", __func__); + return nullptr; +} + +static napi_value Off(napi_env env, napi_callback_info info) +{ + HiLog::Info(LABEL, "%{public}s in", __func__); + size_t argc; + napi_value args[2]; + napi_value thisVar; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL)); + + if (argc < 1) { + HiLog::Error(LABEL, "%{public}s Invalid input.", __func__); + return nullptr; + } + if (!IsMatchType(args[0], napi_number, env)) { + HiLog::Error(LABEL, "%{public}s argument should be number type!", __func__); + return nullptr; + } + int32_t sensorTypeId = GetCppInt32(args[0], env); + if (!IsMatchType(args[1], napi_function, env)) { + HiLog::Error(LABEL, "%{public}s argument should be function type!", __func__); + return nullptr; + } + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]); + int32_t ret = UnsubscribeSensor(sensorTypeId); + if (ret < 0) { + asyncCallbackInfo->status = -1; + HiLog::Error(LABEL, "%{public}s UnsubscribeSensor failed", __func__); + } else { + HiLog::Error(LABEL, "%{public}s UnsubscribeSensor success", __func__); + asyncCallbackInfo->status = 0; + if (g_onCallbackInfos.find(sensorTypeId) != g_onCallbackInfos.end()) { + napi_delete_reference(env, g_onCallbackInfos[sensorTypeId]->callback[0]); + napi_delete_async_work(env, g_onCallbackInfos[sensorTypeId]->asyncWork); + delete g_onCallbackInfos[sensorTypeId]; + g_onCallbackInfos[sensorTypeId] = nullptr; + g_onCallbackInfos.erase(sensorTypeId); + } + } + EmitAsyncCallbackWork(asyncCallbackInfo); + HiLog::Info(LABEL, "%{public}s left", __func__); + return nullptr; +} + +EXTERN_C_START + +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("on", On), + DECLARE_NAPI_FUNCTION("once", Once), + DECLARE_NAPI_FUNCTION("off", Off) + }; + 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 = "sensor", + .nm_priv = ((void *)0), + .reserved = {0} +}; + +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} diff --git a/interfaces/plugin/src/sensor_napi_utils.cpp b/interfaces/plugin/src/sensor_napi_utils.cpp new file mode 100755 index 00000000..e11ae61f --- /dev/null +++ b/interfaces/plugin/src/sensor_napi_utils.cpp @@ -0,0 +1,172 @@ +/* + * 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 "sensor_napi_utils.h" + +#include +#include +#include +#include + +#include "hilog/log.h" + +using namespace OHOS::HiviewDFX; +static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "SensorJsAPI"}; +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; +} + +int64_t GetCppInt64(napi_value value, napi_env env) +{ + int64_t number; + napi_get_value_int64(env, value, &number); + return number; +} + +bool GetCppBool(napi_value value, napi_env env) +{ + bool number; + napi_get_value_bool(env, value, &number); + return number; +} + +napi_value GetUndefined(napi_env env) +{ + napi_value value; + napi_get_undefined(env, &value); + return value; +} + +std::map> g_sensorAttributeList = { + { 0, { "x" } }, + { SENSOR_TYPE_ID_ACCELEROMETER, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_GYROSCOPE, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_AMBIENT_LIGHT, { "intensity" } }, + { SENSOR_TYPE_ID_MAGNETIC_FIELD, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_BAROMETER, { "pressure" } }, + { SENSOR_TYPE_ID_HALL, { "status" } }, + { SENSOR_TYPE_ID_PROXIMITY, { "distance" } }, + { SENSOR_TYPE_ID_HUMIDITY, { "humidity" } }, + { SENSOR_TYPE_ID_ORIENTATION, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_GRAVITY, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_LINEAR_ACCELERATION, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_ROTATION_VECTOR, { "x", "y", "z" } }, + { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, { "temperature" } }, + { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } }, + { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } }, + { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, { "scalar" } }, + { SENSOR_TYPE_ID_PEDOMETER_DETECTION, { "scalar" } }, + { SENSOR_TYPE_ID_PEDOMETER, { "step" } }, + { SENSOR_TYPE_ID_HEART_RATE, { "heartRate" } }, + { SENSOR_TYPE_ID_WEAR_DETECTION, { "value" } }, + { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } } +}; + +void EmitAsyncCallbackWork(AsyncCallbackInfo *asyncCallbackInfo) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + if (asyncCallbackInfo == nullptr) { + HiLog::Error(LABEL, "%{public}s asyncCallbackInfo is null!", __func__); + return; + } + napi_value resourceName; + if (napi_create_string_utf8(asyncCallbackInfo->env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName) != napi_ok) { + HiLog::Error(LABEL, "%{public}s create string utf8 failed", __func__); + return; + } + napi_create_async_work( + asyncCallbackInfo->env, nullptr, resourceName, + [](napi_env env, void* data) {}, + [](napi_env env, napi_status status, void* data) { + HiLog::Debug(LABEL, "%{public}s napi_create_async_work in", __func__); + AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + napi_value callback; + napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback); + napi_value callResult = nullptr; + napi_value result[2] = {0}; + if (asyncCallbackInfo->status < 0) { + HiLog::Debug(LABEL, "%{public}s napi_create_async_work < 0 in", __func__); + 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[0]); + napi_get_undefined(env, &result[1]); + } else if (asyncCallbackInfo->status == 0) { + napi_create_object(env, &result[1]); + napi_value message = nullptr; + napi_create_int32(env, asyncCallbackInfo->status, &message); + napi_set_named_property(env, result[1], "code", message); + napi_get_undefined(env, &result[0]); + } else { + int32_t sensorTypeId = asyncCallbackInfo->sensorTypeId; + if (g_sensorAttributeList.count(sensorTypeId) == 0) { + HiLog::Error(LABEL, "%{public}s count of sensorTypeId is zero", __func__); + return; + } + std::vector sensorAttribute = g_sensorAttributeList[sensorTypeId]; + float *sensorData = asyncCallbackInfo->sensorData; + napi_create_object(env, &result[1]); + for (size_t i = 0; i < sensorAttribute.size(); i++) { + napi_value message = nullptr; + double a = *sensorData; + napi_create_double(env, a, &message); + napi_set_named_property(env, result[1], sensorAttribute[i].c_str(), message); + } + napi_get_undefined(env, &result[0]); + } + napi_call_function(env, nullptr, callback, 2, result, &callResult); + if (asyncCallbackInfo->status != 1) { + HiLog::Debug(LABEL, "%{public}s not a continuous callback, need to release asyncCallbackInfo", __func__); + napi_delete_reference(env, asyncCallbackInfo->callback[0]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + HiLog::Debug(LABEL, "%{public}s napi_create_async_work left", __func__); + free(result); + }, + asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork); + HiLog::Debug(LABEL, "%{public}s end", __func__); +} diff --git a/interfaces/plugin/test/unittest/BUILD.gn b/interfaces/plugin/test/unittest/BUILD.gn new file mode 100755 index 00000000..8b0d776c --- /dev/null +++ b/interfaces/plugin/test/unittest/BUILD.gn @@ -0,0 +1,61 @@ +# 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") +import("//build/test.gni") + +module_output_path = "sensors/sensors_sensor/interfaces" +ohos_unittest("SensorJsTest") { + module_out_path = module_output_path + + include_dirs = [ + "//third_party/node/src", + "//native_engine", + "//base/sensors/sensors_sensor/interfaces/native/include", + "//base/sensors/sensors_sensor/interfaces/plugin/include", + "//utils/native/base/include", + "./include", + "//third_party/libuv/include", + "//foundation/ace/napi", + "//foundation/ace/napi/interfaces/kits", + "//foundation/ace/napi/native_engine", + "//foundation/ace/napi/native_engine/impl/quickjs", + ] + defines = [ + "APP_LOG_TAG = \"sensroJs\"", + "LOG_DOMAIN = 0xD002700", + ] + sources = [ + "sensor_js_test.cpp", + ] + deps = [ + "//foundation/ace/napi:ace_napi", + "//base/sensors/sensors_sensor/interfaces/native:sensor_interface_native", + "//utils/native/base:utils", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/googletest:gtest", + "//third_party/googletest:gtest_main", + "//third_party/libuv:uv_static", + "//third_party/quickjs:qjs", + "//base/sensors/sensors_sensor/interfaces/plugin:sensor" + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + relative_install_dir = "module" + part_name = "sensors_sensor" + subsystem_name = "sensors" +} +group("unittest") { + testonly = true + deps = [ ":SensorJsTest" ] +} \ No newline at end of file diff --git a/interfaces/plugin/test/unittest/sensor_js_test.cpp b/interfaces/plugin/test/unittest/sensor_js_test.cpp new file mode 100755 index 00000000..6d00afd0 --- /dev/null +++ b/interfaces/plugin/test/unittest/sensor_js_test.cpp @@ -0,0 +1,595 @@ +/* + * 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 "napi/native_api.h" +#include "napi/native_node_api.h" +#include "sensor_napi_utils.h" +#include "sensor_agent.h" +#include "native_engine.h" +#include "quickjs_native_engine.h" +#include "hilog/log.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; +static NativeEngine* g_nativeEngine = nullptr; +namespace { + using namespace OHOS::HiviewDFX; + static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "SensorJsTest"}; +} + +class SensorJsTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + SensorJsTest(); + virtual ~SensorJsTest(); +protected: + NativeEngine* engine_; +}; + +void SensorJsTest::SetUp() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); +} + +void SensorJsTest::TearDown() +{ + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +SensorJsTest::SensorJsTest() +{ + JSRuntime* rt = JS_NewRuntime(); + if (rt == nullptr) { + return ; + } + + JSContext* ctx = JS_NewContext(rt); + if (ctx == nullptr) { + return ; + } + + js_std_add_helpers(ctx, 0, nullptr); + g_nativeEngine = new QuickJSNativeEngine(rt, ctx, 0); // default instance id 0 + engine_ = g_nativeEngine; + +} + +SensorJsTest::~SensorJsTest() { + delete g_nativeEngine; + g_nativeEngine = nullptr; +} + +/* + * @tc.name: IsMatchType_001 + * @tc.desc: Match napi_number + * @tc.type: FUNC + * @tc.require:SR000G54IU + */ +HWTEST_F(SensorJsTest, IsMatchType_001, TestSize.Level1) +{ + napi_env env = (napi_env)engine_; + uint32_t cppValue = UINT32_MAX; + napi_value napiValue = nullptr; + napi_create_uint32(env, cppValue, &napiValue); + + bool ret = IsMatchType(napiValue, napi_number, env); + ASSERT_EQ(ret, true); +} + +/* + * @tc.name: IsMatchType_002 + * @tc.desc: Match napi_string + * @tc.type: FUNC + * @tc.require:AR000G54IV + */ +HWTEST_F(SensorJsTest, IsMatchType_002, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + const char cppValue[] = "中文,English,123456,!@#"; + size_t cppValueStrLength = strlen(cppValue); + napi_value napiValue = nullptr; + napi_create_string_utf8(env, cppValue, cppValueStrLength, &napiValue); + + // call function + bool ret = IsMatchType(napiValue, napi_string, env); + ASSERT_EQ(ret, true); +} + +/* + * @tc.name: IsMatchType_003 + * @tc.desc: Match napi_symbol + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, IsMatchType_003, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + const char testStr[] = "testSymbol"; + napi_value result = nullptr; + napi_create_string_latin1(env, testStr, strlen(testStr), &result); + napi_value symbolVal = nullptr; + napi_create_symbol(env, result, &symbolVal); + + // call function + bool ret = IsMatchType(symbolVal, napi_symbol, env); + ASSERT_EQ(ret, true); +} + +/* + * @tc.name: IsMatchType_004 + * @tc.desc: Match napi_function + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, IsMatchType_004, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + const char* tetScriptStr = "new Date();"; + napi_value testScript = nullptr; + napi_create_string_utf8(env, tetScriptStr, strlen(tetScriptStr), &testScript); + napi_value date = nullptr; + napi_run_script(env, testScript, &date); + napi_value getTimeFunc = nullptr; + napi_get_named_property(env, date, "getTime", &getTimeFunc); + + // call function + bool ret = IsMatchType(getTimeFunc, napi_function, env); + ASSERT_EQ(ret, true); +} + +/* + * @tc.name: IsMatchType_005 + * @tc.desc: Match napi_boolean + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, IsMatchType_005, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + napi_value result = nullptr; + napi_get_boolean(env, true, &result); + + // call function + bool ret = IsMatchType(result, napi_boolean, env); + ASSERT_EQ(ret, true); +} + +/* + * @tc.name: GetNapiInt32_001 + * @tc.desc: change int32_t[INT32_MAX] to napi_value + * @tc.type: FUNC + * @tc.require: SR000FU58Q + */ +HWTEST_F(SensorJsTest, GetNapiInt32_001, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = INT32_MAX; + + // call function + napi_value value = GetNapiInt32(number, env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: GetNapiInt32_002 + * @tc.desc: change int32_t[INT32_MIN] to napi_value + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, GetNapiInt32_002, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = INT32_MIN; + + // call function + napi_value value = GetNapiInt32(number, env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: GetNapiInt32_003 + * @tc.desc: change int32_t[true] to napi_value + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, GetNapiInt32_003, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)true; + + // call function + napi_value value = GetNapiInt32(number, env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: GetNapiInt32_004 + * @tc.desc: change int32_t[true] to napi_value + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, GetNapiInt32_004, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)false; + + // call function + napi_value value = GetNapiInt32(number, env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: GetNapiInt32_005 + * @tc.desc: change int32_t[char] to napi_value + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, GetNapiInt32_005, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)'a'; + + // call function + napi_value value = GetNapiInt32(number, env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: NapiGetNamedProperty_001 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, NapiGetNamedProperty_001, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + const char* tetScriptStr = "new Date();"; + napi_value testScript = nullptr; + napi_create_string_utf8(env, tetScriptStr, strlen(tetScriptStr), &testScript); + napi_value date = nullptr; + napi_run_script(env, testScript, &date); + + // call function + napi_value value = NapiGetNamedProperty(date, "getTime", env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_function); +} + +/* + * @tc.name: NapiGetNamedProperty_002 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, NapiGetNamedProperty_002, TestSize.Level1) +{ + // 定义变量 赋值 + napi_env env = (napi_env)engine_; + int32_t status=101; + napi_value message; + napi_create_int32(env, status, &message); + + // 定义变量为对象 + napi_value result; + napi_create_object(env, &result); + + // 赋值给object + napi_set_named_property(env, result, "code", message); + + napi_value value = NapiGetNamedProperty(result, "code", env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_number); +} + +/* + * @tc.name: NapiGetNamedProperty_003 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000FU73V + */ +HWTEST_F(SensorJsTest, NapiGetNamedProperty_003, TestSize.Level1) +{ + // 定义变量 赋值 + napi_env env = (napi_env)engine_; + const char status[] = "type001"; + napi_value message; + napi_create_string_utf8(env, status, strlen(status), &message); + + // 定义变量为对象 + napi_value result; + napi_create_object(env, &result); + + // 赋值给object + napi_set_named_property(env, result, "code", message); + + napi_value value = NapiGetNamedProperty(result, "code", env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_string); +} + +/* + * @tc.name: NapiGetNamedProperty_004 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, NapiGetNamedProperty_004, TestSize.Level1) +{ + // 定义变量 赋值 + napi_env env = (napi_env)engine_; + napi_value message; + napi_get_boolean(env, true, &message); + + // 定义变量为对象 + napi_value result; + napi_create_object(env, &result); + + // 赋值给object + napi_set_named_property(env, result, "code", message); + + + napi_value value = NapiGetNamedProperty(result, "code", env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_boolean); +} + +/* + * @tc.name: NapiGetNamedProperty_005 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, NapiGetNamedProperty_005, TestSize.Level1) +{ + // 定义变量 赋值 + napi_env env = (napi_env)engine_; + const char testStr[] = "testSymbol"; + napi_value resultSymbol = nullptr; + napi_create_string_latin1(env, testStr, strlen(testStr), &resultSymbol); + napi_value message = nullptr; + napi_create_symbol(env, resultSymbol, &message); + + // 定义变量为对象 + napi_value result; + napi_create_object(env, &result); + + // 赋值给object + napi_set_named_property(env, result, "code", message); + + napi_value value = NapiGetNamedProperty(result, "code", env); + napi_valuetype ret; + napi_typeof(env, value, &ret); + ASSERT_EQ(ret, napi_symbol); +} +/* + * @tc.name: GetCppInt32_001 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt32_001, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = INT32_MAX; + napi_value value; + napi_create_int32(env, number, &value); + + // call function + int32_t ret = GetCppInt32(value, env); + ASSERT_EQ(ret, (int32_t)INT32_MAX); +} + +/* + * @tc.name: GetCppInt32_002 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt32_002, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = INT32_MIN; + napi_value value; + napi_create_int32(env, number, &value); + + // call function + int32_t ret = GetCppInt32(value, env); + ASSERT_EQ(ret, (int32_t)INT32_MIN); +} + +/* + * @tc.name: GetCppInt32_003 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt32_003, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)true; + napi_value value; + napi_create_int32(env, number, &value); + + // call function + int32_t ret = GetCppInt32(value, env); + ASSERT_EQ(ret, (int32_t)true); +} + +/* + * @tc.name: GetCppInt32_004 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt32_004, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)false; + napi_value value; + napi_create_int32(env, number, &value); + + // call function + int32_t ret = GetCppInt32(value, env); + ASSERT_EQ(ret, (int32_t)false); +} +/* + * @tc.name: GetCppInt32_005 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt32_005, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int32_t number = (int32_t)'b'; + napi_value value; + napi_create_int32(env, number, &value); + + // call function + int32_t ret = GetCppInt32(value, env); + ASSERT_EQ(ret, (int32_t)'b'); +} + +/* + * @tc.name: GetCppInt64_001 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt64_001, TestSize.Level1) +{ + // Construction parameters + int64_t tmpInt64Max = 9007199254740991;//9223372036854775807;9007199254740992 + napi_env env = (napi_env)engine_; + int64_t number = tmpInt64Max;//(int64_t)INT64_MAX; + napi_value value; + napi_create_int64(env, number, &value); + + // call function + int64_t ret = GetCppInt64(value, env); + ASSERT_EQ(ret, tmpInt64Max); +} + +/* + * @tc.name: GetCppInt64_002 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt64_002, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int64_t number = (int64_t)INT64_MIN; + napi_value value; + napi_create_int64(env, number, &value); + + // call function + int64_t ret = GetCppInt64(value, env); + ASSERT_EQ(ret, (int64_t)INT64_MIN); +} + +/* + * @tc.name: GetCppInt64_003 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt64_003, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int64_t number = (int64_t)true; + napi_value value; + napi_create_int64(env, number, &value); + + + // call function + int64_t ret = GetCppInt64(value, env); + ASSERT_EQ(ret, (int64_t)true); +} + +/* + * @tc.name: GetCppInt64_004 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt64_004, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int64_t number = (int64_t)false; + napi_value value; + napi_create_int64(env, number, &value); + + // call function + int64_t ret = GetCppInt64(value, env); + ASSERT_EQ(ret, (int64_t)false); +} +/* + * @tc.name: GetCppInt64_005 + * @tc.desc: Parse function in Json + * @tc.type: FUNC + * @tc.require: AR000G54IV + */ +HWTEST_F(SensorJsTest, GetCppInt64_005, TestSize.Level1) +{ + // Construction parameters + napi_env env = (napi_env)engine_; + int64_t number = (int64_t)'c'; + napi_value value; + napi_create_int64(env, number, &value); + + // call function + int64_t ret = GetCppInt64(value, env); + ASSERT_EQ(ret, (int64_t)'c'); +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/ohos.build b/ohos.build new file mode 100755 index 00000000..3ade0df5 --- /dev/null +++ b/ohos.build @@ -0,0 +1,39 @@ +{ + "subsystem": "sensors", + "parts": { + "sensors_sensor": { + "variants": [ + "phone", + "ivi", + "wearable", + "intellitv" + ], + "module_list": [ + "//base/sensors/sensors_sensor/interfaces/native:sensor_ndk_target", + "//base/sensors/sensors_sensor/interfaces/plugin:sensor_js_target", + "//base/sensors/sensors_sensor/frameworks/native/sensor:sensor_native_target", + "//base/sensors/sensors_sensor/services/sensor:sensor_service_target", + "//base/sensors/sensors_sensor/utils:sensor_utils_target", + "//base/sensors/sensors_sensor/sa_profile:sensors_sa_profiles" + ], + "inner_kits": [ + { + "header": { + "header_files": [ + "sensor_agent_type.h", + "sensor_agent.h" + ], + "header_base": "//base/sensors/sensors_sensor/interfaces/native/include" + }, + "name": "//base/sensors/sensors_sensor/interfaces/native:sensor_interface_native" + } + ], + "test_list": [ + "//base/sensors/sensors_sensor/frameworks/native/sensor/test:unittest", + "//base/sensors/sensors_sensor/interfaces/native/test:unittest", + "//base/sensors/sensors_sensor/services/sensor/test:unittest", + "//base/sensors/sensors_sensor/interfaces/plugin/test/unittest:unittest" + ] + } + } +} diff --git a/sa_profile/3601.xml b/sa_profile/3601.xml new file mode 100755 index 00000000..580af5ea --- /dev/null +++ b/sa_profile/3601.xml @@ -0,0 +1,24 @@ + + + + hsensors + + 3601 + libsensor_service.z.so + true + false + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100755 index 00000000..1df10558 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,19 @@ +# 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/sa_profile/sa_profile.gni") + +ohos_sa_profile("sensors_sa_profiles") { + sources = [ "3601.xml" ] + part_name = "sensors_sensor" +} diff --git a/utils/BUILD.gn b/utils/BUILD.gn new file mode 100755 index 00000000..cbdacd98 --- /dev/null +++ b/utils/BUILD.gn @@ -0,0 +1,59 @@ +# 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" +ohos_shared_library("libsensor_utils") { + sources = [ + "src/dmd_report.cpp", + "src/miscdevice_common.cpp", + "src/permission_util.cpp", + "src/report_data_callback.cpp", + "src/sensor.cpp", + "src/sensor_basic_data_channel.cpp", + "src/sensor_basic_info.cpp", + "src/sensor_channel_info.cpp", + ] + + include_dirs = [ + "include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//drivers/peripheral/sensor/interfaces/include", + "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include/message_parcel.h", + ] + deps = [ + "//utils/native/base:utils", + "//drivers/peripheral/sensor/hal:hdi_sensor", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + ] + + external_deps = [ + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:appexecfwk_core", + "hiviewdfx_hilog_native:libhilog", + "hisysevent_native:libhisysevent", + "aafwk_standard:base", + "aafwk_standard:intent", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + part_name = "sensors_sensor" + subsystem_name = "sensors" +} + +group("sensor_utils_target") { + deps = [ ":libsensor_utils" ] +} diff --git a/utils/include/app_thread_info.h b/utils/include/app_thread_info.h new file mode 100755 index 00000000..2bf75c1f --- /dev/null +++ b/utils/include/app_thread_info.h @@ -0,0 +1,29 @@ +/* + * 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 APP_THREAD_INFO_H +#define APP_THREAD_INFO_H + +namespace OHOS { +namespace Sensors { +struct AppThreadInfo { + int32_t pid; + int32_t uid; + AppThreadInfo() : pid(0), uid(0) {}; + AppThreadInfo(int32_t pid, int32_t uid) : pid(pid), uid(uid) {}; +}; +} // namespace Sensors +} // namespace OHOS +#endif // APP_THREAD_INFO_H diff --git a/utils/include/death_recipient_template.h b/utils/include/death_recipient_template.h new file mode 100755 index 00000000..d3a13a7a --- /dev/null +++ b/utils/include/death_recipient_template.h @@ -0,0 +1,38 @@ +/* + * 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 DEATH_RECIPIENT_TEMPLATE_H +#define DEATH_RECIPIENT_TEMPLATE_H + +#include "iremote_object.h" + +namespace OHOS { +namespace Sensors { +template +class DeathRecipientTemplate : public IRemoteObject::DeathRecipient { +public: + explicit DeathRecipientTemplate(T &privateData) : privateData_(privateData){}; + virtual ~DeathRecipientTemplate() = default; + virtual void OnRemoteDied(const wptr &object) + { + privateData_.ProcessDeathObserver(object); + }; + +private: + T &privateData_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // DEATH_RECIPIENT_TEMPLATE_H diff --git a/utils/include/dmd_report.h b/utils/include/dmd_report.h new file mode 100755 index 00000000..a47975c4 --- /dev/null +++ b/utils/include/dmd_report.h @@ -0,0 +1,52 @@ +/* + * 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 DMD_REPORT_H +#define DMD_REPORT_H + +#include +#include +#include + +namespace OHOS { +namespace Sensors { +enum SensorEventId { + JNI_ENV_VAR_EXCEPTION = 951000106, + CLASS_NOT_FOUND = 951000107, + NATIVE_METHOD_REGISTER_EXCEPTION = 951000108, + JAVA_VM_THREAD_ATTACH_EXCEPTION = 951000109, + SENSOR_SERVICE_EXCEPTION = 951000110, + MISC_SERVICE_EXCEPTION = 951000111, + SENSOR_SERVICE_IPC_EXCEPTION = 951000112, + MISC_SERVICE_IPC_EXCEPTION = 951000113, + SENSOR_HIDL_SERVICE_EXCEPTION = 951000114, + LIGHT_HIDL_SERVICE_EXCEPTION = 951000115, + VIBRATOR_HIDL_SERVICE_EXCEPTION = 951000116, + SENSOR_DATA_CHANNEL_EXCEPTION = 951000117, +}; + +class DmdReport { +public: + DmdReport() = default; + virtual ~DmdReport() = default; + static void ReportException(int32_t eventId, const std::string &interfaceName, int32_t error); + +private: + static std::mutex eventMutex_; + static std::map eventMap_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // DMD_REPORT_H diff --git a/utils/include/miscdevice_common.h b/utils/include/miscdevice_common.h new file mode 100755 index 00000000..9932d560 --- /dev/null +++ b/utils/include/miscdevice_common.h @@ -0,0 +1,46 @@ +/* + * 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 MISCDEVICE_COMMON_H +#define MISCDEVICE_COMMON_H + +#include +#include + +namespace OHOS { +namespace Sensors { +// These LightId correspand to logical lights +enum LightId { + LIGHT_ID_LED = 0, + LIGHT_ID_KEYBOARD, + LIGHT_ID_BUTTONS, + LIGHT_ID_BELT, + + UNKNOWN, +}; + +// MISC device support id +enum class MiscdeviceDeviceId { LED = 0, VIBRATOR, UNKNOWN }; + +class MiscdeviceCommon { +public: + MiscdeviceCommon() = default; + ~MiscdeviceCommon() = default; + static bool CheckCustomVibratorEffect(const std::vector &timing, const std::vector &intensity, + int32_t periodCount); +}; +} // namespace Sensors +} // namespace OHOS +#endif // MISCDEVICE_COMMON_H diff --git a/utils/include/permission_util.h b/utils/include/permission_util.h new file mode 100755 index 00000000..30a6da77 --- /dev/null +++ b/utils/include/permission_util.h @@ -0,0 +1,57 @@ +/* + * 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 PERMISSION_UTIL_H +#define PERMISSION_UTIL_H + +#include +#include +#include +#include + +#include "app_thread_info.h" +#include "refbase.h" +#include "singleton.h" + +namespace OHOS { +namespace Sensors { +// using namespace OHOS::AppExecFwk; + +// Callback registered with BMS to listen APP permission changes. +// class PermissionChangedCallback : public OnPermissionChangedHost { +// public: + +// private: + +class PermissionUtil : public Singleton { +public: + PermissionUtil() = default; + virtual ~PermissionUtil(); + /* check local caller's permission by permission name */ + bool CheckCallingPermission(const std::string &permissionName); + bool RegistPermissionChanged(const AppThreadInfo &appThreadInfo); + void UnregistPermissionChanged(const AppThreadInfo &appThreadInfo); + void UpdatePermissionStatus(int32_t uid, const std::string &permissionName, bool permissionStatus); + +private: + bool IsPermissionRegisted(int32_t uid); + std::mutex permissionStatusMutex_; + std::unordered_map> appPermissionStatus_; + + static std::unordered_map sensorPermissions_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // PERMISSION_UTIL_H diff --git a/utils/include/report_data_callback.h b/utils/include/report_data_callback.h new file mode 100755 index 00000000..dc2ca69c --- /dev/null +++ b/utils/include/report_data_callback.h @@ -0,0 +1,48 @@ +/* + * 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 REPORT_DATA_CALLBACK_H +#define REPORT_DATA_CALLBACK_H + +#include + +#include "refbase.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +constexpr int32_t CIRCULAR_BUF_LEN = 1024; +constexpr int32_t SENSOR_DATA_LENGHT = 1024; + +struct CircularEventBuf { + struct SensorEvent *circularBuf; + int32_t readPosition; + int32_t writePosition; + int32_t eventNum; +}; + +class ReportDataCallback : public RefBase { +public: + ReportDataCallback(); + ~ReportDataCallback(); + int32_t ZReportDataCallback(const struct SensorEvent *event, sptr cb); + struct CircularEventBuf &GetEventData(); + struct CircularEventBuf eventsBuf_; +}; + +using ZReportDataCb = int32_t (ReportDataCallback::*)(const struct SensorEvent *event, sptr cb); +} // namespace Sensors +} // namespace OHOS +#endif // REPORT_DATA_CALLBACK_H diff --git a/utils/include/sensor.h b/utils/include/sensor.h new file mode 100755 index 00000000..5e86c073 --- /dev/null +++ b/utils/include/sensor.h @@ -0,0 +1,71 @@ +/* + * 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 SENSOR_H +#define SENSOR_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace Sensors { +class Sensor : public Parcelable { +public: + Sensor(); + virtual ~Sensor() = default; + uint32_t GetSensorId() const; + void SetSensorId(uint32_t sensorId); + std::string GetName() const; + void SetName(const std::string &name); + std::string GetVendor() const; + void SetVendor(const std::string &vendor); + uint32_t GetVersion() const; + void SetVersion(uint32_t version); + float GetMaxRange() const; + void SetMaxRange(float maxRange); + float GetResolution() const; + void SetResolution(float resolution); + uint32_t GetFlags() const; + void SetFlags(uint32_t flags); + int32_t GetFifoMaxEventCount() const; + void SetFifoMaxEventCount(int32_t fifoMaxEventCount); + int64_t GetMinSamplePeriodNs() const; + void SetMinSamplePeriodNs(int64_t minSamplePeriodNs); + int64_t GetMaxSamplePeriodNs() const; + void SetMaxSamplePeriodNs(int64_t maxSamplePeriodNs); + std::vector GetReserved() const; + void SetReserved(const std::vector &reserved); + bool ReadFromParcel(Parcel &parcel); + static std::unique_ptr Unmarshalling(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + +private: + uint32_t sensorId_; + std::string name_; + std::string vendor_; + uint32_t version_; + float maxRange_; + float resolution_; + uint32_t flags_; + int32_t fifoMaxEventCount_; + int64_t minSamplePeriodNs_; + int64_t maxSamplePeriodNs_; + std::vector reserved_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_H diff --git a/utils/include/sensor_basic_data_channel.h b/utils/include/sensor_basic_data_channel.h new file mode 100755 index 00000000..52975751 --- /dev/null +++ b/utils/include/sensor_basic_data_channel.h @@ -0,0 +1,64 @@ +/* + * 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 SENSOR_BASIC_DATA_CHANNEL_H +#define SENSOR_BASIC_DATA_CHANNEL_H + +#include +#include + +#include "message_parcel.h" +#include "refbase.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +constexpr int32_t INVALID_FD = -1; +struct TransferSensorEvents { + uint32_t sensorTypeId; /**< Sensor type ID */ + int32_t version; /**< Sensor algorithm version */ + int64_t timestamp; /**< Time when sensor data was reported */ + int32_t option; /**< Sensor data options, including the measurement range and accuracy */ + int32_t mode; /**< Sensor data reporting mode (described in {@link SensorMode}) */ + uint32_t dataLen; /**< Sensor data length */ + uint8_t data[16]; +}; +class SensorBasicDataChannel : public RefBase { +public: + SensorBasicDataChannel(); + virtual ~SensorBasicDataChannel(); + int32_t CreateSensorBasicChannel(size_t sendSize, size_t receiveSize); + int32_t CreateSensorBasicChannel(MessageParcel &data); + int32_t DestroySensorBasicChannel(); + int32_t GetSendDataFd() const; + int32_t GetReceiveDataFd() const; + int32_t SendToBinder(MessageParcel &data); + void CloseSendFd(); + int32_t SendData(const void *vaddr, size_t size); + int32_t ReceiveData(void *vaddr, size_t size); + bool GetSensorStatus() const; + void SetSensorStatus(bool isActive); + const std::unordered_map &GetDataCacheBuf() const; + +private: + int32_t sendFd_; + int32_t receiveFd_; + bool isActive_; + std::mutex statusLock_; + std::unordered_map dataCacheBuf_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_H diff --git a/utils/include/sensor_basic_info.h b/utils/include/sensor_basic_info.h new file mode 100755 index 00000000..aaaa29f9 --- /dev/null +++ b/utils/include/sensor_basic_info.h @@ -0,0 +1,47 @@ +/* + * 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 SENSOR_BASIC_INFO_H +#define SENSOR_BASIC_INFO_H + +#include + +namespace OHOS { +namespace Sensors { +enum SensorState { + SENSOR_DISABLED = 0, + SENSOR_ENABLED = 1, + SENSOR_UNKNOWN_STATE = 2, +}; + +class SensorBasicInfo { +public: + SensorBasicInfo(); + virtual ~SensorBasicInfo() = default; + int64_t GetSamplingPeriodNs() const; + void SetSamplingPeriodNs(int64_t samplingPeriodNs); + int64_t GetMaxReportDelayNs() const; + void SetMaxReportDelayNs(int64_t maxReportDelayNs); + SensorState GetSensorState() const; + void SetSensorState(SensorState sensorState); + +private: + int64_t samplingPeriodNs_; + int64_t maxReportDelayNs_; + SensorState sensorState_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_BASIC_INFO_H diff --git a/utils/include/sensor_catalog.h b/utils/include/sensor_catalog.h new file mode 100755 index 00000000..5856f6d5 --- /dev/null +++ b/utils/include/sensor_catalog.h @@ -0,0 +1,91 @@ +/* + * 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 SENSOR_CATALOG_H +#define SENSOR_CATALOG_H + +namespace OHOS { +namespace Sensors { +enum SensorGroup { + DEVICE_MOTION = 0, + ENVIRONMENT = 1, + ORIENTATION = 2, + LIGHT = 3, + OTHER = 4, + BODY = 5, +}; + +enum GroupMotion { + SENSOR_TYPE_ACCELEROMETER = 0, + SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 1, + SENSOR_TYPE_LINEAR_ACCELERATION = 2, + SENSOR_TYPE_GRAVITY = 3, + SENSOR_TYPE_GYROSCOPE = 4, + SENSOR_TYPE_GYROSCOPE_UNCALIBRATED = 5, + SENSOR_TYPE_SIGNIFICANT_MOTION = 6, + SENSOR_TYPE_DROP_DETECTION = 7, + SENSOR_TYPE_STEP_DETECTOR = 8, + SENSOR_TYPE_STEP_COUNTER = 9, +}; + +enum GroupEnvironment { + SENSOR_TYPE_AMBIENT_TEMPERATURE = 0, + SENSOR_TYPE_MAGNETIC_FIELD = 1, + SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED = 2, + SENSOR_TYPE_HUMIDITY = 3, + SENSOR_TYPE_BAROMETER = 4, + SENSOR_TYPE_SAR = 5, +}; + +enum GroupOrientation { + SENSOR_TYPE_6DOF_ATTITUDE = 0, + SENSOR_TYPE_SCREEN_ROTATION = 1, + SENSOR_TYPE_DEVICE_ORIENTATION = 2, + SENSOR_TYPE_ORIENTATION = 3, + SENSOR_TYPE_ROTATION_VECTOR = 4, + SENSOR_TYPE_GAME_ROTATION_VECTOR = 5, + SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 6, +}; + +enum GroupLight { + SENSOR_TYPE_PROXIMITY = 0, + SENSOR_TYPE_TOF = 1, + SENSOR_TYPE_AMBIENT_LIGHT = 2, + SENSOR_TYPE_COLOR_TEMPERATURE = 3, + SENSOR_TYPE_COLOR_RGB = 4, + SENSOR_TYPE_COLOR_XYZ = 5, +}; + +enum GroupOther { + SENSOR_TYPE_HALL = 0, + SENSOR_TYPE_GRIP_DETECTOR = 1, + SENSOR_TYPE_MAGNET_BRACKET = 2, + SENSOR_TYPE_PRESSURE_DETECTOR = 3, + SENSOR_TYPE_FLUSH = 4, +}; + +enum GroupBody { + SENSOR_TYPE_HEART_RATE_DETECTOR = 0, + SENSOR_TYPE_WEAR_DETECTOR = 1, +}; + +struct SensorCombination { + SensorGroup sensorCatagory; + uint8_t sensorType; + uint8_t sensorIndex; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_CATALOG_H diff --git a/utils/include/sensor_channel_info.h b/utils/include/sensor_channel_info.h new file mode 100755 index 00000000..30084350 --- /dev/null +++ b/utils/include/sensor_channel_info.h @@ -0,0 +1,52 @@ +/* + * 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 SENSOR_CHANNEL_INFO_H +#define SENSOR_CHANNEL_INFO_H + +#include +#include +#include + +namespace OHOS { +namespace Sensors { +class SensorChannelInfo { +public: + SensorChannelInfo(); + virtual ~SensorChannelInfo() = default; + int32_t GetUid() const; + void SetUid(int32_t uid); + std::string GetPackageName() const; + void SetPackageName(const std::string &packageName); + uint32_t GetSensorId() const; + void SetSensorId(uint32_t sensorId); + int64_t GetSamplingPeriodNs() const; + void SetSamplingPeriodNs(int64_t samplingPeriodNs); + int32_t GetFifoCount() const; + void SetFifoCount(int32_t fifoCount); + std::vector GetCmdType() const; + void SetCmdType(const std::vector &cmdType); + +private: + int32_t uid_; + std::string packageName_; + uint32_t sensorId_; + int64_t samplingPeriodNs_; + uint32_t fifoCount_; + std::vector cmdType_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_CHANNEL_INFO_H diff --git a/utils/include/sensor_data_event.h b/utils/include/sensor_data_event.h new file mode 100755 index 00000000..e0e3a349 --- /dev/null +++ b/utils/include/sensor_data_event.h @@ -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. + */ + +#ifndef SENSOR_DATA_EVENT_H +#define SENSOR_DATA_EVENT_H + +namespace OHOS { +namespace Sensors { +constexpr int32_t RESERVED_DATA_LEN = 3; +constexpr int32_t EXTRA_INFO_DATA_LEN = 14; +constexpr int32_t DEFAULT_SENSOR_DATA_DIMS = 16; + +enum { + WAKE_UP_SENSOR = 1u, + CONTINUOUS_SENSOR = 0u, + ON_CHANGE_SENSOR = 2u, + ONE_SHOT_SENSOR = 4u, +}; + +struct SensorData { + float data[DEFAULT_SENSOR_DATA_DIMS]; + uint32_t reserved[RESERVED_DATA_LEN]; +}; + +struct ExtraInfo { + int32_t sensorId; + int32_t type; // type of payload data, see ExtraInfo + int32_t serial; // sequence number of this frame for this type + union { + // for each frame, a single data type, either int32_t or float, should be used. + int32_t data_int32[EXTRA_INFO_DATA_LEN]; + float data_float[EXTRA_INFO_DATA_LEN]; + }; +}; + +struct ExtraSensorInfo { + ExtraInfo additional_info; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_DATA_EVENT_H diff --git a/utils/include/sensors_errors.h b/utils/include/sensors_errors.h new file mode 100755 index 00000000..a05258d2 --- /dev/null +++ b/utils/include/sensors_errors.h @@ -0,0 +1,127 @@ +/* + * 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 SENSORS_ERRORS_H +#define SENSORS_ERRORS_H + +#include + +namespace OHOS { +namespace Sensors { +enum { + MODULE_COMMON = 0x00, + MODULE_SENSORS_ADAPTER = 0x01, + MODULE_SENSOR_SERVICE = 0x02, + MODULE_SENSORS_UTILS = 0x03, + MODULE_MISCDEVICE_SERVICE = 0x04, + MODULE_SENSORS_NATIVE = 0X05, +}; + +// Error code for common +constexpr ErrCode COMMON_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_COMMON); + +enum { + ERROR = -1, + SUCCESS = 0, + COMMON_ERR = COMMON_ERR_OFFSET, +}; + +// Error code for adapter +constexpr ErrCode ADAPTER_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_ADAPTER); + +enum { + ADAPTER_ERR = ADAPTER_ERR_OFFSET, + ADAPTER_ENABLE_SENSOR_ERR = ADAPTER_ERR_OFFSET + 1, + ADAPTER_DISABLE_SENSOR_ERR = ADAPTER_ENABLE_SENSOR_ERR + 1, + ADAPTER_RUN_COMMAND_ERR = ADAPTER_DISABLE_SENSOR_ERR + 1, + ADAPTER_SET_SENSOR_CONFIG_ERR = ADAPTER_RUN_COMMAND_ERR + 1, + ADAPTER_NOT_SUPPORT_CMD_ERR = ADAPTER_SET_SENSOR_CONFIG_ERR + 1, +}; + +// Error code for sensor service +constexpr ErrCode SENSOR_SERVICE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSOR_SERVICE); + +enum { + SENSOR_SERVICE_ERR = SENSOR_SERVICE_ERR_OFFSET, + CMD_TYPE_ERR = SENSOR_SERVICE_ERR + 1, + SENSOR_DEVICE_INIT_ERR = CMD_TYPE_ERR + 1, + CONNECT_SENSOR_HIDL_ERR = SENSOR_DEVICE_INIT_ERR + 1, + SET_SENSOR_CONFIG_ERR = CONNECT_SENSOR_HIDL_ERR + 1, + ENABLE_SENSOR_ERR = SET_SENSOR_CONFIG_ERR + 1, + DISABLE_SENSOR_ERR = ENABLE_SENSOR_ERR + 1, + RUN_COMMAND_ERR = DISABLE_SENSOR_ERR + 1, + GET_SENSOR_LIST_ERR = RUN_COMMAND_ERR + 1, + SENSOR_ENABLED_ERR = GET_SENSOR_LIST_ERR + 1, + UPDATE_SENSOR_CHANNEL_ERR = SENSOR_ENABLED_ERR + 1, + CLEAR_SENSOR_CHANNEL_ERR = UPDATE_SENSOR_CHANNEL_ERR + 1, + CLEAR_SENSOR_INFO_ERR = CLEAR_SENSOR_CHANNEL_ERR + 1, + UPDATE_SENSOR_INFO_ERR = CLEAR_SENSOR_INFO_ERR + 1, + CLIENT_PID_INVALID_ERR = UPDATE_SENSOR_INFO_ERR + 1, + DESTROY_SENSOR_CHANNEL_ERR = CLIENT_PID_INVALID_ERR + 1, + UPDATE_UID_ERR = DESTROY_SENSOR_CHANNEL_ERR + 1, + INVALID_POINTER = UPDATE_UID_ERR + 1, + NO_EVENT = INVALID_POINTER + 1, + COPY_ERR = NO_EVENT + 1, + REGIST_PERMISSION_CHANGED_ERR = COPY_ERR + 1, + DUMP_PARAM_ERR = REGIST_PERMISSION_CHANGED_ERR + 1, + WRITE_MSG_ERR = DUMP_PARAM_ERR + 1, +}; + +// Error code for miscdevice service +constexpr ErrCode MISCDEVICE_SERVICE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_MISCDEVICE_SERVICE); + +enum { + LIGHT_HIDL_CONNECT_ERR = MISCDEVICE_SERVICE_ERR_OFFSET, + LIGHT_ID_NOT_SUPPORT = LIGHT_HIDL_CONNECT_ERR + 1, + LIGHT_ERR = LIGHT_ID_NOT_SUPPORT + 1, + LIGHT_PLAY_EFFECT_ERROR = LIGHT_ERR + 1, + LIGHT_STOP_EFFECT_ERROR = LIGHT_PLAY_EFFECT_ERROR + 1, + LIGHT_END_ERROR = LIGHT_STOP_EFFECT_ERROR, + VIBRATOR_HIDL_CONNECT_ERR = LIGHT_END_ERROR + 1, + VIBRATOR_ON_ERR = VIBRATOR_HIDL_CONNECT_ERR + 1, + VIBRATOR_OFF_ERR = VIBRATOR_ON_ERR + 1, + VIBRATOR_PLAY_EFFECT_ERR = VIBRATOR_OFF_ERR + 1, + VIBRATOR_STOP_EFFECT_ERR = VIBRATOR_PLAY_EFFECT_ERR + 1, + VIBRATOR_SET_PARA_ERR = VIBRATOR_STOP_EFFECT_ERR + 1, +}; +// Error code for Sensor uitls +constexpr ErrCode SENSOR_UTILS_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_UTILS); +enum { + SENSOR_CHANNEL_SOCKET_CREATE_ERR = SENSOR_UTILS_ERR_OFFSET, + SENSOR_CHANNEL_SENDFD_ERR = SENSOR_CHANNEL_SOCKET_CREATE_ERR + 1, + SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR = SENSOR_CHANNEL_SENDFD_ERR + 1, + SENSOR_CHANNEL_DUP_ERR = SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR + 1, + SENSOR_CHANNEL_BASIC_CHANNEL_NOT_INIT = SENSOR_CHANNEL_DUP_ERR + 1, + SENSOR_CHANNEL_SEND_ADDR_ERR = SENSOR_CHANNEL_BASIC_CHANNEL_NOT_INIT + 1, + SENSOR_CHANNEL_SEND_DATA_ERR = SENSOR_CHANNEL_SEND_ADDR_ERR + 1, + SENSOR_CHANNEL_RECEIVE_DATA_ERR = SENSOR_CHANNEL_SEND_DATA_ERR + 1, + SENSOR_CHANNEL_RECEIVE_ADDR_ERR = SENSOR_CHANNEL_RECEIVE_DATA_ERR + 1, + SENSOR_CHANNEL_RESTORE_CB_ERR = SENSOR_CHANNEL_RECEIVE_ADDR_ERR + 1, + SENSOR_CHANNEL_RESTORE_FD_ERR = SENSOR_CHANNEL_RESTORE_CB_ERR + 1, + SENSOR_CHANNEL_RESTORE_THREAD_ERR = SENSOR_CHANNEL_RESTORE_FD_ERR + 1, +}; +// Error code for Sensor native +constexpr ErrCode SENSOR_NATIVE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_NATIVE); + +enum { + SENSOR_NATIVE_SAM_ERR = SENSOR_NATIVE_ERR_OFFSET, + SENSOR_NATIVE_GET_SERVICE_ERR = SENSOR_NATIVE_SAM_ERR + 1, + SENSOR_NATIVE_REGSITER_CB_ERR = SENSOR_NATIVE_GET_SERVICE_ERR + 1, + MISC_NATIVE_GET_SERVICE_ERR = SENSOR_NATIVE_REGSITER_CB_ERR + 1, + MISC_NATIVE_SAM_ERR = MISC_NATIVE_GET_SERVICE_ERR + 1, +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSORS_ERRORS_H diff --git a/utils/include/sensors_log_domain.h b/utils/include/sensors_log_domain.h new file mode 100755 index 00000000..d3a44713 --- /dev/null +++ b/utils/include/sensors_log_domain.h @@ -0,0 +1,34 @@ +/* + * 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 SENSORS_LOG_DOMAIN_H +#define SENSORS_LOG_DOMAIN_H + +#include "hilog/log.h" + +namespace OHOS { +namespace SensorsLogDomain { +constexpr uint32_t COMMON = 0xD002700; +constexpr uint32_t SENSOR_ADAPTER = 0xD002701; +constexpr uint32_t SENSOR_SERVICE = 0xD002702; +constexpr uint32_t SENSOR_UTILS = 0xD002703; +constexpr uint32_t SENSOR_TEST = 0xD002704; +constexpr uint32_t SENSOR_NATIVE = 0xD002705; +constexpr uint32_t SENSOR_JNI = 0xD002706; +constexpr uint32_t SENSORS_IMPLEMENT = 0xD002707; +constexpr uint32_t SENSORS_INTERFACE = 0xD002708; +} // namespace SensorsLogDomain +} // namespace OHOS +#endif // SENSORS_LOG_DOMAIN_H diff --git a/utils/src/dmd_report.cpp b/utils/src/dmd_report.cpp new file mode 100755 index 00000000..c30ca7e4 --- /dev/null +++ b/utils/src/dmd_report.cpp @@ -0,0 +1,102 @@ +/* + * 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 "dmd_report.h" + +#include "datetime_ex.h" +#include "hisysevent.h" + +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "DmdReport" }; +constexpr int32_t SECONDS_HALF_HOUR = 1800; +} // namespace + +std::map DmdReport::eventMap_ = { + { JNI_ENV_VAR_EXCEPTION, 0 }, + { CLASS_NOT_FOUND, 0 }, + { NATIVE_METHOD_REGISTER_EXCEPTION, 0 }, + { JAVA_VM_THREAD_ATTACH_EXCEPTION, 0 }, + { SENSOR_SERVICE_EXCEPTION, 0 }, + { MISC_SERVICE_EXCEPTION, 0 }, + { SENSOR_SERVICE_IPC_EXCEPTION, 0 }, + { MISC_SERVICE_IPC_EXCEPTION, 0 }, + { SENSOR_HIDL_SERVICE_EXCEPTION, 0 }, + { LIGHT_HIDL_SERVICE_EXCEPTION, 0 }, + { VIBRATOR_HIDL_SERVICE_EXCEPTION, 0 }, + { SENSOR_DATA_CHANNEL_EXCEPTION, 0 }, +}; + +std::mutex DmdReport::eventMutex_; + +static std::string GetEventName(int32_t eventId) +{ + switch (eventId) { + case JNI_ENV_VAR_EXCEPTION: + return "JniEnvVarException"; + case CLASS_NOT_FOUND: + return "ClassNotFound"; + case NATIVE_METHOD_REGISTER_EXCEPTION: + return "NativeMethodRegisterException"; + case JAVA_VM_THREAD_ATTACH_EXCEPTION: + return "JavaVmThreadAttachException"; + case SENSOR_SERVICE_EXCEPTION: + return "SensorServiceException"; + case MISC_SERVICE_EXCEPTION: + return "MiscServiceException"; + case SENSOR_SERVICE_IPC_EXCEPTION: + return "SensorServiceIpcException"; + case MISC_SERVICE_IPC_EXCEPTION: + return "MiscServiceIpcException"; + case SENSOR_HIDL_SERVICE_EXCEPTION: + return "SensorHidlServiceException"; + case LIGHT_HIDL_SERVICE_EXCEPTION: + return "LightHidlServiceException"; + case VIBRATOR_HIDL_SERVICE_EXCEPTION: + return "VibratorHidlServiceException"; + case SENSOR_DATA_CHANNEL_EXCEPTION: + return "SensorDataChannelException"; + default: + return ""; + } +} + +void DmdReport::ReportException(int32_t eventId, const std::string &interfaceName, int32_t error) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard eventLock(eventMutex_); + auto eventIt = eventMap_.find(eventId); + if (eventIt == eventMap_.end()) { + HiLog::Error(LABEL, "%{public}s eventId : %{public}d is not supported", __func__, eventId); + return; + } + int64_t curTime = GetSecondsSince1970ToNow(); + if ((curTime - eventIt->second) > SECONDS_HALF_HOUR) { + HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::SENSORS, GetEventName(eventId), + HiviewDFX::HiSysEvent::EventType::FAULT, interfaceName, error); + eventMap_[eventId] = curTime; + HiLog::Debug(LABEL, "%{public}s end", __func__); + return; + } + HiLog::Warn(LABEL, "%{public}s eventId is reported every half an hour", __func__); +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/miscdevice_common.cpp b/utils/src/miscdevice_common.cpp new file mode 100755 index 00000000..5520dee9 --- /dev/null +++ b/utils/src/miscdevice_common.cpp @@ -0,0 +1,59 @@ +/* + * 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 "miscdevice_common.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "MiscdeviceCommon" }; +constexpr int32_t MIN_VIBRATOR_COUNT = 0; +constexpr int32_t MAX_VIBRATOR_COUNT = 100; +constexpr int32_t MIN_VIBRATOR_INTENSITY = 0; +constexpr int32_t MAX_VIBRATOR_INTENSITY = 255; +constexpr int32_t HALF_AN_HOUR = 1800000; // ms +} // namespace + +bool MiscdeviceCommon::CheckCustomVibratorEffect(const std::vector &timing, + const std::vector &intensity, int32_t periodCount) +{ + if ((periodCount < MIN_VIBRATOR_COUNT) || (periodCount > MAX_VIBRATOR_COUNT)) { + HiLog::Error(LABEL, "%{public}s failed, input param invalid", __func__); + return false; + } + if (timing.size() != intensity.size()) { + HiLog::Error(LABEL, "%{public}s failed, timing size invalid", __func__); + return false; + } + int32_t totalTime = 0; + for (uint32_t i = 0; i < timing.size(); i = i + 2) { + totalTime += timing[i]; + } + if (totalTime > HALF_AN_HOUR) { + HiLog::Error(LABEL, "%{public}s failed, totalTime invalid", __func__); + return false; + } + for (uint32_t i = 0; i < intensity.size(); i++) { + if ((intensity[i] < MIN_VIBRATOR_INTENSITY) || (intensity[i] > MAX_VIBRATOR_INTENSITY)) { + return false; + } + } + return true; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/permission_util.cpp b/utils/src/permission_util.cpp new file mode 100755 index 00000000..b66a49b4 --- /dev/null +++ b/utils/src/permission_util.cpp @@ -0,0 +1,123 @@ +/* + * 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 "permission_util.h" + +#include + +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "PermissionUtil" }; +constexpr uint32_t SENSOR_ACCELEROMETER_ID = 256; +constexpr uint32_t SENSOR_ACCELEROMETER_UNCALIBRATED_ID = 65792; +constexpr uint32_t SENSOR_LINEAR_ACCELERATION_ID = 131328; +constexpr uint32_t SENSOR_GYROSCOPE_ID = 262400; +constexpr uint32_t SENSOR_GYROSCOPE_UNCALIBRATED_ID = 327936; +constexpr uint32_t SENSOR_PEDOMETER_DETECTION_ID = 524544; +constexpr uint32_t SENSOR_PEDOMETER_ID = 590080; +constexpr uint32_t SENSOR_HEART_RATE_ID = 83886336; +constexpr int32_t GET_SERVICE_MAX_COUNT = 30; +constexpr uint32_t WAIT_MS = 200; +const std::string ACCELEROMETER_PERMISSION = "ohos.permission.ACCELEROMETER"; +const std::string GYROSCOPE_PERMISSION = "ohos.permission.GYROSCOPE"; +const std::string ACTIVITY_MOTION_PERMISSION = "ohos.permission.ACTIVITY_MOTION"; +const std::string READ_HEALTH_DATA_PERMISSION = "ohos.permission.READ_HEALTH_DATA"; +} // namespace + +std::unordered_map PermissionUtil::sensorPermissions_ = { + { SENSOR_ACCELEROMETER_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_ACCELEROMETER_UNCALIBRATED_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_LINEAR_ACCELERATION_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_GYROSCOPE_ID, GYROSCOPE_PERMISSION }, + { SENSOR_GYROSCOPE_UNCALIBRATED_ID, GYROSCOPE_PERMISSION }, + { SENSOR_PEDOMETER_DETECTION_ID, ACTIVITY_MOTION_PERMISSION }, + { SENSOR_PEDOMETER_ID, ACTIVITY_MOTION_PERMISSION }, + { SENSOR_HEART_RATE_ID, READ_HEALTH_DATA_PERMISSION } +}; + +PermissionUtil::~PermissionUtil() +{ + appPermissionStatus_.clear(); +} + +bool PermissionUtil::IsPermissionRegisted(int32_t uid) +{ + HiLog::Debug(LABEL, "%{public}s appPermissionStatus_.size : %{public}d", __func__, + int32_t { appPermissionStatus_.size() }); + std::lock_guard permissionLock(permissionStatusMutex_); + auto permissionIt = appPermissionStatus_.find(uid); + if (permissionIt != appPermissionStatus_.end()) { + HiLog::Debug(LABEL, "%{public}s uid : %{public}d permission has registered", __func__, uid); + return true; + } + return false; +} + +bool PermissionUtil::RegistPermissionChanged(const AppThreadInfo &appThreadInfo) +{ + HiLog::Debug(LABEL, "%{public}s begin, uid : %{public}d, pid : %{public}d", __func__, appThreadInfo.uid, + appThreadInfo.pid); + // Avoid registering callback functions repeatedly + if (IsPermissionRegisted(appThreadInfo.uid)) { + HiLog::Debug(LABEL, "%{public}s uid : %{public}d permission has registered", __func__, appThreadInfo.uid); + return true; + } + int32_t retry = 0; + while (retry < GET_SERVICE_MAX_COUNT) { + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS)); + HiLog::Error(LABEL, "%{public}s registered failed, retry : %{public}d", __func__, retry); + retry++; + } + HiLog::Debug(LABEL, "%{public}s end", __func__); + return true; +} + +void PermissionUtil::UnregistPermissionChanged(const AppThreadInfo &appThreadInfo) +{ + HiLog::Debug(LABEL, "%{public}s begin, uid : %{public}d, pid : %{public}d", __func__, appThreadInfo.uid, + appThreadInfo.pid); + std::lock_guard permissionLock(permissionStatusMutex_); + auto permissionIt = appPermissionStatus_.find(appThreadInfo.uid); + if (permissionIt != appPermissionStatus_.end()) { + HiLog::Debug(LABEL, "%{public}s erase uid : %{public}d permission", __func__, appThreadInfo.uid); + appPermissionStatus_.erase(permissionIt); + return; + } + HiLog::Debug(LABEL, "%{public}s end", __func__); +} + +void PermissionUtil::UpdatePermissionStatus(int32_t uid, const std::string &permissionName, bool permissionStatus) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard permissionLock(permissionStatusMutex_); + auto permissionIt = appPermissionStatus_.find(uid); + if (permissionIt == appPermissionStatus_.end()) { + std::unordered_map permissionMap; + permissionMap.insert(std::make_pair(permissionName, permissionStatus)); + appPermissionStatus_.insert(std::make_pair(uid, permissionMap)); + HiLog::Debug(LABEL, "%{public}s end", __func__); + return; + } + permissionIt->second[permissionName] = permissionStatus; + HiLog::Debug(LABEL, "%{public}s end", __func__); +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/report_data_callback.cpp b/utils/src/report_data_callback.cpp new file mode 100755 index 00000000..4b27d868 --- /dev/null +++ b/utils/src/report_data_callback.cpp @@ -0,0 +1,102 @@ +/* + * 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 "report_data_callback.h" + +#include +#include + +#include "errors.h" +#include "securec.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "ReportDataCallback" +}; +} // namespace +ReportDataCallback::ReportDataCallback() +{ + eventsBuf_.circularBuf = new struct SensorEvent[CIRCULAR_BUF_LEN]; + eventsBuf_.readPosition = 0; + eventsBuf_.writePosition = 0; + eventsBuf_.eventNum = 0; +} + +ReportDataCallback::~ReportDataCallback() +{ + if (eventsBuf_.circularBuf != nullptr) { + delete[] eventsBuf_.circularBuf; + } + eventsBuf_.circularBuf = nullptr; + eventsBuf_.readPosition = 0; + eventsBuf_.writePosition = 0; + eventsBuf_.eventNum = 0; +} + +int32_t ReportDataCallback::ZReportDataCallback(const struct SensorEvent* event, sptr cb) +{ + float *data = (float*)event->data; + HiLog::Info(LABEL, "%{public}s in, sensorData: %{public}f", __func__, *(data)); + if (cb == nullptr || cb->eventsBuf_.circularBuf == nullptr || event == nullptr) { + HiLog::Error(LABEL, "%{public}s callback or circularBuf or event cannot be null", __func__); + return ERROR; + } + struct SensorEvent eventCopy = { + .sensorTypeId = event->sensorTypeId, + .version = event->version, + .timestamp = event->timestamp, + .option = event->option, + .mode = event->mode, + .dataLen = event->dataLen + }; + eventCopy.data = new uint8_t[SENSOR_DATA_LENGHT]; + if (memcpy_s(eventCopy.data, event->dataLen, event->data, event->dataLen) != EOK) { + HiLog::Error(LABEL, "%{public}s copy data failed", __func__); + return COPY_ERR; + } + int32_t leftSize = CIRCULAR_BUF_LEN - cb->eventsBuf_.eventNum; + int32_t toEndLen = CIRCULAR_BUF_LEN - cb->eventsBuf_.writePosition; + if (toEndLen == 0) { + cb->eventsBuf_.circularBuf[0] = eventCopy; + cb->eventsBuf_.writePosition = 1 - toEndLen; + } else { + cb->eventsBuf_.circularBuf[cb->eventsBuf_.writePosition] = eventCopy; + cb->eventsBuf_.writePosition += 1; + } + if (leftSize < 1) { + cb->eventsBuf_.readPosition = cb->eventsBuf_.writePosition; + } + cb->eventsBuf_.eventNum += 1; + if (cb->eventsBuf_.eventNum >= CIRCULAR_BUF_LEN) { + cb->eventsBuf_.eventNum = CIRCULAR_BUF_LEN; + } + if (cb->eventsBuf_.writePosition == CIRCULAR_BUF_LEN) { + cb->eventsBuf_.writePosition = 0; + } + return ERR_OK; +} + +struct CircularEventBuf &ReportDataCallback::GetEventData() +{ + return eventsBuf_; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/sensor.cpp b/utils/src/sensor.cpp new file mode 100755 index 00000000..84e4129e --- /dev/null +++ b/utils/src/sensor.cpp @@ -0,0 +1,232 @@ +/* + * 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 "sensor.h" + +#include "sensors_errors.h" +#include "sensors_log_domain.h" +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "Sensor" }; +} + +Sensor::Sensor() + : sensorId_(0), + version_(0), + maxRange_(0.0), + resolution_(0.0), + flags_(0), + fifoMaxEventCount_(0), + minSamplePeriodNs_(0), + maxSamplePeriodNs_(0) +{} + +uint32_t Sensor::GetSensorId() const +{ + return sensorId_; +} + +void Sensor::SetSensorId(uint32_t sensorId) +{ + sensorId_ = sensorId; +} + +std::string Sensor::GetName() const +{ + return name_; +} + +void Sensor::SetName(const std::string &name) +{ + name_ = name; +} + +std::string Sensor::GetVendor() const +{ + return vendor_; +} + +void Sensor::SetVendor(const std::string &vendor) +{ + vendor_ = vendor; +} + +uint32_t Sensor::GetVersion() const +{ + return version_; +} + +void Sensor::SetVersion(uint32_t version) +{ + version_ = version; +} + +float Sensor::GetMaxRange() const +{ + return maxRange_; +} + +void Sensor::SetMaxRange(float maxRange) +{ + maxRange_ = maxRange; +} + +float Sensor::GetResolution() const +{ + return resolution_; +} + +void Sensor::SetResolution(float resolution) +{ + resolution_ = resolution; +} + +uint32_t Sensor::GetFlags() const +{ + return flags_; +} + +void Sensor::SetFlags(uint32_t flags) +{ + flags_ = flags; +} + +int32_t Sensor::GetFifoMaxEventCount() const +{ + return fifoMaxEventCount_; +} + +void Sensor::SetFifoMaxEventCount(int32_t fifoMaxEventCount) +{ + fifoMaxEventCount_ = fifoMaxEventCount; +} + +int64_t Sensor::GetMinSamplePeriodNs() const +{ + return minSamplePeriodNs_; +} + +void Sensor::SetMinSamplePeriodNs(int64_t minSamplePeriodNs) +{ + minSamplePeriodNs_ = minSamplePeriodNs; +} + +int64_t Sensor::GetMaxSamplePeriodNs() const +{ + return maxSamplePeriodNs_; +} + +void Sensor::SetMaxSamplePeriodNs(int64_t maxSamplePeriodNs) +{ + maxSamplePeriodNs_ = maxSamplePeriodNs; +} + +std::vector Sensor::GetReserved() const +{ + return reserved_; +} + +void Sensor::SetReserved(const std::vector &reserved) +{ + auto reservedCount = reserved.size(); + for (size_t i = 0; i < reservedCount; i++) { + reserved_[i] = reserved[i]; + } +} + +bool Sensor::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteUint32(sensorId_)) { + HiLog::Error(LABEL, "%{public}s failed, write sensorId failed", __func__); + return false; + } + if (!parcel.WriteString(name_)) { + HiLog::Error(LABEL, "%{public}s failed, write name_ failed", __func__); + return false; + } + if (!parcel.WriteString(vendor_)) { + HiLog::Error(LABEL, "%{public}s failed, write vendor_ failed", __func__); + return false; + } + if (!parcel.WriteUint32(version_)) { + HiLog::Error(LABEL, "%{public}s failed, write version_ failed", __func__); + return false; + } + if (!parcel.WriteFloat(maxRange_)) { + HiLog::Error(LABEL, "%{public}s failed, write maxRange_ failed", __func__); + return false; + } + if (!parcel.WriteFloat(resolution_)) { + HiLog::Error(LABEL, "%{public}s failed, write resolution_ failed", __func__); + return false; + } + if (!parcel.WriteUint32(flags_)) { + HiLog::Error(LABEL, "%{public}s failed, write flags_ failed", __func__); + return false; + } + if (!parcel.WriteInt32(fifoMaxEventCount_)) { + HiLog::Error(LABEL, "%{public}s failed, write fifoMaxEventCount_ failed", __func__); + return false; + } + if (!parcel.WriteInt64(minSamplePeriodNs_)) { + HiLog::Error(LABEL, "%{public}s failed, write minSamplePeriodNs_ failed", __func__); + return false; + } + if (!parcel.WriteInt64(maxSamplePeriodNs_)) { + HiLog::Error(LABEL, "%{public}s failed, write maxSamplePeriodNs_ failed", __func__); + return false; + } + if (!parcel.WriteUInt32Vector(reserved_)) { + HiLog::Error(LABEL, "%{public}s failed, write reserved_ failed", __func__); + return false; + } + + return true; +} + +std::unique_ptr Sensor::Unmarshalling(Parcel &parcel) +{ + auto sensor = std::make_unique(); + if (sensor == nullptr) { + HiLog::Error(LABEL, "%{public}s sensor cannot be null", __func__); + return nullptr; + } + + if (!sensor->ReadFromParcel(parcel)) { + HiLog::Error(LABEL, "%{public}s ReadFromParcel failed", __func__); + return nullptr; + } + return sensor; +} + +bool Sensor::ReadFromParcel(Parcel &parcel) +{ + sensorId_ = parcel.ReadUint32(); + name_ = parcel.ReadString(); + vendor_ = parcel.ReadString(); + version_ = parcel.ReadUint32(); + maxRange_ = parcel.ReadFloat(); + resolution_ = parcel.ReadFloat(); + flags_ = parcel.ReadUint32(); + fifoMaxEventCount_ = parcel.ReadInt32(); + minSamplePeriodNs_ = parcel.ReadInt64(); + maxSamplePeriodNs_ = parcel.ReadInt64(); + return parcel.ReadUInt32Vector(&reserved_); +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/sensor_basic_data_channel.cpp b/utils/src/sensor_basic_data_channel.cpp new file mode 100755 index 00000000..3ae2fc33 --- /dev/null +++ b/utils/src/sensor_basic_data_channel.cpp @@ -0,0 +1,216 @@ +/* + * 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 "sensor_basic_data_channel.h" + +#include +#include +#include + +#include "dmd_report.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "SensorBasicChannel" }; +constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024; +constexpr int32_t SOCKET_PAIR_SIZE = 2; +} // namespace + +SensorBasicDataChannel::SensorBasicDataChannel() : sendFd_(INVALID_FD), receiveFd_(INVALID_FD), isActive_(false) +{ + HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d, sendFd: %{public}d", __func__, isActive_, sendFd_); +} + +int32_t SensorBasicDataChannel::CreateSensorBasicChannel(size_t sendSize, size_t receiveSize) +{ + if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) { + HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__); + return ERR_OK; + } + + int32_t socketPair[SOCKET_PAIR_SIZE] = { 0 }; + if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketPair) != 0) { + DmdReport::ReportException(SENSOR_DATA_CHANNEL_EXCEPTION, "CreateSensorBasicChannel", + SENSOR_CHANNEL_SOCKET_CREATE_ERR); + HiLog::Error(LABEL, "%{public}s create socketpair failed", __func__); + sendFd_ = INVALID_FD; + receiveFd_ = INVALID_FD; + return SENSOR_CHANNEL_SOCKET_CREATE_ERR; + } + // set socket attr + setsockopt(socketPair[0], SOL_SOCKET, SO_SNDBUF, &sendSize, sizeof(sendSize)); + setsockopt(socketPair[1], SOL_SOCKET, SO_RCVBUF, &receiveSize, sizeof(receiveSize)); + int32_t bufferSize = DEFAULT_CHANNEL_SIZE; + int32_t ret = setsockopt(socketPair[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s setsockopt socketpair 0 failed", __func__); + return SENSOR_CHANNEL_SOCKET_CREATE_ERR; + } + ret = setsockopt(socketPair[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s setsockopt socketpair 1 failed", __func__); + return SENSOR_CHANNEL_SOCKET_CREATE_ERR; + } + ret = fcntl(socketPair[0], F_SETFL, O_NONBLOCK); + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s fcntl socketpair 0 failed", __func__); + return SENSOR_CHANNEL_SOCKET_CREATE_ERR; + } + ret = fcntl(socketPair[1], F_SETFL, O_NONBLOCK); + if (ret != 0) { + HiLog::Error(LABEL, "%{public}s fcntl socketpair 1 failed", __func__); + return SENSOR_CHANNEL_SOCKET_CREATE_ERR; + } + sendFd_ = socketPair[0]; + receiveFd_ = socketPair[1]; + HiLog::Debug(LABEL, "%{public}s create socketpair success, receiveFd_ : %{public}d, sendFd_ : %{public}d", __func__, + receiveFd_, sendFd_); + return ERR_OK; +} + +int32_t SensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) { + HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__); + return ERR_OK; + } + int32_t tmpFd = data.ReadFileDescriptor(); + if (tmpFd < 0) { + HiLog::Error(LABEL, "%{public}s ReadFileDescriptor failed", __func__); + sendFd_ = INVALID_FD; + return SENSOR_CHANNEL_DUP_ERR; + } + sendFd_ = dup(tmpFd); + if (sendFd_ < 0) { + HiLog::Error(LABEL, "%{public}s dup FileDescriptor failed", __func__); + sendFd_ = INVALID_FD; + return SENSOR_CHANNEL_DUP_ERR; + } + return ERR_OK; +} + +SensorBasicDataChannel::~SensorBasicDataChannel() +{ + DestroySensorBasicChannel(); +} + +int32_t SensorBasicDataChannel::SendToBinder(MessageParcel &data) +{ + HiLog::Debug(LABEL, "%{public}s sendFd: %{public}d", __func__, sendFd_); + if (sendFd_ < 0) { + HiLog::Error(LABEL, "%{public}s sendFd FileDescriptor error", __func__); + return SENSOR_CHANNEL_SENDFD_ERR; + } + bool result = data.WriteFileDescriptor(sendFd_); + if (!result) { + HiLog::Error(LABEL, "%{public}s send sendFd_ failed", __func__); + CloseSendFd(); + return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR; + } + return ERR_OK; +} + +void SensorBasicDataChannel::CloseSendFd() +{ + if (sendFd_ != INVALID_FD) { + close(sendFd_); + sendFd_ = INVALID_FD; + HiLog::Debug(LABEL, "%{public}s close sendFd_", __func__); + } +} + +int32_t SensorBasicDataChannel::SendData(const void *vaddr, size_t size) +{ + if (vaddr == nullptr || sendFd_ < 0) { + HiLog::Error(LABEL, "%{public}s failed, param is invalid", __func__); + return SENSOR_CHANNEL_SEND_ADDR_ERR; + } + ssize_t length; + do { + length = send(sendFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); + } while (errno == EINTR); + if (length < 0) { + HiLog::Error(LABEL, "%{public}s send fail : %{public}d, length = %{public}d", __func__, errno, (int32_t)length); + return SENSOR_CHANNEL_SEND_DATA_ERR; + } + return ERR_OK; +} + +int32_t SensorBasicDataChannel::ReceiveData(void *vaddr, size_t size) +{ + if (vaddr == nullptr || (receiveFd_ == INVALID_FD)) { + HiLog::Error(LABEL, "%{public}s failed, vaddr is null or receiveFd_ invalid", __func__); + return SENSOR_CHANNEL_RECEIVE_ADDR_ERR; + } + ssize_t length; + do { + length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT); + } while (errno == EINTR); + if (length < 0) { + return 0; + } + return length; +} + +int32_t SensorBasicDataChannel::GetSendDataFd() const +{ + return sendFd_; +} + +int32_t SensorBasicDataChannel::GetReceiveDataFd() const +{ + return receiveFd_; +} + +int32_t SensorBasicDataChannel::DestroySensorBasicChannel() +{ + if (sendFd_ >= 0) { + close(sendFd_); + sendFd_ = INVALID_FD; + HiLog::Debug(LABEL, "%{public}s close sendFd_ success", __func__); + } + if (receiveFd_ >= 0) { + close(receiveFd_); + receiveFd_ = INVALID_FD; + HiLog::Debug(LABEL, "%{public}s close receiveFd_ success", __func__); + } + return ERR_OK; +} + +const std::unordered_map &SensorBasicDataChannel::GetDataCacheBuf() const +{ + return dataCacheBuf_; +} + +bool SensorBasicDataChannel::GetSensorStatus() const +{ + return isActive_; +} + +void SensorBasicDataChannel::SetSensorStatus(bool isActive) +{ + HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d", __func__, isActive); + std::unique_lock lock(statusLock_); + isActive_ = isActive; + return; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/sensor_basic_info.cpp b/utils/src/sensor_basic_info.cpp new file mode 100755 index 00000000..959806cc --- /dev/null +++ b/utils/src/sensor_basic_info.cpp @@ -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. + */ + +#include "sensor_basic_info.h" + +namespace OHOS { +namespace Sensors { +SensorBasicInfo::SensorBasicInfo() : samplingPeriodNs_(0L), maxReportDelayNs_(0L), sensorState_(SENSOR_DISABLED) +{} + +int64_t SensorBasicInfo::GetSamplingPeriodNs() const +{ + return samplingPeriodNs_; +} + +void SensorBasicInfo::SetSamplingPeriodNs(int64_t samplingPeriodNs) +{ + samplingPeriodNs_ = samplingPeriodNs; +} + +int64_t SensorBasicInfo::GetMaxReportDelayNs() const +{ + return maxReportDelayNs_; +} + +void SensorBasicInfo::SetMaxReportDelayNs(int64_t maxReportDelayNs) +{ + maxReportDelayNs_ = maxReportDelayNs; +} + +SensorState SensorBasicInfo::GetSensorState() const +{ + return sensorState_; +} + +void SensorBasicInfo::SetSensorState(SensorState sensorState) +{ + sensorState_ = sensorState; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/src/sensor_channel_info.cpp b/utils/src/sensor_channel_info.cpp new file mode 100755 index 00000000..f844a45a --- /dev/null +++ b/utils/src/sensor_channel_info.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 "sensor_channel_info.h" + +namespace OHOS { +namespace Sensors { +SensorChannelInfo::SensorChannelInfo() : uid_(0), sensorId_(0), samplingPeriodNs_(0), fifoCount_(0) +{} + +int32_t SensorChannelInfo::GetUid() const +{ + return uid_; +} + +void SensorChannelInfo::SetUid(int32_t uid) +{ + uid_ = uid; +} + +std::string SensorChannelInfo::GetPackageName() const +{ + return packageName_; +} + +void SensorChannelInfo::SetPackageName(const std::string &packageName) +{ + packageName_ = packageName; +} + +uint32_t SensorChannelInfo::GetSensorId() const +{ + return sensorId_; +} + +void SensorChannelInfo::SetSensorId(uint32_t sensorId) +{ + sensorId_ = sensorId; +} + +int64_t SensorChannelInfo::GetSamplingPeriodNs() const +{ + return samplingPeriodNs_; +} + +void SensorChannelInfo::SetSamplingPeriodNs(int64_t samplingPeriodNs) +{ + samplingPeriodNs_ = samplingPeriodNs; +} + +int32_t SensorChannelInfo::GetFifoCount() const +{ + return fifoCount_; +} + +void SensorChannelInfo::SetFifoCount(int32_t fifoCount) +{ + fifoCount_ = fifoCount; +} + +std::vector SensorChannelInfo::GetCmdType() const +{ + return cmdType_; +} + +void SensorChannelInfo::SetCmdType(const std::vector &cmdType) +{ + cmdType_ = cmdType; +} +} // namespace Sensors +} // namespace OHOS -- Gitee From d6454f030125b41d865c43a81564f626adb635b3 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Tue, 14 Sep 2021 02:28:12 +0000 Subject: [PATCH 2/5] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- frameworks/native/sensor/BUILD.gn | 23 ++-- .../sensor/test/unittest/common/BUILD.gn | 35 +++--- .../sensor/test/unittest/phone/BUILD.gn | 21 ++-- interfaces/native/BUILD.gn | 5 +- interfaces/native/test/BUILD.gn | 11 +- interfaces/plugin/BUILD.gn | 7 +- interfaces/plugin/test/unittest/BUILD.gn | 117 +++++++++--------- ohos.build | 24 ++-- utils/BUILD.gn | 10 +- 9 files changed, 127 insertions(+), 126 deletions(-) diff --git a/frameworks/native/sensor/BUILD.gn b/frameworks/native/sensor/BUILD.gn index d61ed650..6210e4a1 100755 --- a/frameworks/native/sensor/BUILD.gn +++ b/frameworks/native/sensor/BUILD.gn @@ -17,40 +17,41 @@ import( "//foundation/appexecfwk/standard/libs/libeventhandler/lib_event_handler_sources.gni") SUBSYSTEM_DIR = "//base/sensors" + ############################################## ohos_shared_library("libsensor_native") { sources = [ + "src/my_event_handler.cpp", + "src/my_file_descriptor_listener.cpp", + "src/sensor_agent_proxy.cpp", "src/sensor_data_channel.cpp", "src/sensor_service_client.cpp", "src/sensor_service_proxy.cpp", - "src/sensor_agent_proxy.cpp", - "src/my_event_handler.cpp", - "src/my_file_descriptor_listener.cpp", ] include_dirs = [ "include", "//utils/native/base/include", "//utils/system/safwk/native/include", - "$SUBSYSTEM_DIR/sensors_sensor/utils/include", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", "//drivers/peripheral/sensor/interfaces/include", "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", "//foundation/appexecfwk/standard/libs/test/moduletest/common/event_handler", ] deps = [ - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", - "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", - "//utils/native/base:utils", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", "//drivers/peripheral/sensor/hal:hdi_sensor", "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", "//foundation/appexecfwk/standard/libs/libeventhandler:libeventhandler_target", + "//utils/native/base:utils", ] - + external_deps = [ - "ipc:ipc_core", "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", "safwk:system_ability_fwk", "samgr_L2:samgr_proxy", ] diff --git a/frameworks/native/sensor/test/unittest/common/BUILD.gn b/frameworks/native/sensor/test/unittest/common/BUILD.gn index a574087a..143de54d 100755 --- a/frameworks/native/sensor/test/unittest/common/BUILD.gn +++ b/frameworks/native/sensor/test/unittest/common/BUILD.gn @@ -14,7 +14,7 @@ import("//build/test.gni") SUBSYSTEM_DIR = "//base/sensors" -module_output_path = "sensors/sensors_sensor/frameworks/sensor" +module_output_path = "sensors/sensor/frameworks/sensor" ####################################################### ohos_unittest("SensorNativeCommonTest") { @@ -24,18 +24,18 @@ ohos_unittest("SensorNativeCommonTest") { include_dirs = [ "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", - "$SUBSYSTEM_DIR/sensors_sensor/utils/include", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/common/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/common/include", "//utils/native/base/include", ] deps = [ - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", - "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//utils/native/base:utils", @@ -57,18 +57,18 @@ ohos_unittest("SensorDfxTest") { include_dirs = [ "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", - "$SUBSYSTEM_DIR/sensors_sensor/utils/include", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", "//utils/native/base/include", ] deps = [ - #"$SUBSYSTEM_DIR/sensors_sensor/adapter/frameworks:libsensor_fwk_adapter", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", - "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + #"$SUBSYSTEM_DIR/sensor/adapter/frameworks:libsensor_fwk_adapter", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//utils/native/base:utils", @@ -76,6 +76,7 @@ ohos_unittest("SensorDfxTest") { external_deps = [ "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/frameworks/native/sensor/test/unittest/phone/BUILD.gn b/frameworks/native/sensor/test/unittest/phone/BUILD.gn index 4e65b9b7..112320b2 100755 --- a/frameworks/native/sensor/test/unittest/phone/BUILD.gn +++ b/frameworks/native/sensor/test/unittest/phone/BUILD.gn @@ -14,7 +14,7 @@ import("//build/test.gni") SUBSYSTEM_DIR = "//base/sensors" -module_output_path = "sensors/sensors_sensor/frameworks/sensor" +module_output_path = "sensors/sensor/frameworks/sensor" ####################################################### ohos_unittest("SensorNativeTest") { @@ -24,19 +24,19 @@ ohos_unittest("SensorNativeTest") { include_dirs = [ "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", - "$SUBSYSTEM_DIR/sensors_sensor/utils/include", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor/include", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/common/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/common/include", "//utils/native/base/include", ] deps = [ - #"$SUBSYSTEM_DIR/sensors_sensor/adapter/frameworks:libsensor_fwk_adapter", - "$SUBSYSTEM_DIR/sensors_sensor/frameworks/native/sensor:libsensor_native", - "$SUBSYSTEM_DIR/sensors_sensor/services/sensor:libsensor_service", - "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + #"$SUBSYSTEM_DIR/sensor/adapter/frameworks:libsensor_fwk_adapter", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//utils/native/base:utils", @@ -44,6 +44,7 @@ ohos_unittest("SensorNativeTest") { external_deps = [ "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", "ipc:ipc_core", "safwk:system_ability_fwk", diff --git a/interfaces/native/BUILD.gn b/interfaces/native/BUILD.gn index 8972d418..f98d92a6 100755 --- a/interfaces/native/BUILD.gn +++ b/interfaces/native/BUILD.gn @@ -32,6 +32,7 @@ ohos_shared_library("sensor_interface_native") { "//utils/system/safwk/native/include", "$SUBSYSTEM_DIR/frameworks/native/sensor/include", "$SUBSYSTEM_DIR/utils/include", + #"//drivers/peripheral/sensor/interfaces/include", "$SUBSYSTEM_DIR/interfaces/native/include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", @@ -39,10 +40,10 @@ ohos_shared_library("sensor_interface_native") { ] deps = [ "$SUBSYSTEM_DIR/frameworks/native/sensor:libsensor_native", - "$SUBSYSTEM_DIR/utils:libsensor_utils", - "//utils/native/base:utils", "$SUBSYSTEM_DIR/interfaces/native:libsensor_ndk", + "$SUBSYSTEM_DIR/utils:libsensor_utils", "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//utils/native/base:utils", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] part_name = "sensors_sensor" diff --git a/interfaces/native/test/BUILD.gn b/interfaces/native/test/BUILD.gn index b9f30f3c..c0d402a8 100755 --- a/interfaces/native/test/BUILD.gn +++ b/interfaces/native/test/BUILD.gn @@ -14,7 +14,7 @@ import("//build/test.gni") SUBSYSTEM_DIR = "//base/sensors" -module_output_path = "sensors/sensors_sensor/interfaces" +module_output_path = "sensors/sensor/interfaces" ###########################SensorAgentTest########################### ohos_unittest("SensorAgentTest") { @@ -24,19 +24,20 @@ ohos_unittest("SensorAgentTest") { include_dirs = [ "//utils/native/base/include", - "$SUBSYSTEM_DIR/sensors_sensor/utils/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", ] deps = [ - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native:sensor_ndk_target", - "$SUBSYSTEM_DIR/sensors_sensor/utils:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/interfaces/native:sensor_ndk_target", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] external_deps = [ "hiviewdfx_hilog_native:libhilog", + #"communication_L2:ipc_core", "ipc:ipc_core", ] diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn index 143087c3..0b761ffa 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("sensor") { include_dirs = [ "//third_party/node/src", @@ -24,16 +23,16 @@ ohos_shared_library("sensor") { "./include", ] defines = [ - "APP_LOG_TAG = \"sensroJs\"", - "LOG_DOMAIN = 0xD002700", + "APP_LOG_TAG = \"sensroJs\"", + "LOG_DOMAIN = 0xD002700", ] sources = [ "./src/sensor_js.cpp", "./src/sensor_napi_utils.cpp", ] deps = [ - "//foundation/ace/napi:ace_napi", "../native:sensor_interface_native", + "//foundation/ace/napi:ace_napi", "//utils/native/base:utils", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/interfaces/plugin/test/unittest/BUILD.gn b/interfaces/plugin/test/unittest/BUILD.gn index 8b0d776c..7c121c8d 100755 --- a/interfaces/plugin/test/unittest/BUILD.gn +++ b/interfaces/plugin/test/unittest/BUILD.gn @@ -1,61 +1,58 @@ -# 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 +# 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") -import("//build/test.gni") - -module_output_path = "sensors/sensors_sensor/interfaces" -ohos_unittest("SensorJsTest") { - module_out_path = module_output_path - - include_dirs = [ - "//third_party/node/src", - "//native_engine", - "//base/sensors/sensors_sensor/interfaces/native/include", - "//base/sensors/sensors_sensor/interfaces/plugin/include", - "//utils/native/base/include", - "./include", - "//third_party/libuv/include", - "//foundation/ace/napi", - "//foundation/ace/napi/interfaces/kits", - "//foundation/ace/napi/native_engine", - "//foundation/ace/napi/native_engine/impl/quickjs", - ] - defines = [ - "APP_LOG_TAG = \"sensroJs\"", - "LOG_DOMAIN = 0xD002700", - ] - sources = [ - "sensor_js_test.cpp", - ] - deps = [ - "//foundation/ace/napi:ace_napi", - "//base/sensors/sensors_sensor/interfaces/native:sensor_interface_native", - "//utils/native/base:utils", - "//foundation/ace/napi/:ace_napi_quickjs", - "//third_party/googletest:gtest", - "//third_party/googletest:gtest_main", - "//third_party/libuv:uv_static", - "//third_party/quickjs:qjs", - "//base/sensors/sensors_sensor/interfaces/plugin:sensor" - ] - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] - relative_install_dir = "module" - part_name = "sensors_sensor" - subsystem_name = "sensors" -} -group("unittest") { - testonly = true - deps = [ ":SensorJsTest" ] -} \ No newline at end of file + +#import("//build/config/ohos/rules.gni") +import("//build/ohos.gni") +import("//build/test.gni") +module_output_path = "sensors/sensor/interfaces" +ohos_unittest("SensorJsTest") { + module_out_path = module_output_path + + include_dirs = [ + "//third_party/node/src", + "//native_engine", + "//base/sensors/sensor/interfaces/native/include", + "//base/sensors/sensor/interfaces/plugin/include", + "//utils/native/base/include", + "./include", + "//third_party/libuv/include", + "//foundation/ace/napi", + "//foundation/ace/napi/interfaces/kits", + "//foundation/ace/napi/native_engine", + "//foundation/ace/napi/native_engine/impl/quickjs", + ] + defines = [ + "APP_LOG_TAG = \"sensroJs\"", + "LOG_DOMAIN = 0xD002700", + ] + sources = [ "sensor_js_test.cpp" ] + deps = [ + "//base/sensors/sensor/interfaces/native:sensor_interface_native", + "//base/sensors/sensor/interfaces/plugin:sensor", + "//foundation/ace/napi:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/googletest:gtest", + "//third_party/googletest:gtest_main", + "//third_party/libuv:uv_static", + "//third_party/quickjs:qjs", + "//utils/native/base:utils", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + relative_install_dir = "module" + part_name = "sensors_sensor" + subsystem_name = "sensors" +} +group("unittest") { + testonly = true + deps = [ ":SensorJsTest" ] +} diff --git a/ohos.build b/ohos.build index 3ade0df5..85db58cd 100755 --- a/ohos.build +++ b/ohos.build @@ -9,12 +9,12 @@ "intellitv" ], "module_list": [ - "//base/sensors/sensors_sensor/interfaces/native:sensor_ndk_target", - "//base/sensors/sensors_sensor/interfaces/plugin:sensor_js_target", - "//base/sensors/sensors_sensor/frameworks/native/sensor:sensor_native_target", - "//base/sensors/sensors_sensor/services/sensor:sensor_service_target", - "//base/sensors/sensors_sensor/utils:sensor_utils_target", - "//base/sensors/sensors_sensor/sa_profile:sensors_sa_profiles" + "//base/sensors/sensor/interfaces/native:sensor_ndk_target", + "//base/sensors/sensor/interfaces/plugin:sensor_js_target", + "//base/sensors/sensor/frameworks/native/sensor:sensor_native_target", + "//base/sensors/sensor/services/sensor:sensor_service_target", + "//base/sensors/sensor/utils:sensor_utils_target", + "//base/sensors/sensor/sa_profile:sensors_sa_profiles" ], "inner_kits": [ { @@ -23,16 +23,16 @@ "sensor_agent_type.h", "sensor_agent.h" ], - "header_base": "//base/sensors/sensors_sensor/interfaces/native/include" + "header_base": "//base/sensors/sensor/interfaces/native/include" }, - "name": "//base/sensors/sensors_sensor/interfaces/native:sensor_interface_native" + "name": "//base/sensors/sensor/interfaces/native:sensor_interface_native" } ], "test_list": [ - "//base/sensors/sensors_sensor/frameworks/native/sensor/test:unittest", - "//base/sensors/sensors_sensor/interfaces/native/test:unittest", - "//base/sensors/sensors_sensor/services/sensor/test:unittest", - "//base/sensors/sensors_sensor/interfaces/plugin/test/unittest:unittest" + "//base/sensors/sensor/frameworks/native/sensor/test:unittest", + "//base/sensors/sensor/interfaces/native/test:unittest", + "//base/sensors/sensor/services/sensor/test:unittest", + "//base/sensors/sensor/interfaces/plugin/test/unittest:unittest" ] } } diff --git a/utils/BUILD.gn b/utils/BUILD.gn index cbdacd98..afd130cb 100755 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -30,22 +30,22 @@ ohos_shared_library("libsensor_utils") { "//utils/native/base/include", "//utils/system/safwk/native/include", "//drivers/peripheral/sensor/interfaces/include", - "$SUBSYSTEM_DIR/sensors_sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include/message_parcel.h", ] deps = [ - "//utils/native/base:utils", "//drivers/peripheral/sensor/hal:hdi_sensor", "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//utils/native/base:utils", ] external_deps = [ + "aafwk_standard:base", + "aafwk_standard:intent", "appexecfwk_standard:appexecfwk_base", "appexecfwk_standard:appexecfwk_core", - "hiviewdfx_hilog_native:libhilog", "hisysevent_native:libhisysevent", - "aafwk_standard:base", - "aafwk_standard:intent", + "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr_L2:samgr_proxy", -- Gitee From e51f9387e658ddf7b6857e0314448f81c878de25 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Tue, 14 Sep 2021 12:39:07 +0000 Subject: [PATCH 3/5] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- README.md | 2 +- README_zh.md | 2 +- interfaces/native/BUILD.gn | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ce59576b..3134c386 100755 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The following figure shows the sensor architecture. The sample code for importing the sensor module is as follows: ``` -/base/sensors/sensors_sensor +/base/sensors/sensor ├── frameworks # Framework code │ └── native # Sensor client code ├── interfaces # External APIs diff --git a/README_zh.md b/README_zh.md index 93dc535d..10a2b2cc 100755 --- a/README_zh.md +++ b/README_zh.md @@ -35,7 +35,7 @@ sensor导入模块的示例代码如下: ``` -/base/sensors/sensors_sensor +/base/sensors/sensor ├── frameworks # 框架代码 │ └── native # sensor客户端代码 ├── interfaces # 对外接口存放目录 diff --git a/interfaces/native/BUILD.gn b/interfaces/native/BUILD.gn index f98d92a6..7f8cc5db 100755 --- a/interfaces/native/BUILD.gn +++ b/interfaces/native/BUILD.gn @@ -13,7 +13,7 @@ import("//build/ohos.gni") -SUBSYSTEM_DIR = "//base/sensors/sensors_sensor" +SUBSYSTEM_DIR = "//base/sensors/sensor" ############################################## ohos_ndk_library("libsensor_ndk") { -- Gitee From 31c64c9328bd96c9e734ec4518018144768145fd Mon Sep 17 00:00:00 2001 From: h00514358 Date: Wed, 15 Sep 2021 01:47:26 +0000 Subject: [PATCH 4/5] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- interfaces/plugin/src/sensor_js.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interfaces/plugin/src/sensor_js.cpp b/interfaces/plugin/src/sensor_js.cpp index 176e19c9..20a8286c 100755 --- a/interfaces/plugin/src/sensor_js.cpp +++ b/interfaces/plugin/src/sensor_js.cpp @@ -103,8 +103,7 @@ static int32_t UnsubscribeSensor(int32_t sensorTypeId) static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) { - HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d, interval: %{public}lld ", __func__, - sensorTypeId, interval); + HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d", __func__, sensorTypeId,); int32_t ret = SubscribeSensor(sensorTypeId, &user); if (ret < 0) { HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__); -- Gitee From 70a533f4a43b6b89c4a6f67eef7f64d4763a9a3a Mon Sep 17 00:00:00 2001 From: h00514358 Date: Wed, 15 Sep 2021 02:48:37 +0000 Subject: [PATCH 5/5] Signed-off-by:hellohyh001 Signed-off-by: h00514358 --- README.md | 2 +- interfaces/plugin/src/sensor_js.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3134c386..bb5a5ff7 100755 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ The sample code for importing the sensor module is as follows: ├── sa_profile # Configuration file of system ability names and dynamic libraries ├── services # Code of services │ └── sensor # Sensor service for reporting data about sensors, such as the acceleration and gyroscope sensors -└── utils # Common code, including permissions and communication capabilities +└── utils # Common code, including permissions and communication capabilities ``` ## Constraints diff --git a/interfaces/plugin/src/sensor_js.cpp b/interfaces/plugin/src/sensor_js.cpp index 20a8286c..96e611a6 100755 --- a/interfaces/plugin/src/sensor_js.cpp +++ b/interfaces/plugin/src/sensor_js.cpp @@ -103,7 +103,7 @@ static int32_t UnsubscribeSensor(int32_t sensorTypeId) static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) { - HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d", __func__, sensorTypeId,); + HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d", __func__, sensorTypeId); int32_t ret = SubscribeSensor(sensorTypeId, &user); if (ret < 0) { HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__); -- Gitee