• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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<std::shared_ptr<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<std::shared_ptr<OHOS::Notification::NotificationRequest>> & notificationRequestList)80 void JsObjToNotificationRequestList(const napi_env& env, const napi_value& object,
81     std::vector<std::shared_ptr<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<std::shared_ptr<OHOS::Notification::NotificationRequest>> & notificationRequestList)87 void GetNotificationRequestArray(const napi_env& env, const napi_value& notificationRequestValue,
88     std::vector<std::shared_ptr<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         std::shared_ptr<OHOS::Notification::NotificationRequest> notificationRequest =
112             std::make_shared<OHOS::Notification::NotificationRequest>();
113         GenNotificationRequest(env, elementValue, notificationRequest);
114         notificationRequestList.push_back(notificationRequest);
115     }
116 }
117 
GenNotificationRequest(const napi_env & env,const napi_value & elementValue,std::shared_ptr<OHOS::Notification::NotificationRequest> & notificationRequest)118 void GenNotificationRequest(const napi_env& env, const napi_value& elementValue,
119     std::shared_ptr<OHOS::Notification::NotificationRequest>& notificationRequest)
120 {
121     napi_valuetype elementValueType;
122     NAPI_CALL_RETURN_VOID(env, napi_typeof(env, elementValue, &elementValueType));
123     if (elementValueType != napi_object) {
124         LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
125         return;
126     }
127     // argv[0] : NotificationRequest
128     NotificationNapi::GetNotificationRequest(env, elementValue, *notificationRequest);
129 }
130 #endif
131 
JsObjToGeofenceTransitionEventList(const napi_env & env,const napi_value & object,std::vector<GeofenceTransitionEvent> & geofenceTransitionStatusList)132 void JsObjToGeofenceTransitionEventList(const napi_env& env, const napi_value& object,
133     std::vector<GeofenceTransitionEvent>& geofenceTransitionStatusList)
134 {
135     napi_value monitorTransitionEvents = GetArrayProperty(env, object, "monitorTransitionEvents");
136     GetGeofenceTransitionEventArray(env, monitorTransitionEvents, geofenceTransitionStatusList);
137 }
138 
GetGeofenceTransitionEventArray(const napi_env & env,const napi_value & monitorTransitionEvents,std::vector<GeofenceTransitionEvent> & geofenceTransitionStatusList)139 void GetGeofenceTransitionEventArray(const napi_env& env, const napi_value& monitorTransitionEvents,
140     std::vector<GeofenceTransitionEvent>& geofenceTransitionStatusList)
141 {
142     napi_valuetype valueType;
143     NAPI_CALL_RETURN_VOID(env, napi_typeof(env, monitorTransitionEvents, &valueType));
144     if (valueType != napi_object) {
145         LBSLOGE(NAPI_UTILS, "Wrong argument type, value should be object");
146         return;
147     }
148     uint32_t arrayLength = 0;
149     NAPI_CALL_RETURN_VOID(env, napi_get_array_length(env, monitorTransitionEvents, &arrayLength));
150     if (arrayLength == 0 || arrayLength > MAX_TRANSITION_ARRAY_SIZE) {
151         LBSLOGE(NAPI_UTILS, "The array is empty or out of range.");
152         return;
153     }
154     for (uint32_t i = 0; i < arrayLength; i++) {
155         napi_value elementValue = nullptr;
156         NAPI_CALL_RETURN_VOID(env, napi_get_element(env, monitorTransitionEvents, i, &elementValue));
157         napi_valuetype napiType;
158         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, elementValue, &napiType));
159         if (napiType != napi_number) {
160             LBSLOGE(NAPI_UTILS, "Wrong argument type.");
161             break;
162         }
163         int geofenceTransitionStatus = -1;
164         NAPI_CALL_RETURN_VOID(env, napi_get_value_int32(env, elementValue, &geofenceTransitionStatus));
165         geofenceTransitionStatusList.push_back(static_cast<GeofenceTransitionEvent>(geofenceTransitionStatus));
166     }
167 }
168 
CheckGeofenceParameter(const GeoFence & fenceInfo)169 static bool CheckGeofenceParameter(const GeoFence& fenceInfo)
170 {
171     if (fenceInfo.latitude > MAX_LATITUDE || fenceInfo.latitude < MIN_LATITUDE) {
172         LBSLOGE(LOCATOR_STANDARD, "latitude error.");
173         return false;
174     }
175     if (fenceInfo.longitude > MAX_LONGITUDE || fenceInfo.longitude < MIN_LONGITUDE) {
176         LBSLOGE(LOCATOR_STANDARD, "longitude error.");
177         return false;
178     }
179     if (!(fenceInfo.radius > 0)) {
180         LBSLOGE(LOCATOR_STANDARD, "radius error.");
181         return false;
182     }
183     if (!(fenceInfo.expiration > 0)) {
184         LBSLOGE(LOCATOR_STANDARD, "expiration error.");
185         return false;
186     }
187     return true;
188 }
189 
JsObjToGeoFenceRequest(const napi_env & env,const napi_value & object,const std::shared_ptr<GeofenceRequest> & request)190 bool JsObjToGeoFenceRequest(const napi_env& env, const napi_value& object,
191     const std::shared_ptr<GeofenceRequest>& request)
192 {
193     int value = 0;
194     if (JsObjectToInt(env, object, "scenario", value) == SUCCESS) {
195         request->SetScenario(value);
196     }
197     napi_value geofenceValue = GetNapiValueByKey(env, "geofence", object);
198     if (geofenceValue == nullptr) {
199         LBSLOGE(LOCATOR_STANDARD, "parse geofence failed");
200         return false;
201     }
202     GeoFence geofence = {0};
203     if (JsObjectToDouble(env, geofenceValue, "latitude", geofence.latitude) != SUCCESS) {
204         LBSLOGE(LOCATOR_STANDARD, "parse latitude failed");
205         return false;
206     }
207     if (JsObjectToDouble(env, geofenceValue, "longitude", geofence.longitude) != SUCCESS) {
208         LBSLOGE(LOCATOR_STANDARD, "parse longitude failed");
209         return false;
210     }
211     if (JsObjectToInt(env, geofenceValue, "coordinateSystemType", value) == SUCCESS) {
212         geofence.coordinateSystemType = static_cast<CoordinateSystemType>(value);
213     } else {
214         geofence.coordinateSystemType = CoordinateSystemType::WGS84;
215     }
216     if (JsObjectToDouble(env, geofenceValue, "radius", geofence.radius) != SUCCESS) {
217         LBSLOGE(LOCATOR_STANDARD, "parse radius failed");
218         return false;
219     }
220     if (JsObjectToDouble(env, geofenceValue, "expiration", geofence.expiration) != SUCCESS) {
221         LBSLOGE(LOCATOR_STANDARD, "parse expiration failed");
222         return false;
223     }
224     bool isValidParameter = CheckGeofenceParameter(geofence);
225     if (!isValidParameter) {
226         return false;
227     }
228     request->SetGeofence(geofence);
229     return true;
230 }
231 
GeofenceTransitionToJs(const napi_env & env,const GeofenceTransition geofenceTransition,napi_value & result)232 void GeofenceTransitionToJs(const napi_env& env,
233     const GeofenceTransition geofenceTransition, napi_value& result)
234 {
235     SetValueInt32(env, "geofenceId", geofenceTransition.fenceId, result);
236     SetValueInt32(env, "transitionEvent", static_cast<int>(geofenceTransition.event), result);
237     if (geofenceTransition.beaconFence != nullptr) {
238         napi_value beaconFenceJsObj = CreateBeaconFenceJsObj(env, geofenceTransition.beaconFence);
239         SetValueBeacon(env, "beaconFence", beaconFenceJsObj, result);
240     }
241 }
242 
CreateBeaconFenceJsObj(const napi_env & env,const std::shared_ptr<BeaconFence> & beaconFence)243 napi_value CreateBeaconFenceJsObj(const napi_env& env, const std::shared_ptr<BeaconFence>& beaconFence)
244 {
245     napi_value beaconFenceObject = nullptr;
246     NAPI_CALL(env, napi_create_object(env, &beaconFenceObject));
247     SetValueUtf8String(env, "identifier",
248         beaconFence->GetIdentifier().c_str(), beaconFenceObject);
249     SetValueInt32(env, "beaconFenceInfoType",
250         static_cast<int>(beaconFence->GetBeaconFenceInfoType()), beaconFenceObject);
251 
252     napi_value manufactureDataObject = nullptr;
253     NAPI_CALL(env, napi_create_object(env, &manufactureDataObject));
254     SetValueInt32(env, "manufactureId",
255         beaconFence->GetBeaconManufactureData().manufactureId, manufactureDataObject);
256     SetValueArrayBuffer(env, "manufactureData",
257         beaconFence->GetBeaconManufactureData().manufactureData, manufactureDataObject);
258     SetValueArrayBuffer(env, "manufactureDataMask",
259         beaconFence->GetBeaconManufactureData().manufactureDataMask, manufactureDataObject);
260     SetValueBeacon(env, "manufactureData",
261         manufactureDataObject, beaconFenceObject);
262     return beaconFenceObject;
263 }
264 
SetValueBeacon(const napi_env & env,const char * fieldStr,napi_value & value,napi_value & result)265 napi_status SetValueBeacon(const napi_env& env, const char* fieldStr, napi_value& value, napi_value& result)
266 {
267     NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
268     return napi_ok;
269 }
270 }  // namespace Location
271 }  // namespace OHOS
272