1 /*
2  * Copyright (C) 2022 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 "location_napi_system.h"
17 
18 #include "locator_callback_napi.h"
19 #include "location_log.h"
20 #include "locator.h"
21 #include "napi_util.h"
22 
23 namespace OHOS {
24 namespace Location {
25 sptr<LocatorCallbackNapi> g_systemSingleLocatorCallbackHost =
26     sptr<LocatorCallbackNapi>(new (std::nothrow)LocatorCallbackNapi());
27 sptr<LocatorCallbackNapi> g_systemSubcribeCallbackHost =
28     sptr<LocatorCallbackNapi>(new (std::nothrow)LocatorCallbackNapi());
29 auto g_locatorImpl = Locator::GetInstance();
30 
GetLocationOnce(const napi_env & env,const napi_ref & successHandlerRef,const napi_ref & failHandlerRef,const napi_ref & completeHandlerRef,int fixNumber)31 napi_value GetLocationOnce(const napi_env& env,
32                            const napi_ref& successHandlerRef,
33                            const napi_ref& failHandlerRef,
34                            const napi_ref& completeHandlerRef,
35                            int fixNumber)
36 {
37     NAPI_ASSERT(env, g_locatorImpl != nullptr, "get locator SA failed");
38     auto requestConfig = std::make_unique<RequestConfig>();
39     auto locatorCallback = sptr<ILocatorCallback>(g_systemSingleLocatorCallbackHost);
40     requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX);
41     requestConfig->SetFixNumber(fixNumber);
42     if (g_systemSingleLocatorCallbackHost->GetSuccHandleCb() != nullptr ||
43         g_systemSingleLocatorCallbackHost->GetFailHandleCb() != nullptr ||
44         g_systemSingleLocatorCallbackHost->GetCompleteHandleCb() != nullptr) {
45         LBSLOGI(LOCATION_NAPI, "handlers is not nullptr, stop locating first");
46         g_locatorImpl->StopLocating(locatorCallback);
47         if (env == g_systemSingleLocatorCallbackHost->GetEnv()) {
48             g_systemSingleLocatorCallbackHost->DeleteAllCallbacks();
49         }
50     }
51     g_systemSingleLocatorCallbackHost->SetEnv(env);
52     g_systemSingleLocatorCallbackHost->SetFixNumber(fixNumber);
53     g_systemSingleLocatorCallbackHost->SetSuccHandleCb(successHandlerRef);
54     g_systemSingleLocatorCallbackHost->SetFailHandleCb(failHandlerRef);
55     g_systemSingleLocatorCallbackHost->SetCompleteHandleCb(completeHandlerRef);
56     g_locatorImpl->StartLocating(requestConfig, locatorCallback);
57     return UndefinedNapiValue(env);
58 }
59 
GetAllCallback(const napi_env & env,const napi_value & argv,napi_ref & successHandlerRef,napi_ref & failHandlerRef,napi_ref & completeHandlerRef)60 void GetAllCallback(const napi_env &env, const napi_value &argv, napi_ref &successHandlerRef,
61     napi_ref &failHandlerRef, napi_ref &completeHandlerRef)
62 {
63     bool hasProperty = false;
64     napi_value nVsuccessCallback = nullptr;
65     napi_value nVfailCallback = nullptr;
66     napi_value nVcompleteCallback = nullptr;
67     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, argv, "success", &hasProperty));
68     if (hasProperty) {
69         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "success", &nVsuccessCallback));
70         NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, nVsuccessCallback, 1, &successHandlerRef));
71     }
72     hasProperty = false;
73     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, argv, "fail", &hasProperty));
74     if (hasProperty) {
75         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "fail", &nVfailCallback));
76         NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, nVfailCallback, 1, &failHandlerRef));
77     }
78     hasProperty = false;
79     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, argv, "complete", &hasProperty));
80     if (hasProperty) {
81         NAPI_CALL_RETURN_VOID(env, napi_get_named_property(env, argv, "complete", &nVcompleteCallback));
82         NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, nVcompleteCallback, 1, &completeHandlerRef));
83     }
84 }
85 
GetLocation(napi_env env,napi_callback_info cbinfo)86 napi_value GetLocation(napi_env env, napi_callback_info cbinfo)
87 {
88     size_t argc = MAXIMUM_JS_PARAMS;
89     napi_value argv[MAXIMUM_JS_PARAMS] = {0};
90     napi_value thisVar = nullptr;
91     napi_value result = nullptr;
92     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
93     napi_valuetype valueType = napi_undefined;
94     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
95     NAPI_ASSERT(env, argc == 1, "number of parameters is error");
96     NAPI_ASSERT(env, valueType == napi_object, "type of parameters is error");
97     NAPI_ASSERT(env, g_locatorImpl != nullptr, "get locator SA failed");
98     napi_value nVtimeout;
99     napi_value nVcoordType;
100     int32_t timeout = 0;
101     napi_ref successHandlerRef = nullptr;
102     napi_ref failHandlerRef = nullptr;
103     napi_ref completeHandlerRef = nullptr;
104     bool hasProperty = false;
105     NAPI_CALL(env, napi_has_named_property(env, argv[0], "timeout", &hasProperty));
106     if (hasProperty) {
107         NAPI_CALL(env, napi_get_named_property(env, argv[0], "timeout", &nVtimeout));
108         NAPI_CALL(env, napi_get_value_int32(env, nVtimeout, &timeout));
109     }
110     hasProperty = false;
111     NAPI_CALL(env, napi_has_named_property(env, argv[0], "coordType", &hasProperty));
112     if (hasProperty) {
113         NAPI_CALL(env, napi_get_named_property(env, argv[0], "coordType", &nVcoordType));
114         char type[64] = {0};
115         size_t typeLen = 0;
116         NAPI_CALL(env, napi_get_value_string_utf8(env, nVcoordType, type, sizeof(type), &typeLen));
117         std::string coordType = type;
118         if (coordType != "wgs84") {
119             NAPI_CALL(env, napi_get_undefined(env, &result));
120             return result;
121         }
122     }
123     GetAllCallback(env, argv[0], successHandlerRef, failHandlerRef, completeHandlerRef);
124     int fixnumber = 1;
125     GetLocationOnce(env, successHandlerRef, failHandlerRef, completeHandlerRef, fixnumber);
126     NAPI_CALL(env, napi_get_undefined(env, &result));
127     return result;
128 }
129 
EmitSyncCallbackWork(const napi_env & env,const napi_value & successHandler,const napi_value & failHandler,const napi_value & completeHandler)130 bool EmitSyncCallbackWork(const napi_env& env,
131                           const napi_value& successHandler,
132                           const napi_value& failHandler,
133                           const napi_value& completeHandler)
134 {
135     napi_value jsEvent = nullptr;
136     napi_value arrString = nullptr;
137     napi_value value;
138     int arrIndex = 0;
139     NAPI_CALL_BASE(env, napi_create_array(env, &arrString), false);
140     NAPI_CALL_BASE(env, napi_create_string_utf8(env, "gps", NAPI_AUTO_LENGTH, &value), false);
141     NAPI_CALL_BASE(env, napi_set_element(env, arrString, arrIndex, value), false);
142     arrIndex++;
143     NAPI_CALL_BASE(env, napi_create_string_utf8(env, "network", NAPI_AUTO_LENGTH, &value), false);
144     NAPI_CALL_BASE(env, napi_set_element(env, arrString, arrIndex, value), false);
145     NAPI_CALL_BASE(env, napi_create_object(env, &jsEvent), false);
146     NAPI_CALL_BASE(env, napi_set_named_property(env, jsEvent, "types", arrString), false);
147     napi_value undefine;
148     NAPI_CALL_BASE(env, napi_get_undefined(env, &undefine), false);
149     NAPI_CALL_BASE(env, napi_call_function(env, nullptr, successHandler, 1, &jsEvent, &undefine), false);
150     return true;
151 }
152 
GetLocationType(napi_env env,napi_callback_info cbinfo)153 napi_value GetLocationType(napi_env env, napi_callback_info cbinfo)
154 {
155     size_t argc = MAXIMUM_JS_PARAMS;
156     napi_value argv[MAXIMUM_JS_PARAMS] = {0};
157     napi_value thisVar = nullptr;
158     napi_value result = nullptr;
159     napi_valuetype valueType = napi_undefined;
160     NAPI_CALL(env,  napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
161     NAPI_ASSERT(env, argc == 1, "number of parameters is error");
162     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
163     NAPI_ASSERT(env, valueType == napi_object, "type of parameters is error");
164     napi_value nVsuccessCallback;
165     napi_value nVfailCallback;
166     napi_value nVcompleteCallback;
167     bool hasProperty = false;
168     NAPI_CALL(env, napi_has_named_property(env, argv[0], "success", &hasProperty));
169     if (hasProperty) {
170         NAPI_CALL(env, napi_get_named_property(env, argv[0], "success", &nVsuccessCallback));
171     }
172     hasProperty = false;
173     NAPI_CALL(env, napi_has_named_property(env, argv[0], "fail", &hasProperty));
174     if (hasProperty) {
175         NAPI_CALL(env, napi_get_named_property(env, argv[0], "fail", &nVfailCallback));
176     }
177     hasProperty = false;
178     NAPI_CALL(env, napi_has_named_property(env, argv[0], "complete", &hasProperty));
179     if (hasProperty) {
180         NAPI_CALL(env, napi_get_named_property(env, argv[0], "complete", &nVcompleteCallback));
181     }
182     EmitSyncCallbackWork(env, nVsuccessCallback, nVfailCallback, nVcompleteCallback);
183     NAPI_CALL(env, napi_get_undefined(env, &result));
184     return result;
185 }
186 
SubscribeSystemLocationChange(napi_env env,napi_ref & successHandlerRef,napi_ref & failHandlerRef,int fixNumber,sptr<LocatorCallbackNapi> & locatorCallbackHost)187 void SubscribeSystemLocationChange(napi_env env,
188                                    napi_ref& successHandlerRef,
189                                    napi_ref& failHandlerRef,
190                                    int fixNumber,
191                                    sptr<LocatorCallbackNapi>& locatorCallbackHost)
192 {
193     auto locatorCallback = sptr<ILocatorCallback>(locatorCallbackHost);
194     if (locatorCallbackHost->GetSuccHandleCb() != nullptr ||
195         locatorCallbackHost->GetFailHandleCb() != nullptr) {
196         LBSLOGI(LOCATION_NAPI, "GetHandlerCb() != nullptr, UnSubscribeLocationChange");
197         g_locatorImpl->StopLocating(locatorCallback);
198         if (env == locatorCallbackHost->GetEnv()) {
199             locatorCallbackHost->DeleteAllCallbacks();
200         }
201     }
202     locatorCallbackHost->SetEnv(env);
203     locatorCallbackHost->SetFixNumber(fixNumber);
204     locatorCallbackHost->SetSuccHandleCb(successHandlerRef);
205     locatorCallbackHost->SetFailHandleCb(failHandlerRef);
206     std::unique_ptr<RequestConfig> requestConfig = std::make_unique<RequestConfig>();
207     requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX);
208     requestConfig->SetFixNumber(fixNumber);
209     g_locatorImpl->StartLocating(requestConfig, locatorCallback);
210 }
211 
Subscribe(napi_env env,napi_callback_info cbinfo)212 napi_value Subscribe(napi_env env, napi_callback_info cbinfo)
213 {
214     size_t argc = MAXIMUM_JS_PARAMS;
215     napi_value argv[MAXIMUM_JS_PARAMS] = {0};
216     napi_value thisVar = nullptr;
217     napi_value result = nullptr;
218     napi_value nVcoordType;
219     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
220     napi_valuetype valueType = napi_undefined;
221     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
222     NAPI_ASSERT(env, argc == 1, "number of parameters is error");
223     NAPI_ASSERT(env, valueType == napi_object, "type of parameters is error");
224     NAPI_ASSERT(env, g_locatorImpl != nullptr, "get locator SA failed");
225     napi_ref successHandlerRef = nullptr;
226     napi_ref failHandlerRef = nullptr;
227     napi_ref completeHandlerRef = nullptr;
228     bool hasProperty = false;
229     NAPI_CALL(env, napi_has_named_property(env, argv[0], "coordType", &hasProperty));
230     if (hasProperty) {
231         NAPI_CALL(env, napi_get_named_property(env, argv[0], "coordType", &nVcoordType));
232         char type[64] = {0};
233         size_t typeLen = 0;
234         NAPI_CALL(env, napi_get_value_string_utf8(env, nVcoordType, type, sizeof(type), &typeLen));
235         std::string coordType = type;
236         if (coordType != "wgs84") {
237             NAPI_CALL(env, napi_get_undefined(env, &result));
238             return result;
239         }
240     }
241     GetAllCallback(env, argv[0], successHandlerRef, failHandlerRef, completeHandlerRef);
242     SubscribeSystemLocationChange(env, successHandlerRef, failHandlerRef, 0, g_systemSubcribeCallbackHost);
243     NAPI_CALL(env, napi_get_undefined(env, &result));
244     return result;
245 }
246 
Unsubscribe(napi_env env,napi_callback_info cbinfo)247 napi_value Unsubscribe(napi_env env, napi_callback_info cbinfo)
248 {
249     NAPI_ASSERT(env, g_locatorImpl != nullptr, "get locator SA failed");
250     napi_value result = nullptr;
251     auto locatorCallback = sptr<ILocatorCallback>(g_systemSubcribeCallbackHost);
252     g_locatorImpl->StopLocating(locatorCallback);
253     if (env == g_systemSubcribeCallbackHost->GetEnv()) {
254         g_systemSubcribeCallbackHost->DeleteAllCallbacks();
255     }
256     NAPI_CALL(env, napi_get_undefined(env, &result));
257     return result;
258 }
259 
GetSupportedCoordTypes(napi_env env,napi_callback_info cbinfo)260 napi_value GetSupportedCoordTypes(napi_env env, napi_callback_info cbinfo)
261 {
262     size_t argc = MAXIMUM_JS_PARAMS;
263     napi_value argv[MAXIMUM_JS_PARAMS] = {0};
264     napi_value thisVar = nullptr;
265     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
266     NAPI_ASSERT(env, argc == 0, "number of parameters is error");
267     napi_value arrString = nullptr;
268     napi_value value;
269     int arrIndex = 0;
270     NAPI_CALL(env, napi_create_array(env, &arrString));
271     NAPI_CALL(env, napi_create_string_utf8(env, "wgs84", NAPI_AUTO_LENGTH, &value));
272     NAPI_CALL(env, napi_set_element(env, arrString, arrIndex, value));
273     return arrString;
274 }
275 }  // namespace Location
276 }  // namespace OHOS
277