1 /*
2 * Copyright (C) 2024 Huawei Device Co., 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 "napi_util.h"
17 #include "securec.h"
18 #include "string_ex.h"
19 #include "common_utils.h"
20 #include "location_log.h"
21 #ifdef NOTIFICATION_ENABLE
22 #include "notification_request.h"
23 #include "notification.h"
24 #include "notification_napi.h"
25 #endif
26 #include "geofence_definition.h"
27 #include "geofence_napi.h"
28
29 namespace OHOS {
30 namespace Location {
31 const int MAX_TRANSITION_ARRAY_SIZE = 3;
32
ParseGnssGeofenceRequest(const napi_env & env,const napi_value & value,std::shared_ptr<GeofenceRequest> & request)33 bool ParseGnssGeofenceRequest(
34 const napi_env& env, const napi_value& value, std::shared_ptr<GeofenceRequest>& request)
35 {
36 napi_valuetype valueType;
37 NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
38 if (valueType != napi_object) {
39 LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
40 return false;
41 }
42 return GenGnssGeofenceRequest(env, value, request);
43 }
44
GenGnssGeofenceRequest(const napi_env & env,const napi_value & value,std::shared_ptr<GeofenceRequest> & geofenceRequest)45 bool GenGnssGeofenceRequest(
46 const napi_env& env, const napi_value& value, std::shared_ptr<GeofenceRequest>& geofenceRequest)
47 {
48 if (geofenceRequest == nullptr) {
49 LBSLOGE(NAPI_UTILS, "geofenceRequest == nullptr");
50 return false;
51 }
52 bool isValidParameter = JsObjToGeoFenceRequest(env, value, geofenceRequest);
53 if (!isValidParameter) {
54 return false;
55 }
56 std::vector<GeofenceTransitionEvent> geofenceTransitionStatusList;
57 JsObjToGeofenceTransitionEventList(env, value, geofenceTransitionStatusList);
58 geofenceRequest->SetGeofenceTransitionEventList(geofenceTransitionStatusList);
59 #ifdef NOTIFICATION_ENABLE
60 std::vector<OHOS::Notification::NotificationRequest> notificationRequestList;
61 JsObjToNotificationRequestList(env, value, notificationRequestList);
62 geofenceRequest->SetNotificationRequestList(notificationRequestList);
63 #endif
64 return true;
65 }
66
JsObjToGeofenceTransitionCallback(const napi_env & env,const napi_value & object,sptr<LocationGnssGeofenceCallbackNapi> callbackHost)67 void JsObjToGeofenceTransitionCallback(const napi_env& env, const napi_value& object,
68 sptr<LocationGnssGeofenceCallbackNapi> callbackHost)
69 {
70 napi_ref handlerRef = nullptr;
71 napi_value callbackNapiValue = nullptr;
72 NAPI_CALL_RETURN_VOID(env,
73 napi_get_named_property(env, object, "geofenceTransitionCallback", &callbackNapiValue));
74 NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, callbackNapiValue, 1, &handlerRef));
75 callbackHost->SetEnv(env);
76 callbackHost->SetHandleCb(handlerRef);
77 }
78
79 #ifdef NOTIFICATION_ENABLE
JsObjToNotificationRequestList(const napi_env & env,const napi_value & object,std::vector<OHOS::Notification::NotificationRequest> & notificationRequestList)80 void JsObjToNotificationRequestList(const napi_env& env, const napi_value& object,
81 std::vector<OHOS::Notification::NotificationRequest>& notificationRequestList)
82 {
83 napi_value notificationRequest = GetArrayProperty(env, object, "notifications");
84 GetNotificationRequestArray(env, notificationRequest, notificationRequestList);
85 }
86
GetNotificationRequestArray(const napi_env & env,const napi_value & notificationRequestValue,std::vector<OHOS::Notification::NotificationRequest> & notificationRequestList)87 void GetNotificationRequestArray(const napi_env& env, const napi_value& notificationRequestValue,
88 std::vector<OHOS::Notification::NotificationRequest>& notificationRequestList)
89 {
90 napi_valuetype valueType;
91 NAPI_CALL_RETURN_VOID(env, napi_typeof(env, notificationRequestValue, &valueType));
92 if (valueType != napi_object) {
93 LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
94 return;
95 }
96 uint32_t arrayLength = 0;
97 NAPI_CALL_RETURN_VOID(env, napi_get_array_length(env, notificationRequestValue, &arrayLength));
98 if (arrayLength == 0 || arrayLength > MAX_TRANSITION_ARRAY_SIZE) {
99 LBSLOGE(NAPI_UTILS, "The array is empty or out of range.");
100 return;
101 }
102 for (uint32_t i = 0; i < arrayLength; i++) {
103 napi_value elementValue = nullptr;
104 NAPI_CALL_RETURN_VOID(env, napi_get_element(env, notificationRequestValue, i, &elementValue));
105 napi_valuetype napiType;
106 NAPI_CALL_RETURN_VOID(env, napi_typeof(env, elementValue, &napiType));
107 if (napiType != napi_object) {
108 LBSLOGE(NAPI_UTILS, "Wrong argument type.");
109 break;
110 }
111 OHOS::Notification::NotificationRequest notificationRequest;
112 GenNotificationRequest(env, elementValue, notificationRequest);
113 notificationRequestList.push_back(notificationRequest);
114 }
115 }
116
GenNotificationRequest(const napi_env & env,const napi_value & elementValue,OHOS::Notification::NotificationRequest & notificationRequest)117 void GenNotificationRequest(const napi_env& env, const napi_value& elementValue,
118 OHOS::Notification::NotificationRequest& notificationRequest)
119 {
120 napi_valuetype elementValueType;
121 NAPI_CALL_RETURN_VOID(env, napi_typeof(env, elementValue, &elementValueType));
122 if (elementValueType != napi_object) {
123 LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
124 return;
125 }
126 // argv[0] : NotificationRequest
127 NotificationNapi::GetNotificationRequest(env, elementValue, notificationRequest);
128 }
129 #endif
130
JsObjToGeofenceTransitionEventList(const napi_env & env,const napi_value & object,std::vector<GeofenceTransitionEvent> & geofenceTransitionStatusList)131 void JsObjToGeofenceTransitionEventList(const napi_env& env, const napi_value& object,
132 std::vector<GeofenceTransitionEvent>& geofenceTransitionStatusList)
133 {
134 napi_value monitorTransitionEvents = GetArrayProperty(env, object, "monitorTransitionEvents");
135 GetGeofenceTransitionEventArray(env, monitorTransitionEvents, geofenceTransitionStatusList);
136 }
137
GetGeofenceTransitionEventArray(const napi_env & env,const napi_value & monitorTransitionEvents,std::vector<GeofenceTransitionEvent> & geofenceTransitionStatusList)138 void GetGeofenceTransitionEventArray(const napi_env& env, const napi_value& monitorTransitionEvents,
139 std::vector<GeofenceTransitionEvent>& geofenceTransitionStatusList)
140 {
141 napi_valuetype valueType;
142 NAPI_CALL_RETURN_VOID(env, napi_typeof(env, monitorTransitionEvents, &valueType));
143 if (valueType != napi_object) {
144 LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
145 return;
146 }
147 uint32_t arrayLength = 0;
148 NAPI_CALL_RETURN_VOID(env, napi_get_array_length(env, monitorTransitionEvents, &arrayLength));
149 if (arrayLength == 0 || arrayLength > MAX_TRANSITION_ARRAY_SIZE) {
150 LBSLOGE(NAPI_UTILS, "The array is empty or out of range.");
151 return;
152 }
153 for (uint32_t i = 0; i < arrayLength; i++) {
154 napi_value elementValue = nullptr;
155 NAPI_CALL_RETURN_VOID(env, napi_get_element(env, monitorTransitionEvents, i, &elementValue));
156 napi_valuetype napiType;
157 NAPI_CALL_RETURN_VOID(env, napi_typeof(env, elementValue, &napiType));
158 if (napiType != napi_number) {
159 LBSLOGE(NAPI_UTILS, "Wrong argument type.");
160 break;
161 }
162 int geofenceTransitionStatus = -1;
163 NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, elementValue, &geofenceTransitionStatus));
164 geofenceTransitionStatusList.push_back(static_cast<GeofenceTransitionEvent>(geofenceTransitionStatus));
165 }
166 }
167
CheckGeofenceParameter(const GeoFence & fenceInfo)168 static bool CheckGeofenceParameter(const GeoFence& fenceInfo)
169 {
170 if (fenceInfo.latitude > MAX_LATITUDE || fenceInfo.latitude < MIN_LATITUDE) {
171 LBSLOGE(LOCATOR_STANDARD, "latitude error.");
172 return false;
173 }
174 if (fenceInfo.longitude > MAX_LONGITUDE || fenceInfo.longitude < MIN_LONGITUDE) {
175 LBSLOGE(LOCATOR_STANDARD, "longitude error.");
176 return false;
177 }
178 if (!(fenceInfo.radius > 0)) {
179 LBSLOGE(LOCATOR_STANDARD, "radius error.");
180 return false;
181 }
182 if (!(fenceInfo.expiration > 0)) {
183 LBSLOGE(LOCATOR_STANDARD, "expiration error.");
184 return false;
185 }
186 return true;
187 }
188
JsObjToGeoFenceRequest(const napi_env & env,const napi_value & object,const std::shared_ptr<GeofenceRequest> & request)189 bool JsObjToGeoFenceRequest(const napi_env& env, const napi_value& object,
190 const std::shared_ptr<GeofenceRequest>& request)
191 {
192 int value = 0;
193 if (JsObjectToInt(env, object, "scenario", value) == SUCCESS) {
194 request->SetScenario(value);
195 }
196 napi_value geofenceValue = GetNapiValueByKey(env, "geofence", object);
197 if (geofenceValue == nullptr) {
198 LBSLOGE(LOCATOR_STANDARD, "parse geofence failed");
199 return false;
200 }
201 GeoFence geofence = {0};
202 if (JsObjectToDouble(env, geofenceValue, "latitude", geofence.latitude) != SUCCESS) {
203 LBSLOGE(LOCATOR_STANDARD, "parse latitude failed");
204 return false;
205 }
206 if (JsObjectToDouble(env, geofenceValue, "longitude", geofence.longitude) != SUCCESS) {
207 LBSLOGE(LOCATOR_STANDARD, "parse longitude failed");
208 return false;
209 }
210 if (JsObjectToInt(env, geofenceValue, "coordinateSystemType", value) == SUCCESS) {
211 geofence.coordinateSystemType = static_cast<CoordinateSystemType>(value);
212 } else {
213 geofence.coordinateSystemType = CoordinateSystemType::WGS84;
214 }
215 if (JsObjectToDouble(env, geofenceValue, "radius", geofence.radius) != SUCCESS) {
216 LBSLOGE(LOCATOR_STANDARD, "parse radius failed");
217 return false;
218 }
219 if (JsObjectToDouble(env, geofenceValue, "expiration", geofence.expiration) != SUCCESS) {
220 LBSLOGE(LOCATOR_STANDARD, "parse expiration failed");
221 return false;
222 }
223 bool isValidParameter = CheckGeofenceParameter(geofence);
224 if (!isValidParameter) {
225 return false;
226 }
227 request->SetGeofence(geofence);
228 return true;
229 }
230
GeofenceTransitionToJs(const napi_env & env,const GeofenceTransition geofenceTransition,napi_value & result)231 void GeofenceTransitionToJs(const napi_env& env,
232 const GeofenceTransition geofenceTransition, napi_value& result)
233 {
234 SetValueInt32(env, "geofenceId", geofenceTransition.fenceId, result);
235 SetValueInt32(env, "transitionEvent", static_cast<int>(geofenceTransition.event), result);
236 }
237 } // namespace Location
238 } // namespace OHOS
239