10826e83eSopenharmony_ci/*
20826e83eSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
30826e83eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40826e83eSopenharmony_ci * you may not use this file except in compliance with the License.
50826e83eSopenharmony_ci * You may obtain a copy of the License at
60826e83eSopenharmony_ci *
70826e83eSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80826e83eSopenharmony_ci *
90826e83eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100826e83eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110826e83eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120826e83eSopenharmony_ci * See the License for the specific language governing permissions and
130826e83eSopenharmony_ci * limitations under the License.
140826e83eSopenharmony_ci */
150826e83eSopenharmony_ci
160826e83eSopenharmony_ci#include "napi_geolocation_permission.h"
170826e83eSopenharmony_ci
180826e83eSopenharmony_ci#include <cstdint>
190826e83eSopenharmony_ci#include <vector>
200826e83eSopenharmony_ci
210826e83eSopenharmony_ci#include "business_error.h"
220826e83eSopenharmony_ci#include "napi/native_common.h"
230826e83eSopenharmony_ci#include "nweb_data_base.h"
240826e83eSopenharmony_ci#include "nweb_helper.h"
250826e83eSopenharmony_ci#include "web_errors.h"
260826e83eSopenharmony_ci#include "securec.h"
270826e83eSopenharmony_ci
280826e83eSopenharmony_cinamespace {
290826e83eSopenharmony_ciconstexpr int32_t PARAMZERO = 0;
300826e83eSopenharmony_ciconstexpr int32_t PARAMONE = 1;
310826e83eSopenharmony_ciconstexpr int32_t PARAMTWO = 2;
320826e83eSopenharmony_ciconstexpr int32_t PARAMTHREE = 3;
330826e83eSopenharmony_ciconstexpr int32_t RESULT_COUNT = 2;
340826e83eSopenharmony_ciconstexpr int32_t INTERFACE_OK = 0;
350826e83eSopenharmony_ciconstexpr int32_t INTERFACE_ERROR = -1;
360826e83eSopenharmony_ciconstexpr int32_t ALLOW_PERMISSION_OPERATION = 1;
370826e83eSopenharmony_ciconstexpr int32_t DELETE_PERMISSION_OPERATION = 2;
380826e83eSopenharmony_ci
390826e83eSopenharmony_cistruct GetPermissionOriginsParam {
400826e83eSopenharmony_ci    std::vector<std::string> origins;
410826e83eSopenharmony_ci    napi_env env;
420826e83eSopenharmony_ci    napi_async_work asyncWork;
430826e83eSopenharmony_ci    napi_deferred deferred;
440826e83eSopenharmony_ci    napi_ref callbackRef;
450826e83eSopenharmony_ci    napi_status status;
460826e83eSopenharmony_ci    int errCode;
470826e83eSopenharmony_ci    bool incognitoMode;
480826e83eSopenharmony_ci};
490826e83eSopenharmony_ci
500826e83eSopenharmony_cistruct GetOriginPermissionStateParam {
510826e83eSopenharmony_ci    bool retValue;
520826e83eSopenharmony_ci    bool incognitoMode;
530826e83eSopenharmony_ci    std::string origin;
540826e83eSopenharmony_ci    napi_env env;
550826e83eSopenharmony_ci    napi_async_work asyncWork;
560826e83eSopenharmony_ci    napi_deferred deferred;
570826e83eSopenharmony_ci    napi_ref jsStringRef;
580826e83eSopenharmony_ci    napi_ref callbackRef;
590826e83eSopenharmony_ci    napi_status status;
600826e83eSopenharmony_ci    int errCode;
610826e83eSopenharmony_ci};
620826e83eSopenharmony_ci} // namespace
630826e83eSopenharmony_ci
640826e83eSopenharmony_cinamespace OHOS {
650826e83eSopenharmony_cinamespace NWeb {
660826e83eSopenharmony_cinapi_value NapiGeolocationPermission::Init(napi_env env, napi_value exports)
670826e83eSopenharmony_ci{
680826e83eSopenharmony_ci    const std::string GEOLOCATION_PERMISSION_CLASS_NAME = "GeolocationPermissions";
690826e83eSopenharmony_ci    napi_property_descriptor properties[] = {
700826e83eSopenharmony_ci        DECLARE_NAPI_STATIC_FUNCTION("allowGeolocation", NapiGeolocationPermission::JsAllowGeolocation),
710826e83eSopenharmony_ci        DECLARE_NAPI_STATIC_FUNCTION("deleteGeolocation", NapiGeolocationPermission::JsDeleteGeolocation),
720826e83eSopenharmony_ci        DECLARE_NAPI_STATIC_FUNCTION("deleteAllGeolocation", NapiGeolocationPermission::JsDeleteAllGeolocation),
730826e83eSopenharmony_ci        DECLARE_NAPI_STATIC_FUNCTION("getStoredGeolocation", NapiGeolocationPermission::JsGetStoredGeolocation),
740826e83eSopenharmony_ci        DECLARE_NAPI_STATIC_FUNCTION("getAccessibleGeolocation",
750826e83eSopenharmony_ci            NapiGeolocationPermission::JsGetAccessibleGeolocation),
760826e83eSopenharmony_ci    };
770826e83eSopenharmony_ci    napi_value constructor = nullptr;
780826e83eSopenharmony_ci    napi_define_class(env, GEOLOCATION_PERMISSION_CLASS_NAME.c_str(), GEOLOCATION_PERMISSION_CLASS_NAME.length(),
790826e83eSopenharmony_ci        JsConstructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &constructor);
800826e83eSopenharmony_ci    NAPI_ASSERT(env, constructor != nullptr, "NapiGeolocationPermission define js class failed");
810826e83eSopenharmony_ci    napi_status status = napi_set_named_property(env, exports, "GeolocationPermissions", constructor);
820826e83eSopenharmony_ci    NAPI_ASSERT(env, status == napi_ok, "NapiGeolocationPermission set property failed");
830826e83eSopenharmony_ci    return exports;
840826e83eSopenharmony_ci}
850826e83eSopenharmony_ci
860826e83eSopenharmony_cibool NapiGeolocationPermission::GetStringPara(napi_env env, napi_value argv, std::string& outValue)
870826e83eSopenharmony_ci{
880826e83eSopenharmony_ci    constexpr int32_t MAX_STRING_LENGTH = 40960;
890826e83eSopenharmony_ci    size_t bufferSize = 0;
900826e83eSopenharmony_ci    napi_valuetype valueType = napi_null;
910826e83eSopenharmony_ci
920826e83eSopenharmony_ci    napi_typeof(env, argv, &valueType);
930826e83eSopenharmony_ci    if (valueType != napi_string) {
940826e83eSopenharmony_ci        return false;
950826e83eSopenharmony_ci    }
960826e83eSopenharmony_ci    napi_get_value_string_utf8(env, argv, nullptr, 0, &bufferSize);
970826e83eSopenharmony_ci    if (bufferSize > MAX_STRING_LENGTH) {
980826e83eSopenharmony_ci        return false;
990826e83eSopenharmony_ci    }
1000826e83eSopenharmony_ci    char stringValue[bufferSize + 1];
1010826e83eSopenharmony_ci    size_t jsStringLength = 0;
1020826e83eSopenharmony_ci    napi_get_value_string_utf8(env, argv, stringValue, bufferSize + 1, &jsStringLength);
1030826e83eSopenharmony_ci    if (jsStringLength != bufferSize) {
1040826e83eSopenharmony_ci        return false;
1050826e83eSopenharmony_ci    }
1060826e83eSopenharmony_ci    outValue = stringValue;
1070826e83eSopenharmony_ci    return true;
1080826e83eSopenharmony_ci}
1090826e83eSopenharmony_ci
1100826e83eSopenharmony_cibool NapiGeolocationPermission::GetBooleanPara(napi_env env, napi_value argv, bool& outValue)
1110826e83eSopenharmony_ci{
1120826e83eSopenharmony_ci    napi_valuetype valueType = napi_null;
1130826e83eSopenharmony_ci
1140826e83eSopenharmony_ci    napi_typeof(env, argv, &valueType);
1150826e83eSopenharmony_ci    if (valueType != napi_boolean) {
1160826e83eSopenharmony_ci        return false;
1170826e83eSopenharmony_ci    }
1180826e83eSopenharmony_ci
1190826e83eSopenharmony_ci    bool boolValue;
1200826e83eSopenharmony_ci    napi_get_value_bool(env, argv, &boolValue);
1210826e83eSopenharmony_ci    outValue = boolValue;
1220826e83eSopenharmony_ci    return true;
1230826e83eSopenharmony_ci}
1240826e83eSopenharmony_ci
1250826e83eSopenharmony_cinapi_value NapiGeolocationPermission::ProcessActionByType(napi_env env, napi_callback_info info,
1260826e83eSopenharmony_ci    int32_t operationType)
1270826e83eSopenharmony_ci{
1280826e83eSopenharmony_ci    napi_value retValue = nullptr;
1290826e83eSopenharmony_ci    size_t argc = PARAMTWO;
1300826e83eSopenharmony_ci    size_t argcForOld = PARAMONE;
1310826e83eSopenharmony_ci    napi_value argv[PARAMTWO] = { 0 };
1320826e83eSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
1330826e83eSopenharmony_ci    if (argc != PARAMTWO && argc != argcForOld) {
1340826e83eSopenharmony_ci        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
1350826e83eSopenharmony_ci            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "one", "two"));
1360826e83eSopenharmony_ci        return nullptr;
1370826e83eSopenharmony_ci    }
1380826e83eSopenharmony_ci
1390826e83eSopenharmony_ci    std::string origin;
1400826e83eSopenharmony_ci    if (!GetStringPara(env, argv[PARAMZERO], origin)) {
1410826e83eSopenharmony_ci        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
1420826e83eSopenharmony_ci            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "origin", "string"));
1430826e83eSopenharmony_ci        return nullptr;
1440826e83eSopenharmony_ci    }
1450826e83eSopenharmony_ci    bool incognitoMode = false;
1460826e83eSopenharmony_ci    if (argc == PARAMTWO) {
1470826e83eSopenharmony_ci        napi_get_value_bool(env, argv[PARAMONE], &incognitoMode);
1480826e83eSopenharmony_ci    }
1490826e83eSopenharmony_ci
1500826e83eSopenharmony_ci    napi_value result = nullptr;
1510826e83eSopenharmony_ci    napi_get_undefined(env, &result);
1520826e83eSopenharmony_ci    std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
1530826e83eSopenharmony_ci    if (!dataBase) {
1540826e83eSopenharmony_ci        return result;
1550826e83eSopenharmony_ci    }
1560826e83eSopenharmony_ci    if (operationType == ALLOW_PERMISSION_OPERATION) {
1570826e83eSopenharmony_ci        if (dataBase->SetPermissionByOrigin(origin, OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, true,
1580826e83eSopenharmony_ci            incognitoMode) == NWebError::INVALID_ORIGIN) {
1590826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::INVALID_ORIGIN);
1600826e83eSopenharmony_ci            return result;
1610826e83eSopenharmony_ci        }
1620826e83eSopenharmony_ci    } else if (operationType == DELETE_PERMISSION_OPERATION) {
1630826e83eSopenharmony_ci        if (dataBase->ClearPermissionByOrigin(origin, OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE,
1640826e83eSopenharmony_ci            incognitoMode) == NWebError::INVALID_ORIGIN) {
1650826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::INVALID_ORIGIN);
1660826e83eSopenharmony_ci            return result;
1670826e83eSopenharmony_ci        }
1680826e83eSopenharmony_ci    }
1690826e83eSopenharmony_ci    return result;
1700826e83eSopenharmony_ci}
1710826e83eSopenharmony_ci
1720826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsAllowGeolocation(napi_env env, napi_callback_info info)
1730826e83eSopenharmony_ci{
1740826e83eSopenharmony_ci    return ProcessActionByType(env, info, ALLOW_PERMISSION_OPERATION);
1750826e83eSopenharmony_ci}
1760826e83eSopenharmony_ci
1770826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsDeleteGeolocation(napi_env env, napi_callback_info info)
1780826e83eSopenharmony_ci{
1790826e83eSopenharmony_ci    return ProcessActionByType(env, info, DELETE_PERMISSION_OPERATION);
1800826e83eSopenharmony_ci}
1810826e83eSopenharmony_ci
1820826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsDeleteAllGeolocation(napi_env env, napi_callback_info info)
1830826e83eSopenharmony_ci{
1840826e83eSopenharmony_ci    napi_value retValue = nullptr;
1850826e83eSopenharmony_ci    size_t argc = PARAMONE;
1860826e83eSopenharmony_ci    size_t argcForOld = 0;
1870826e83eSopenharmony_ci    napi_value argv[PARAMONE] = { 0 };
1880826e83eSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
1890826e83eSopenharmony_ci    if (argc != PARAMONE && argc != argcForOld) {
1900826e83eSopenharmony_ci        return nullptr;
1910826e83eSopenharmony_ci    }
1920826e83eSopenharmony_ci    bool incognitoMode = false;
1930826e83eSopenharmony_ci    if (argc == PARAMONE) {
1940826e83eSopenharmony_ci        napi_get_value_bool(env, argv[PARAMZERO], &incognitoMode);
1950826e83eSopenharmony_ci    }
1960826e83eSopenharmony_ci
1970826e83eSopenharmony_ci    std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
1980826e83eSopenharmony_ci    if (dataBase != nullptr) {
1990826e83eSopenharmony_ci        dataBase->ClearAllPermission(OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, incognitoMode);
2000826e83eSopenharmony_ci    }
2010826e83eSopenharmony_ci
2020826e83eSopenharmony_ci    napi_value result = nullptr;
2030826e83eSopenharmony_ci    napi_get_undefined(env, &result);
2040826e83eSopenharmony_ci    return result;
2050826e83eSopenharmony_ci}
2060826e83eSopenharmony_ci
2070826e83eSopenharmony_civoid NapiGeolocationPermission::GetPermissionStateComplete(napi_env env, napi_status status, void *data)
2080826e83eSopenharmony_ci{
2090826e83eSopenharmony_ci    GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
2100826e83eSopenharmony_ci    napi_handle_scope scope = nullptr;
2110826e83eSopenharmony_ci    napi_open_handle_scope(env, &scope);
2120826e83eSopenharmony_ci    if (scope == nullptr) {
2130826e83eSopenharmony_ci        return;
2140826e83eSopenharmony_ci    }
2150826e83eSopenharmony_ci    napi_value setResult[RESULT_COUNT] = {0};
2160826e83eSopenharmony_ci    if (param->status) {
2170826e83eSopenharmony_ci        setResult[PARAMZERO] = NWebError::BusinessError::CreateError(env, param->errCode);
2180826e83eSopenharmony_ci        napi_get_undefined(env, &setResult[PARAMONE]);
2190826e83eSopenharmony_ci    } else {
2200826e83eSopenharmony_ci        napi_get_undefined(env, &setResult[PARAMZERO]);
2210826e83eSopenharmony_ci        napi_get_boolean(env, param->retValue, &setResult[PARAMONE]);
2220826e83eSopenharmony_ci    }
2230826e83eSopenharmony_ci    napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
2240826e83eSopenharmony_ci    napi_value callback = nullptr;
2250826e83eSopenharmony_ci    napi_get_reference_value(env, param->callbackRef, &callback);
2260826e83eSopenharmony_ci    napi_value returnVal = nullptr;
2270826e83eSopenharmony_ci    napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &returnVal);
2280826e83eSopenharmony_ci    napi_delete_reference(env, param->jsStringRef);
2290826e83eSopenharmony_ci    napi_delete_reference(env, param->callbackRef);
2300826e83eSopenharmony_ci    napi_delete_async_work(env, param->asyncWork);
2310826e83eSopenharmony_ci    napi_close_handle_scope(env, scope);
2320826e83eSopenharmony_ci    delete param;
2330826e83eSopenharmony_ci    param = nullptr;
2340826e83eSopenharmony_ci}
2350826e83eSopenharmony_ci
2360826e83eSopenharmony_civoid NapiGeolocationPermission::GetPermissionStatePromiseComplete(napi_env env, napi_status status, void *data)
2370826e83eSopenharmony_ci{
2380826e83eSopenharmony_ci    GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
2390826e83eSopenharmony_ci    napi_handle_scope scope = nullptr;
2400826e83eSopenharmony_ci    napi_open_handle_scope(env, &scope);
2410826e83eSopenharmony_ci    if (scope == nullptr) {
2420826e83eSopenharmony_ci        return;
2430826e83eSopenharmony_ci    }
2440826e83eSopenharmony_ci    napi_value setResult[RESULT_COUNT] = {0};
2450826e83eSopenharmony_ci    setResult[PARAMZERO] = NWebError::BusinessError::CreateError(env, param->errCode);
2460826e83eSopenharmony_ci    napi_get_boolean(env, param->retValue, &setResult[PARAMONE]);
2470826e83eSopenharmony_ci    napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
2480826e83eSopenharmony_ci    if (param->status == napi_ok) {
2490826e83eSopenharmony_ci        napi_resolve_deferred(env, param->deferred, args[1]);
2500826e83eSopenharmony_ci    } else {
2510826e83eSopenharmony_ci        napi_reject_deferred(env, param->deferred, args[0]);
2520826e83eSopenharmony_ci    }
2530826e83eSopenharmony_ci    napi_delete_reference(env, param->jsStringRef);
2540826e83eSopenharmony_ci    napi_delete_async_work(env, param->asyncWork);
2550826e83eSopenharmony_ci    napi_close_handle_scope(env, scope);
2560826e83eSopenharmony_ci    delete param;
2570826e83eSopenharmony_ci    param = nullptr;
2580826e83eSopenharmony_ci}
2590826e83eSopenharmony_ci
2600826e83eSopenharmony_civoid NapiGeolocationPermission::ExecuteGetPermissionState(napi_env env, void *data)
2610826e83eSopenharmony_ci{
2620826e83eSopenharmony_ci    GetOriginPermissionStateParam *param = static_cast<GetOriginPermissionStateParam *>(data);
2630826e83eSopenharmony_ci    std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
2640826e83eSopenharmony_ci    if (!dataBase) {
2650826e83eSopenharmony_ci        param->errCode = INTERFACE_ERROR;
2660826e83eSopenharmony_ci        param->status = napi_generic_failure;
2670826e83eSopenharmony_ci        return;
2680826e83eSopenharmony_ci    }
2690826e83eSopenharmony_ci    if (dataBase->GetPermissionResultByOrigin(param->origin,
2700826e83eSopenharmony_ci        OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, param->retValue, param->incognitoMode)) {
2710826e83eSopenharmony_ci        param->errCode = INTERFACE_OK;
2720826e83eSopenharmony_ci        param->status = napi_ok;
2730826e83eSopenharmony_ci    } else {
2740826e83eSopenharmony_ci        param->errCode = NWebError::INVALID_ORIGIN;
2750826e83eSopenharmony_ci        param->status = napi_generic_failure;
2760826e83eSopenharmony_ci    }
2770826e83eSopenharmony_ci}
2780826e83eSopenharmony_ci
2790826e83eSopenharmony_cinapi_value NapiGeolocationPermission::GetPermissionStateAsync(napi_env env,
2800826e83eSopenharmony_ci    napi_value *argv, const std::string& origin, bool incognitoMode)
2810826e83eSopenharmony_ci{
2820826e83eSopenharmony_ci    napi_value result = nullptr;
2830826e83eSopenharmony_ci    napi_value resourceName = nullptr;
2840826e83eSopenharmony_ci
2850826e83eSopenharmony_ci    GetOriginPermissionStateParam *param = new (std::nothrow) GetOriginPermissionStateParam {
2860826e83eSopenharmony_ci        .retValue = false,
2870826e83eSopenharmony_ci        .incognitoMode = incognitoMode,
2880826e83eSopenharmony_ci        .origin = origin,
2890826e83eSopenharmony_ci        .env = env,
2900826e83eSopenharmony_ci        .asyncWork = nullptr,
2910826e83eSopenharmony_ci        .deferred = nullptr,
2920826e83eSopenharmony_ci        .jsStringRef = nullptr,
2930826e83eSopenharmony_ci        .callbackRef = nullptr,
2940826e83eSopenharmony_ci    };
2950826e83eSopenharmony_ci    if (param == nullptr) {
2960826e83eSopenharmony_ci        return nullptr;
2970826e83eSopenharmony_ci    }
2980826e83eSopenharmony_ci    napi_create_reference(env, argv[0], 1, &param->jsStringRef);
2990826e83eSopenharmony_ci    napi_create_reference(env, argv[1], 1, &param->callbackRef);
3000826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3010826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetPermissionState,
3020826e83eSopenharmony_ci        GetPermissionStateComplete, static_cast<void *>(param), &param->asyncWork));
3030826e83eSopenharmony_ci    NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
3040826e83eSopenharmony_ci    napi_get_undefined(env, &result);
3050826e83eSopenharmony_ci    return result;
3060826e83eSopenharmony_ci}
3070826e83eSopenharmony_ci
3080826e83eSopenharmony_cinapi_value NapiGeolocationPermission::GetPermissionStatePromise(napi_env env, napi_value *argv,
3090826e83eSopenharmony_ci    const std::string& origin, bool incognitoMode)
3100826e83eSopenharmony_ci{
3110826e83eSopenharmony_ci    napi_deferred deferred = nullptr;
3120826e83eSopenharmony_ci    napi_value promise = nullptr;
3130826e83eSopenharmony_ci    napi_create_promise(env, &deferred, &promise);
3140826e83eSopenharmony_ci
3150826e83eSopenharmony_ci    GetOriginPermissionStateParam *param = new (std::nothrow) GetOriginPermissionStateParam {
3160826e83eSopenharmony_ci        .retValue = false,
3170826e83eSopenharmony_ci        .incognitoMode = incognitoMode,
3180826e83eSopenharmony_ci        .origin = origin,
3190826e83eSopenharmony_ci        .env = env,
3200826e83eSopenharmony_ci        .asyncWork = nullptr,
3210826e83eSopenharmony_ci        .deferred = deferred,
3220826e83eSopenharmony_ci        .jsStringRef = nullptr,
3230826e83eSopenharmony_ci        .callbackRef = nullptr,
3240826e83eSopenharmony_ci    };
3250826e83eSopenharmony_ci    if (param == nullptr) {
3260826e83eSopenharmony_ci        return nullptr;
3270826e83eSopenharmony_ci    }
3280826e83eSopenharmony_ci    napi_create_reference(env, argv[0], 1, &param->jsStringRef);
3290826e83eSopenharmony_ci    napi_value resourceName = nullptr;
3300826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
3310826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetPermissionState,
3320826e83eSopenharmony_ci        GetPermissionStatePromiseComplete, static_cast<void *>(param), &param->asyncWork));
3330826e83eSopenharmony_ci    NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
3340826e83eSopenharmony_ci    return promise;
3350826e83eSopenharmony_ci}
3360826e83eSopenharmony_ci
3370826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsGetAccessibleGeolocation(napi_env env, napi_callback_info info)
3380826e83eSopenharmony_ci{
3390826e83eSopenharmony_ci    napi_value retValue = nullptr;
3400826e83eSopenharmony_ci    size_t argc = PARAMTHREE;
3410826e83eSopenharmony_ci    size_t argcPromiseForOld = PARAMONE;
3420826e83eSopenharmony_ci    size_t argcPromise = PARAMTWO;
3430826e83eSopenharmony_ci    size_t argcCallback = PARAMTHREE;
3440826e83eSopenharmony_ci    napi_value argv[PARAMTHREE] = { 0 };
3450826e83eSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
3460826e83eSopenharmony_ci    if (argc != argcPromise && argc != argcCallback && argc != argcPromiseForOld) {
3470826e83eSopenharmony_ci        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3480826e83eSopenharmony_ci            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_THREE, "one", "two", "three"));
3490826e83eSopenharmony_ci        return nullptr;
3500826e83eSopenharmony_ci    }
3510826e83eSopenharmony_ci    std::string origin;
3520826e83eSopenharmony_ci    if (!GetStringPara(env, argv[PARAMZERO], origin)) {
3530826e83eSopenharmony_ci        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3540826e83eSopenharmony_ci            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "origin", "string"));
3550826e83eSopenharmony_ci        return nullptr;
3560826e83eSopenharmony_ci    }
3570826e83eSopenharmony_ci    bool incognitoMode = false;
3580826e83eSopenharmony_ci    napi_value result = nullptr;
3590826e83eSopenharmony_ci    if (argc == argcCallback) {
3600826e83eSopenharmony_ci        napi_valuetype valueType = napi_undefined;
3610826e83eSopenharmony_ci        napi_typeof(env, argv[PARAMONE], &valueType);
3620826e83eSopenharmony_ci        if (valueType != napi_function) {
3630826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3640826e83eSopenharmony_ci                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
3650826e83eSopenharmony_ci            return nullptr;
3660826e83eSopenharmony_ci        }
3670826e83eSopenharmony_ci        if (!GetBooleanPara(env, argv[PARAMTWO], incognitoMode)) {
3680826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3690826e83eSopenharmony_ci                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
3700826e83eSopenharmony_ci            return nullptr;
3710826e83eSopenharmony_ci        }
3720826e83eSopenharmony_ci        GetPermissionStateAsync(env, argv, origin, incognitoMode);
3730826e83eSopenharmony_ci        napi_get_undefined(env, &result);
3740826e83eSopenharmony_ci        return result;
3750826e83eSopenharmony_ci    }
3760826e83eSopenharmony_ci    if (argc == PARAMTWO) {
3770826e83eSopenharmony_ci        napi_valuetype valueType = napi_undefined;
3780826e83eSopenharmony_ci        napi_typeof(env, argv[PARAMONE], &valueType);
3790826e83eSopenharmony_ci        if (valueType != napi_function) {
3800826e83eSopenharmony_ci            if (!GetBooleanPara(env, argv[PARAMONE], incognitoMode)) {
3810826e83eSopenharmony_ci                NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3820826e83eSopenharmony_ci                    NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
3830826e83eSopenharmony_ci                return nullptr;
3840826e83eSopenharmony_ci            }
3850826e83eSopenharmony_ci            return GetPermissionStatePromise(env, argv, origin, incognitoMode);
3860826e83eSopenharmony_ci        }
3870826e83eSopenharmony_ci        GetPermissionStateAsync(env, argv, origin, incognitoMode);
3880826e83eSopenharmony_ci        napi_get_undefined(env, &result);
3890826e83eSopenharmony_ci        return result;
3900826e83eSopenharmony_ci    }
3910826e83eSopenharmony_ci    return GetPermissionStatePromise(env, argv, origin, incognitoMode);
3920826e83eSopenharmony_ci}
3930826e83eSopenharmony_ci
3940826e83eSopenharmony_civoid NapiGeolocationPermission::GetOriginComplete(napi_env env, napi_status status, void *data)
3950826e83eSopenharmony_ci{
3960826e83eSopenharmony_ci    GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
3970826e83eSopenharmony_ci    napi_handle_scope scope = nullptr;
3980826e83eSopenharmony_ci    napi_open_handle_scope(env, &scope);
3990826e83eSopenharmony_ci    if (scope == nullptr) {
4000826e83eSopenharmony_ci        return;
4010826e83eSopenharmony_ci    }
4020826e83eSopenharmony_ci    napi_value setResult[RESULT_COUNT] = {0};
4030826e83eSopenharmony_ci    if (param->status) {
4040826e83eSopenharmony_ci        napi_get_undefined(env, &setResult[PARAMZERO]);
4050826e83eSopenharmony_ci        napi_get_undefined(env, &setResult[PARAMONE]);
4060826e83eSopenharmony_ci    } else {
4070826e83eSopenharmony_ci        napi_get_undefined(env, &setResult[PARAMZERO]);
4080826e83eSopenharmony_ci        napi_create_array(env, &setResult[PARAMONE]);
4090826e83eSopenharmony_ci        for (uint32_t i = 0; i < param->origins.size(); i++) {
4100826e83eSopenharmony_ci            std::string str = param->origins[i];
4110826e83eSopenharmony_ci            napi_value val = nullptr;
4120826e83eSopenharmony_ci            napi_create_string_utf8(env, str.c_str(), str.length(), &val);
4130826e83eSopenharmony_ci            napi_set_element(env, setResult[PARAMONE], i, val);
4140826e83eSopenharmony_ci        }
4150826e83eSopenharmony_ci    }
4160826e83eSopenharmony_ci    napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
4170826e83eSopenharmony_ci    napi_value callback = nullptr;
4180826e83eSopenharmony_ci    napi_get_reference_value(env, param->callbackRef, &callback);
4190826e83eSopenharmony_ci    napi_value returnVal = nullptr;
4200826e83eSopenharmony_ci    napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &returnVal);
4210826e83eSopenharmony_ci    napi_delete_reference(env, param->callbackRef);
4220826e83eSopenharmony_ci    napi_delete_async_work(env, param->asyncWork);
4230826e83eSopenharmony_ci    napi_close_handle_scope(env, scope);
4240826e83eSopenharmony_ci    delete param;
4250826e83eSopenharmony_ci    param = nullptr;
4260826e83eSopenharmony_ci}
4270826e83eSopenharmony_ci
4280826e83eSopenharmony_civoid NapiGeolocationPermission::GetOriginsPromiseComplete(napi_env env, napi_status status, void *data)
4290826e83eSopenharmony_ci{
4300826e83eSopenharmony_ci    GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
4310826e83eSopenharmony_ci    napi_handle_scope scope = nullptr;
4320826e83eSopenharmony_ci    napi_open_handle_scope(env, &scope);
4330826e83eSopenharmony_ci    if (scope == nullptr) {
4340826e83eSopenharmony_ci        delete param;
4350826e83eSopenharmony_ci        return;
4360826e83eSopenharmony_ci    }
4370826e83eSopenharmony_ci    napi_value setResult[RESULT_COUNT] = {0};
4380826e83eSopenharmony_ci    napi_get_undefined(env, &setResult[PARAMZERO]);
4390826e83eSopenharmony_ci    napi_create_array(env, &setResult[PARAMONE]);
4400826e83eSopenharmony_ci    for (uint32_t i = 0; i < param->origins.size(); i++) {
4410826e83eSopenharmony_ci        std::string str = param->origins[i];
4420826e83eSopenharmony_ci        napi_value val = nullptr;
4430826e83eSopenharmony_ci        napi_create_string_utf8(env, str.c_str(), str.length(), &val);
4440826e83eSopenharmony_ci        napi_set_element(env, setResult[PARAMONE], i, val);
4450826e83eSopenharmony_ci    }
4460826e83eSopenharmony_ci    napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
4470826e83eSopenharmony_ci    if (param->status == napi_ok) {
4480826e83eSopenharmony_ci        napi_resolve_deferred(env, param->deferred, args[1]);
4490826e83eSopenharmony_ci    } else {
4500826e83eSopenharmony_ci        napi_reject_deferred(env, param->deferred, args[0]);
4510826e83eSopenharmony_ci    }
4520826e83eSopenharmony_ci    napi_delete_async_work(env, param->asyncWork);
4530826e83eSopenharmony_ci    napi_close_handle_scope(env, scope);
4540826e83eSopenharmony_ci    delete param;
4550826e83eSopenharmony_ci    param = nullptr;
4560826e83eSopenharmony_ci}
4570826e83eSopenharmony_ci
4580826e83eSopenharmony_civoid NapiGeolocationPermission::ExecuteGetOrigins(napi_env env, void *data)
4590826e83eSopenharmony_ci{
4600826e83eSopenharmony_ci    GetPermissionOriginsParam *param = static_cast<GetPermissionOriginsParam *>(data);
4610826e83eSopenharmony_ci    std::shared_ptr<OHOS::NWeb::NWebDataBase> dataBase = OHOS::NWeb::NWebHelper::Instance().GetDataBase();
4620826e83eSopenharmony_ci    if (!dataBase) {
4630826e83eSopenharmony_ci        param->errCode = INTERFACE_ERROR;
4640826e83eSopenharmony_ci        param->status = napi_generic_failure;
4650826e83eSopenharmony_ci        return;
4660826e83eSopenharmony_ci    }
4670826e83eSopenharmony_ci    param->origins = dataBase->GetOriginsByPermission(
4680826e83eSopenharmony_ci        OHOS::NWeb::NWebDataBase::WebPermissionType::GEOLOCATION_TYPE, param->incognitoMode);
4690826e83eSopenharmony_ci    param->errCode = INTERFACE_OK;
4700826e83eSopenharmony_ci    param->status = napi_ok;
4710826e83eSopenharmony_ci}
4720826e83eSopenharmony_ci
4730826e83eSopenharmony_cinapi_value NapiGeolocationPermission::GetOriginsAsync(napi_env env,
4740826e83eSopenharmony_ci                                                      napi_value *argv,
4750826e83eSopenharmony_ci                                                      bool incognitoMode)
4760826e83eSopenharmony_ci{
4770826e83eSopenharmony_ci    napi_value result = nullptr;
4780826e83eSopenharmony_ci    napi_value resourceName = nullptr;
4790826e83eSopenharmony_ci
4800826e83eSopenharmony_ci    GetPermissionOriginsParam *param = new (std::nothrow) GetPermissionOriginsParam {
4810826e83eSopenharmony_ci        .env = env,
4820826e83eSopenharmony_ci        .asyncWork = nullptr,
4830826e83eSopenharmony_ci        .deferred = nullptr,
4840826e83eSopenharmony_ci        .callbackRef = nullptr,
4850826e83eSopenharmony_ci        .incognitoMode = incognitoMode,
4860826e83eSopenharmony_ci    };
4870826e83eSopenharmony_ci    if (param == nullptr) {
4880826e83eSopenharmony_ci        return nullptr;
4890826e83eSopenharmony_ci    }
4900826e83eSopenharmony_ci    napi_create_reference(env, *argv, 1, &param->callbackRef);
4910826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
4920826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetOrigins,
4930826e83eSopenharmony_ci        GetOriginComplete, static_cast<void *>(param), &param->asyncWork));
4940826e83eSopenharmony_ci    NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
4950826e83eSopenharmony_ci    napi_get_undefined(env, &result);
4960826e83eSopenharmony_ci    return result;
4970826e83eSopenharmony_ci}
4980826e83eSopenharmony_ci
4990826e83eSopenharmony_cinapi_value NapiGeolocationPermission::GetOriginsPromise(napi_env env,
5000826e83eSopenharmony_ci                                                        bool incognitoMode)
5010826e83eSopenharmony_ci{
5020826e83eSopenharmony_ci    napi_deferred deferred = nullptr;
5030826e83eSopenharmony_ci    napi_value promise = nullptr;
5040826e83eSopenharmony_ci    napi_create_promise(env, &deferred, &promise);
5050826e83eSopenharmony_ci
5060826e83eSopenharmony_ci    GetPermissionOriginsParam *param = new (std::nothrow) GetPermissionOriginsParam {
5070826e83eSopenharmony_ci        .env = env,
5080826e83eSopenharmony_ci        .asyncWork = nullptr,
5090826e83eSopenharmony_ci        .deferred = deferred,
5100826e83eSopenharmony_ci        .callbackRef = nullptr,
5110826e83eSopenharmony_ci        .incognitoMode = incognitoMode,
5120826e83eSopenharmony_ci    };
5130826e83eSopenharmony_ci    if (param == nullptr) {
5140826e83eSopenharmony_ci        return nullptr;
5150826e83eSopenharmony_ci    }
5160826e83eSopenharmony_ci    napi_value resourceName = nullptr;
5170826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_string_utf8(env, __func__, NAPI_AUTO_LENGTH, &resourceName));
5180826e83eSopenharmony_ci    NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, ExecuteGetOrigins,
5190826e83eSopenharmony_ci        GetOriginsPromiseComplete, static_cast<void *>(param), &param->asyncWork));
5200826e83eSopenharmony_ci    NAPI_CALL(env, napi_queue_async_work_with_qos(env, param->asyncWork, napi_qos_user_initiated));
5210826e83eSopenharmony_ci    return promise;
5220826e83eSopenharmony_ci}
5230826e83eSopenharmony_ci
5240826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsGetStoredGeolocation(napi_env env, napi_callback_info info)
5250826e83eSopenharmony_ci{
5260826e83eSopenharmony_ci    napi_value retValue = nullptr;
5270826e83eSopenharmony_ci    size_t argc = PARAMTWO;
5280826e83eSopenharmony_ci    size_t argcForZero = PARAMZERO;
5290826e83eSopenharmony_ci    size_t argcPromise = PARAMONE;
5300826e83eSopenharmony_ci    size_t argcCallback = PARAMTWO;
5310826e83eSopenharmony_ci    napi_value argv[PARAMTWO] = { 0 };
5320826e83eSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &retValue, nullptr);
5330826e83eSopenharmony_ci    if (argc != argcPromise && argc != argcCallback && argc != argcForZero) {
5340826e83eSopenharmony_ci        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
5350826e83eSopenharmony_ci            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_THREE, "one", "two", "three"));
5360826e83eSopenharmony_ci        return nullptr;
5370826e83eSopenharmony_ci    }
5380826e83eSopenharmony_ci
5390826e83eSopenharmony_ci    bool incognitoMode = false;
5400826e83eSopenharmony_ci    if (argc == argcCallback) {
5410826e83eSopenharmony_ci        napi_valuetype valueType = napi_undefined;
5420826e83eSopenharmony_ci        napi_typeof(env, argv[PARAMZERO], &valueType);
5430826e83eSopenharmony_ci        if (valueType != napi_function) {
5440826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
5450826e83eSopenharmony_ci                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
5460826e83eSopenharmony_ci            return nullptr;
5470826e83eSopenharmony_ci        }
5480826e83eSopenharmony_ci
5490826e83eSopenharmony_ci        if (!GetBooleanPara(env, argv[PARAMONE], incognitoMode)) {
5500826e83eSopenharmony_ci            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
5510826e83eSopenharmony_ci                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
5520826e83eSopenharmony_ci            return nullptr;
5530826e83eSopenharmony_ci        }
5540826e83eSopenharmony_ci        GetOriginsAsync(env, argv, incognitoMode);
5550826e83eSopenharmony_ci        napi_value result = nullptr;
5560826e83eSopenharmony_ci        napi_get_undefined(env, &result);
5570826e83eSopenharmony_ci        return result;
5580826e83eSopenharmony_ci    }
5590826e83eSopenharmony_ci
5600826e83eSopenharmony_ci    if (argc == PARAMONE) {
5610826e83eSopenharmony_ci        napi_valuetype valueType = napi_undefined;
5620826e83eSopenharmony_ci        napi_typeof(env, argv[PARAMZERO], &valueType);
5630826e83eSopenharmony_ci        if (valueType != napi_function) {
5640826e83eSopenharmony_ci            if (!GetBooleanPara(env, argv[PARAMZERO], incognitoMode)) {
5650826e83eSopenharmony_ci                NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
5660826e83eSopenharmony_ci                    NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "incognito", "boolean"));
5670826e83eSopenharmony_ci                return nullptr;
5680826e83eSopenharmony_ci            }
5690826e83eSopenharmony_ci            return GetOriginsPromise(env, incognitoMode);
5700826e83eSopenharmony_ci        }
5710826e83eSopenharmony_ci        GetOriginsAsync(env, argv, incognitoMode);
5720826e83eSopenharmony_ci        napi_value result = nullptr;
5730826e83eSopenharmony_ci        napi_get_undefined(env, &result);
5740826e83eSopenharmony_ci        return result;
5750826e83eSopenharmony_ci    }
5760826e83eSopenharmony_ci
5770826e83eSopenharmony_ci    return GetOriginsPromise(env, incognitoMode);
5780826e83eSopenharmony_ci}
5790826e83eSopenharmony_ci
5800826e83eSopenharmony_cinapi_value NapiGeolocationPermission::JsConstructor(napi_env env, napi_callback_info info)
5810826e83eSopenharmony_ci{
5820826e83eSopenharmony_ci    napi_value thisVar = nullptr;
5830826e83eSopenharmony_ci    size_t argc = PARAMTWO;
5840826e83eSopenharmony_ci    napi_value argv[PARAMTWO] = { 0 };
5850826e83eSopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5860826e83eSopenharmony_ci    return thisVar;
5870826e83eSopenharmony_ci}
5880826e83eSopenharmony_ci} // namespace NWeb
5890826e83eSopenharmony_ci} // namespace OHOS
590