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 "napi_geolocation_permission.h"
17 
18 #include <cstdint>
19 #include <vector>
20 
21 #include "business_error.h"
22 #include "napi/native_common.h"
23 #include "nweb_data_base.h"
24 #include "nweb_helper.h"
25 #include "web_errors.h"
26 #include "securec.h"
27 
28 namespace {
29 constexpr int32_t PARAMZERO = 0;
30 constexpr int32_t PARAMONE = 1;
31 constexpr int32_t PARAMTWO = 2;
32 constexpr int32_t PARAMTHREE = 3;
33 constexpr int32_t RESULT_COUNT = 2;
34 constexpr int32_t INTERFACE_OK = 0;
35 constexpr int32_t INTERFACE_ERROR = -1;
36 constexpr int32_t ALLOW_PERMISSION_OPERATION = 1;
37 constexpr int32_t DELETE_PERMISSION_OPERATION = 2;
38 
39 struct GetPermissionOriginsParam {
40     std::vector<std::string> origins;
41     napi_env env;
42     napi_async_work asyncWork;
43     napi_deferred deferred;
44     napi_ref callbackRef;
45     napi_status status;
46     int errCode;
47     bool incognitoMode;
48 };
49 
50 struct GetOriginPermissionStateParam {
51     bool retValue;
52     bool incognitoMode;
53     std::string origin;
54     napi_env env;
55     napi_async_work asyncWork;
56     napi_deferred deferred;
57     napi_ref jsStringRef;
58     napi_ref callbackRef;
59     napi_status status;
60     int errCode;
61 };
62 } // namespace
63 
64 namespace OHOS {
65 namespace NWeb {
Init(napi_env env,napi_value exports)66 napi_value NapiGeolocationPermission::Init(napi_env env, napi_value exports)
67 {
68     const std::string GEOLOCATION_PERMISSION_CLASS_NAME = "GeolocationPermissions";
69     napi_property_descriptor properties[] = {
70         DECLARE_NAPI_STATIC_FUNCTION("allowGeolocation", NapiGeolocationPermission::JsAllowGeolocation),
71         DECLARE_NAPI_STATIC_FUNCTION("deleteGeolocation", NapiGeolocationPermission::JsDeleteGeolocation),
72         DECLARE_NAPI_STATIC_FUNCTION("deleteAllGeolocation", NapiGeolocationPermission::JsDeleteAllGeolocation),
73         DECLARE_NAPI_STATIC_FUNCTION("getStoredGeolocation", NapiGeolocationPermission::JsGetStoredGeolocation),
74         DECLARE_NAPI_STATIC_FUNCTION("getAccessibleGeolocation",
75             NapiGeolocationPermission::JsGetAccessibleGeolocation),
76     };
77     napi_value constructor = nullptr;
78     napi_define_class(env, GEOLOCATION_PERMISSION_CLASS_NAME.c_str(), GEOLOCATION_PERMISSION_CLASS_NAME.length(),
79         JsConstructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &constructor);
80     NAPI_ASSERT(env, constructor != nullptr, "NapiGeolocationPermission define js class failed");
81     napi_status status = napi_set_named_property(env, exports, "GeolocationPermissions", constructor);
82     NAPI_ASSERT(env, status == napi_ok, "NapiGeolocationPermission set property failed");
83     return exports;
84 }
85 
GetStringPara(napi_env env,napi_value argv,std::string & outValue)86 bool NapiGeolocationPermission::GetStringPara(napi_env env, napi_value argv, std::string& outValue)
87 {
88     constexpr int32_t MAX_STRING_LENGTH = 40960;
89     size_t bufferSize = 0;
90     napi_valuetype valueType = napi_null;
91 
92     napi_typeof(env, argv, &valueType);
93     if (valueType != napi_string) {
94         return false;
95     }
96     napi_get_value_string_utf8(env, argv, nullptr, 0, &bufferSize);
97     if (bufferSize > MAX_STRING_LENGTH) {
98         return false;
99     }
100     char stringValue[bufferSize + 1];
101     size_t jsStringLength = 0;
102     napi_get_value_string_utf8(env, argv, stringValue, bufferSize + 1, &jsStringLength);
103     if (jsStringLength != bufferSize) {
104         return false;
105     }
106     outValue = stringValue;
107     return true;
108 }
109 
GetBooleanPara(napi_env env,napi_value argv,bool & outValue)110 bool NapiGeolocationPermission::GetBooleanPara(napi_env env, napi_value argv, bool& outValue)
111 {
112     napi_valuetype valueType = napi_null;
113 
114     napi_typeof(env, argv, &valueType);
115     if (valueType != napi_boolean) {
116         return false;
117     }
118 
119     bool boolValue;
120     napi_get_value_bool(env, argv, &boolValue);
121     outValue = boolValue;
122     return true;
123 }
124 
ProcessActionByType(napi_env env,napi_callback_info info,int32_t operationType)125 napi_value NapiGeolocationPermission::ProcessActionByType(napi_env env, napi_callback_info info,
126     int32_t operationType)
127 {
128     napi_value retValue = nullptr;
129     size_t argc = PARAMTWO;
130     size_t argcForOld = PARAMONE;
131     napi_value argv[PARAMTWO] = { 0 };
132     napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
133     if (argc != PARAMTWO && argc != argcForOld) {
134         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
135             NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "one", "two"));
136         return nullptr;
137     }
138 
139     std::string origin;
140     if (!GetStringPara(env, argv[PARAMZERO], origin)) {
141         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
142             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "origin", "string"));
143         return nullptr;
144     }
145     bool incognitoMode = false;
146     if (argc == PARAMTWO) {
147         napi_get_value_bool(env, argv[PARAMONE], &incognitoMode);
148     }
149 
150     napi_value result = nullptr;
151     napi_get_undefined(env, &result);
152     std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
153     if (!dataBase) {
154         return result;
155     }
156     if (operationType == ALLOW_PERMISSION_OPERATION) {
157         if (dataBase->SetPermissionByOrigin(origin, OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, true,
158             incognitoMode) == NWebError::INVALID_ORIGIN) {
159             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::INVALID_ORIGIN);
160             return result;
161         }
162     } else if (operationType == DELETE_PERMISSION_OPERATION) {
163         if (dataBase->ClearPermissionByOrigin(origin, OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE,
164             incognitoMode) == NWebError::INVALID_ORIGIN) {
165             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::INVALID_ORIGIN);
166             return result;
167         }
168     }
169     return result;
170 }
171 
JsAllowGeolocation(napi_env env,napi_callback_info info)172 napi_value NapiGeolocationPermission::JsAllowGeolocation(napi_env env, napi_callback_info info)
173 {
174     return ProcessActionByType(env, info, ALLOW_PERMISSION_OPERATION);
175 }
176 
JsDeleteGeolocation(napi_env env,napi_callback_info info)177 napi_value NapiGeolocationPermission::JsDeleteGeolocation(napi_env env, napi_callback_info info)
178 {
179     return ProcessActionByType(env, info, DELETE_PERMISSION_OPERATION);
180 }
181 
JsDeleteAllGeolocation(napi_env env,napi_callback_info info)182 napi_value NapiGeolocationPermission::JsDeleteAllGeolocation(napi_env env, napi_callback_info info)
183 {
184     napi_value retValue = nullptr;
185     size_t argc = PARAMONE;
186     size_t argcForOld = 0;
187     napi_value argv[PARAMONE] = { 0 };
188     napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
189     if (argc != PARAMONE && argc != argcForOld) {
190         return nullptr;
191     }
192     bool incognitoMode = false;
193     if (argc == PARAMONE) {
194         napi_get_value_bool(env, argv[PARAMZERO], &incognitoMode);
195     }
196 
197     std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
198     if (dataBase != nullptr) {
199         dataBase->ClearAllPermission(OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, incognitoMode);
200     }
201 
202     napi_value result = nullptr;
203     napi_get_undefined(env, &result);
204     return result;
205 }
206 
GetPermissionStateComplete(napi_env env,napi_status status,void * data)207 void NapiGeolocationPermission::GetPermissionStateComplete(napi_env env, napi_status status, void *data)
208 {
209     GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
210     napi_handle_scope scope = nullptr;
211     napi_open_handle_scope(env, &scope);
212     if (scope == nullptr) {
213         return;
214     }
215     napi_value setResult[RESULT_COUNT] = {0};
216     if (param->status) {
217         setResult[PARAMZERO] = NWebError::BusinessError::CreateError(env, param->errCode);
218         napi_get_undefined(env, &setResult[PARAMONE]);
219     } else {
220         napi_get_undefined(env, &setResult[PARAMZERO]);
221         napi_get_boolean(env, param->retValue, &setResult[PARAMONE]);
222     }
223     napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
224     napi_value callback = nullptr;
225     napi_get_reference_value(env, param->callbackRef, &callback);
226     napi_value returnVal = nullptr;
227     napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &returnVal);
228     napi_delete_reference(env, param->jsStringRef);
229     napi_delete_reference(env, param->callbackRef);
230     napi_delete_async_work(env, param->asyncWork);
231     napi_close_handle_scope(env, scope);
232     delete param;
233     param = nullptr;
234 }
235 
GetPermissionStatePromiseComplete(napi_env env,napi_status status,void * data)236 void NapiGeolocationPermission::GetPermissionStatePromiseComplete(napi_env env, napi_status status, void *data)
237 {
238     GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
239     napi_handle_scope scope = nullptr;
240     napi_open_handle_scope(env, &scope);
241     if (scope == nullptr) {
242         return;
243     }
244     napi_value setResult[RESULT_COUNT] = {0};
245     setResult[PARAMZERO] = NWebError::BusinessError::CreateError(env, param->errCode);
246     napi_get_boolean(env, param->retValue, &setResult[PARAMONE]);
247     napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
248     if (param->status == napi_ok) {
249         napi_resolve_deferred(env, param->deferred, args[1]);
250     } else {
251         napi_reject_deferred(env, param->deferred, args[0]);
252     }
253     napi_delete_reference(env, param->jsStringRef);
254     napi_delete_async_work(env, param->asyncWork);
255     napi_close_handle_scope(env, scope);
256     delete param;
257     param = nullptr;
258 }
259 
ExecuteGetPermissionState(napi_env env,void * data)260 void NapiGeolocationPermission::ExecuteGetPermissionState(napi_env env, void *data)
261 {
262     GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
263     std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
264     if (!dataBase) {
265         param->errCode = INTERFACE_ERROR;
266         param->status = napi_generic_failure;
267         return;
268     }
269     if (dataBase->GetPermissionResultByOrigin(param->origin,
270         OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, param->retValue, param->incognitoMode)) {
271         param->errCode = INTERFACE_OK;
272         param->status = napi_ok;
273     } else {
274         param->errCode = NWebError::INVALID_ORIGIN;
275         param->status = napi_generic_failure;
276     }
277 }
278 
GetPermissionStateAsync(napi_env env,napi_value * argv,const std::string & origin,bool incognitoMode)279 napi_value NapiGeolocationPermission::GetPermissionStateAsync(napi_env env,
280     napi_value *argv, const std::string& origin, bool incognitoMode)
281 {
282     napi_value result = nullptr;
283     napi_value resourceName = nullptr;
284 
285     GetOriginPermissionStateParam *param = new (std::nothrow) GetOriginPermissionStateParam {
286         .retValue = false,
287         .incognitoMode = incognitoMode,
288         .origin = origin,
289         .env = env,
290         .asyncWork = nullptr,
291         .deferred = nullptr,
292         .jsStringRef = nullptr,
293         .callbackRef = nullptr,
294     };
295     if (param == nullptr) {
296         return nullptr;
297     }
298     napi_create_reference(env, argv[0], 1, &param->jsStringRef);
299     napi_create_reference(env, argv[1], 1, &param->callbackRef);
300     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
301     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetPermissionState,
302         GetPermissionStateComplete, static_cast<void *>(param), &param->asyncWork));
303     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
304     napi_get_undefined(env, &result);
305     return result;
306 }
307 
GetPermissionStatePromise(napi_env env,napi_value * argv,const std::string & origin,bool incognitoMode)308 napi_value NapiGeolocationPermission::GetPermissionStatePromise(napi_env env, napi_value *argv,
309     const std::string& origin, bool incognitoMode)
310 {
311     napi_deferred deferred = nullptr;
312     napi_value promise = nullptr;
313     napi_create_promise(env, &deferred, &promise);
314 
315     GetOriginPermissionStateParam *param = new (std::nothrow) GetOriginPermissionStateParam {
316         .retValue = false,
317         .incognitoMode = incognitoMode,
318         .origin = origin,
319         .env = env,
320         .asyncWork = nullptr,
321         .deferred = deferred,
322         .jsStringRef = nullptr,
323         .callbackRef = nullptr,
324     };
325     if (param == nullptr) {
326         return nullptr;
327     }
328     napi_create_reference(env, argv[0], 1, &param->jsStringRef);
329     napi_value resourceName = nullptr;
330     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
331     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetPermissionState,
332         GetPermissionStatePromiseComplete, static_cast<void *>(param), &param->asyncWork));
333     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
334     return promise;
335 }
336 
JsGetAccessibleGeolocation(napi_env env,napi_callback_info info)337 napi_value NapiGeolocationPermission::JsGetAccessibleGeolocation(napi_env env, napi_callback_info info)
338 {
339     napi_value retValue = nullptr;
340     size_t argc = PARAMTHREE;
341     size_t argcPromiseForOld = PARAMONE;
342     size_t argcPromise = PARAMTWO;
343     size_t argcCallback = PARAMTHREE;
344     napi_value argv[PARAMTHREE] = { 0 };
345     napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
346     if (argc != argcPromise && argc != argcCallback && argc != argcPromiseForOld) {
347         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
348             NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_THREE, "one", "two", "three"));
349         return nullptr;
350     }
351     std::string origin;
352     if (!GetStringPara(env, argv[PARAMZERO], origin)) {
353         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
354             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "origin", "string"));
355         return nullptr;
356     }
357     bool incognitoMode = false;
358     napi_value result = nullptr;
359     if (argc == argcCallback) {
360         napi_valuetype valueType = napi_undefined;
361         napi_typeof(env, argv[PARAMONE], &valueType);
362         if (valueType != napi_function) {
363             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
364                 NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
365             return nullptr;
366         }
367         if (!GetBooleanPara(env, argv[PARAMTWO], incognitoMode)) {
368             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
369                 NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
370             return nullptr;
371         }
372         GetPermissionStateAsync(env, argv, origin, incognitoMode);
373         napi_get_undefined(env, &result);
374         return result;
375     }
376     if (argc == PARAMTWO) {
377         napi_valuetype valueType = napi_undefined;
378         napi_typeof(env, argv[PARAMONE], &valueType);
379         if (valueType != napi_function) {
380             if (!GetBooleanPara(env, argv[PARAMONE], incognitoMode)) {
381                 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
382                     NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
383                 return nullptr;
384             }
385             return GetPermissionStatePromise(env, argv, origin, incognitoMode);
386         }
387         GetPermissionStateAsync(env, argv, origin, incognitoMode);
388         napi_get_undefined(env, &result);
389         return result;
390     }
391     return GetPermissionStatePromise(env, argv, origin, incognitoMode);
392 }
393 
GetOriginComplete(napi_env env,napi_status status,void * data)394 void NapiGeolocationPermission::GetOriginComplete(napi_env env, napi_status status, void *data)
395 {
396     GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
397     napi_handle_scope scope = nullptr;
398     napi_open_handle_scope(env, &scope);
399     if (scope == nullptr) {
400         return;
401     }
402     napi_value setResult[RESULT_COUNT] = {0};
403     if (param->status) {
404         napi_get_undefined(env, &setResult[PARAMZERO]);
405         napi_get_undefined(env, &setResult[PARAMONE]);
406     } else {
407         napi_get_undefined(env, &setResult[PARAMZERO]);
408         napi_create_array(env, &setResult[PARAMONE]);
409         for (uint32_t i = 0; i < param->origins.size(); i++) {
410             std::string str = param->origins[i];
411             napi_value val = nullptr;
412             napi_create_string_utf8(env, str.c_str(), str.length(), &val);
413             napi_set_element(env, setResult[PARAMONE], i, val);
414         }
415     }
416     napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
417     napi_value callback = nullptr;
418     napi_get_reference_value(env, param->callbackRef, &callback);
419     napi_value returnVal = nullptr;
420     napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &returnVal);
421     napi_delete_reference(env, param->callbackRef);
422     napi_delete_async_work(env, param->asyncWork);
423     napi_close_handle_scope(env, scope);
424     delete param;
425     param = nullptr;
426 }
427 
GetOriginsPromiseComplete(napi_env env,napi_status status,void * data)428 void NapiGeolocationPermission::GetOriginsPromiseComplete(napi_env env, napi_status status, void *data)
429 {
430     GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
431     napi_handle_scope scope = nullptr;
432     napi_open_handle_scope(env, &scope);
433     if (scope == nullptr) {
434         delete param;
435         return;
436     }
437     napi_value setResult[RESULT_COUNT] = {0};
438     napi_get_undefined(env, &setResult[PARAMZERO]);
439     napi_create_array(env, &setResult[PARAMONE]);
440     for (uint32_t i = 0; i < param->origins.size(); i++) {
441         std::string str = param->origins[i];
442         napi_value val = nullptr;
443         napi_create_string_utf8(env, str.c_str(), str.length(), &val);
444         napi_set_element(env, setResult[PARAMONE], i, val);
445     }
446     napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
447     if (param->status == napi_ok) {
448         napi_resolve_deferred(env, param->deferred, args[1]);
449     } else {
450         napi_reject_deferred(env, param->deferred, args[0]);
451     }
452     napi_delete_async_work(env, param->asyncWork);
453     napi_close_handle_scope(env, scope);
454     delete param;
455     param = nullptr;
456 }
457 
ExecuteGetOrigins(napi_env env,void * data)458 void NapiGeolocationPermission::ExecuteGetOrigins(napi_env env, void *data)
459 {
460     GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
461     std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
462     if (!dataBase) {
463         param->errCode = INTERFACE_ERROR;
464         param->status = napi_generic_failure;
465         return;
466     }
467     param->origins = dataBase->GetOriginsByPermission(
468         OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, param->incognitoMode);
469     param->errCode = INTERFACE_OK;
470     param->status = napi_ok;
471 }
472 
GetOriginsAsync(napi_env env,napi_value * argv,bool incognitoMode)473 napi_value NapiGeolocationPermission::GetOriginsAsync(napi_env env,
474                                                       napi_value *argv,
475                                                       bool incognitoMode)
476 {
477     napi_value result = nullptr;
478     napi_value resourceName = nullptr;
479 
480     GetPermissionOriginsParam *param = new (std::nothrow) GetPermissionOriginsParam {
481         .env = env,
482         .asyncWork = nullptr,
483         .deferred = nullptr,
484         .callbackRef = nullptr,
485         .incognitoMode = incognitoMode,
486     };
487     if (param == nullptr) {
488         return nullptr;
489     }
490     napi_create_reference(env, *argv, 1, &param->callbackRef);
491     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
492     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetOrigins,
493         GetOriginComplete, static_cast<void *>(param), &param->asyncWork));
494     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
495     napi_get_undefined(env, &result);
496     return result;
497 }
498 
GetOriginsPromise(napi_env env,bool incognitoMode)499 napi_value NapiGeolocationPermission::GetOriginsPromise(napi_env env,
500                                                         bool incognitoMode)
501 {
502     napi_deferred deferred = nullptr;
503     napi_value promise = nullptr;
504     napi_create_promise(env, &deferred, &promise);
505 
506     GetPermissionOriginsParam *param = new (std::nothrow) GetPermissionOriginsParam {
507         .env = env,
508         .asyncWork = nullptr,
509         .deferred = deferred,
510         .callbackRef = nullptr,
511         .incognitoMode = incognitoMode,
512     };
513     if (param == nullptr) {
514         return nullptr;
515     }
516     napi_value resourceName = nullptr;
517     NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
518     NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetOrigins,
519         GetOriginsPromiseComplete, static_cast<void *>(param), &param->asyncWork));
520     NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
521     return promise;
522 }
523 
JsGetStoredGeolocation(napi_env env,napi_callback_info info)524 napi_value NapiGeolocationPermission::JsGetStoredGeolocation(napi_env env, napi_callback_info info)
525 {
526     napi_value retValue = nullptr;
527     size_t argc = PARAMTWO;
528     size_t argcForZero = PARAMZERO;
529     size_t argcPromise = PARAMONE;
530     size_t argcCallback = PARAMTWO;
531     napi_value argv[PARAMTWO] = { 0 };
532     napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
533     if (argc != argcPromise && argc != argcCallback && argc != argcForZero) {
534         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
535             NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_THREE, "one", "two", "three"));
536         return nullptr;
537     }
538 
539     bool incognitoMode = false;
540     if (argc == argcCallback) {
541         napi_valuetype valueType = napi_undefined;
542         napi_typeof(env, argv[PARAMZERO], &valueType);
543         if (valueType != napi_function) {
544             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
545                 NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
546             return nullptr;
547         }
548 
549         if (!GetBooleanPara(env, argv[PARAMONE], incognitoMode)) {
550             NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
551                 NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
552             return nullptr;
553         }
554         GetOriginsAsync(env, argv, incognitoMode);
555         napi_value result = nullptr;
556         napi_get_undefined(env, &result);
557         return result;
558     }
559 
560     if (argc == PARAMONE) {
561         napi_valuetype valueType = napi_undefined;
562         napi_typeof(env, argv[PARAMZERO], &valueType);
563         if (valueType != napi_function) {
564             if (!GetBooleanPara(env, argv[PARAMZERO], incognitoMode)) {
565                 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
566                     NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
567                 return nullptr;
568             }
569             return GetOriginsPromise(env, incognitoMode);
570         }
571         GetOriginsAsync(env, argv, incognitoMode);
572         napi_value result = nullptr;
573         napi_get_undefined(env, &result);
574         return result;
575     }
576 
577     return GetOriginsPromise(env, incognitoMode);
578 }
579 
JsConstructor(napi_env env,napi_callback_info info)580 napi_value NapiGeolocationPermission::JsConstructor(napi_env env, napi_callback_info info)
581 {
582     napi_value thisVar = nullptr;
583     size_t argc = PARAMTWO;
584     napi_value argv[PARAMTWO] = { 0 };
585     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
586     return thisVar;
587 }
588 } // namespace NWeb
589 } // namespace OHOS
590