1 /*
2  * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "medical_napi_utils.h"
17 
18 #include <iostream>
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 #include "hilog/log.h"
24 
25 namespace OHOS {
26 namespace Sensors {
27 using namespace OHOS::HiviewDFX;
28 static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002786, "AfeJsAPI"};
IsMatchType(napi_value value,napi_valuetype type,napi_env env)29 bool IsMatchType(napi_value value, napi_valuetype type, napi_env env)
30 {
31     napi_valuetype paramType;
32     napi_typeof(env, value, &paramType);
33     if (paramType != type) {
34         HiLog::Error(LABEL, "%{public}s  failed!", __func__);
35         return false;
36     }
37     return true;
38 }
39 
GetNapiInt32(int32_t number,napi_env env)40 napi_value GetNapiInt32(int32_t number, napi_env env)
41 {
42     napi_value value;
43     napi_create_int32(env, number, &value);
44     return value;
45 }
46 
NapiGetNamedProperty(napi_value jsonObject,std::string name,napi_env env)47 napi_value NapiGetNamedProperty(napi_value jsonObject, std::string name, napi_env env)
48 {
49     napi_value value;
50     napi_get_named_property(env, jsonObject, name.c_str(), &value);
51     return value;
52 }
53 
GetCppInt32(napi_value value,napi_env env)54 int32_t GetCppInt32(napi_value value, napi_env env)
55 {
56     int32_t number;
57     napi_get_value_int32(env, value, &number);
58     return number;
59 }
60 
GetCppInt64(napi_value value,napi_env env)61 int64_t GetCppInt64(napi_value value, napi_env env)
62 {
63     int64_t number;
64     napi_get_value_int64(env, value, &number);
65     return number;
66 }
67 
GetCppBool(napi_value value,napi_env env)68 bool GetCppBool(napi_value value, napi_env env)
69 {
70     bool number;
71     napi_get_value_bool(env, value, &number);
72     return number;
73 }
74 
GetUndefined(napi_env env)75 napi_value GetUndefined(napi_env env)
76 {
77     napi_value value;
78     napi_get_undefined(env, &value);
79     return value;
80 }
81 
82 std::map<int32_t, std::vector<std::string>> g_sensorAttributeList = {
83     { TYPE_ID_NONE, { "dataArray" } },
84     { TYPE_ID_PHOTOPLETHYSMOGRAPH, { "dataArray" } },
85 };
86 
EmitAsyncCallbackWork(AsyncCallbackInfo * asyncCallbackInfo)87 void EmitAsyncCallbackWork(AsyncCallbackInfo *asyncCallbackInfo)
88 {
89     HiLog::Debug(LABEL, "%{public}s begin", __func__);
90     if (asyncCallbackInfo == nullptr) {
91         HiLog::Error(LABEL, "%{public}s asyncCallbackInfo is null!", __func__);
92         return;
93     }
94     napi_value resourceName;
95     if (napi_create_string_utf8(asyncCallbackInfo->env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName) != napi_ok) {
96         HiLog::Error(LABEL, "%{public}s create string utf8 failed", __func__);
97         return;
98     }
99     napi_create_async_work(
100         asyncCallbackInfo->env, nullptr, resourceName,
101         [](napi_env env, void* data) {},
102         [](napi_env env, napi_status status, void* data) {
103             HiLog::Debug(LABEL, "%{public}s napi_create_async_work in", __func__);
104             AsyncCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(data);
105             napi_value callback;
106             napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback);
107             napi_value callResult = nullptr;
108             napi_value result;
109             napi_get_undefined(env, &result);
110             napi_call_function(env, nullptr, callback, 1, &result, &callResult);
111             napi_delete_reference(env, asyncCallbackInfo->callback[0]);
112             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
113             delete asyncCallbackInfo;
114             asyncCallbackInfo = nullptr;
115             HiLog::Debug(LABEL, "%{public}s napi_create_async_work left", __func__);
116         },
117         asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
118     napi_queue_async_work_with_qos(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default);
119     HiLog::Debug(LABEL, "%{public}s end", __func__);
120 }
121 
EmitUvEventLoop(AsyncCallbackInfo * asyncCallbackInfo)122 void EmitUvEventLoop(AsyncCallbackInfo *asyncCallbackInfo)
123 {
124     uv_loop_s *loop(nullptr);
125     napi_get_uv_event_loop(asyncCallbackInfo->env, &loop);
126     if (loop == nullptr) {
127         HiLog::Error(LABEL, "%{public}s loop is null", __func__);
128         return;
129     }
130 
131     uv_work_t *work = new(std::nothrow) uv_work_t;
132     if (work == nullptr) {
133         HiLog::Error(LABEL, "%{public}s work is null", __func__);
134         return;
135     }
136 
137     work->data = reinterpret_cast<void *>(asyncCallbackInfo);
138     uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
139         AsyncCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(work->data);
140         if (asyncCallbackInfo == nullptr) {
141             HiLog::Error(LABEL, "%{public}s asyncCallbackInfo is null", __func__);
142             return;
143         }
144         napi_env env = asyncCallbackInfo->env;
145         napi_value undefined;
146         napi_get_undefined(env, &undefined);
147         if (asyncCallbackInfo->callback[0] == nullptr) {
148             HiLog::Error(LABEL, "%{public}s callback is null", __func__);
149             return;
150         }
151         napi_value callback;
152         napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback);
153         napi_value callResult = nullptr;
154         napi_value result;
155 
156         int32_t sensorTypeId = asyncCallbackInfo->sensorTypeId;
157         if (g_sensorAttributeList.count(sensorTypeId) == 0) {
158             HiLog::Error(LABEL, "%{public}s count of sensorTypeId is zero", __func__);
159             return;
160         }
161 
162         std::vector<std::string> sensorAttribute = g_sensorAttributeList[sensorTypeId];
163         napi_create_object(env, &result);
164         for (size_t i = 0; i < sensorAttribute.size(); i++) {
165             napi_value message = nullptr;
166             napi_create_array(env, &message);
167             for (size_t j = 0; j < asyncCallbackInfo->sensorDataLength; j++) {
168                 napi_value num;
169                 napi_create_uint32(env, asyncCallbackInfo->sensorData[j], &num);
170                 napi_set_element(env, message, j, num);
171             }
172             napi_set_named_property(env, result, sensorAttribute[i].c_str(), message);
173         }
174 
175         napi_call_function(env, undefined, callback, 1, &result, &callResult);
176 
177         delete work;
178         work = nullptr;
179     }, uv_qos_default);
180 }
181 } // namespace Sensors
182 } // namespace OHOS