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_webview_controller.h"
17
18#include <arpa/inet.h>
19#include <cctype>
20#include <climits>
21#include <cstdint>
22#include <regex>
23#include <securec.h>
24#include <unistd.h>
25#include <uv.h>
26
27#include "application_context.h"
28#include "business_error.h"
29#include "napi_parse_utils.h"
30#include "native_engine/native_engine.h"
31#include "nweb.h"
32#include "nweb_adapter_helper.h"
33#include "nweb_helper.h"
34#include "nweb_init_params.h"
35#include "nweb_log.h"
36#include "ohos_adapter_helper.h"
37#include "parameters.h"
38#include "pixel_map.h"
39#include "pixel_map_napi.h"
40#include "web_errors.h"
41#include "webview_javascript_execute_callback.h"
42#include "webview_createpdf_execute_callback.h"
43
44#include "web_download_delegate.h"
45#include "web_download_manager.h"
46#include "arkweb_scheme_handler.h"
47#include "web_scheme_handler_request.h"
48
49namespace OHOS {
50namespace NWeb {
51using namespace NWebError;
52using NWebError::NO_ERROR;
53
54namespace {
55constexpr uint32_t URL_MAXIMUM = 2048;
56constexpr uint32_t SOCKET_MAXIMUM = 6;
57constexpr char URL_REGEXPR[] = "^http(s)?:\\/\\/.+";
58constexpr size_t MAX_RESOURCES_COUNT = 30;
59constexpr size_t MAX_RESOURCE_SIZE = 10 * 1024 * 1024;
60constexpr size_t MAX_URL_TRUST_LIST_STR_LEN = 10 * 1024 * 1024; // 10M
61constexpr double A4_WIDTH = 8.27;
62constexpr double A4_HEIGHT = 11.69;
63constexpr double SCALE_MIN = 0.1;
64constexpr double SCALE_MAX = 2.0;
65constexpr double HALF = 2.0;
66constexpr double TEN_MILLIMETER_TO_INCH = 0.39;
67constexpr size_t BFCACHE_DEFAULT_SIZE = 1;
68constexpr size_t BFCACHE_DEFAULT_TIMETOLIVE = 600;
69using WebPrintWriteResultCallback = std::function<void(std::string, uint32_t)>;
70
71bool ParsePrepareUrl(napi_env env, napi_value urlObj, std::string& url)
72{
73    napi_valuetype valueType = napi_null;
74    napi_typeof(env, urlObj, &valueType);
75
76    if (valueType == napi_string) {
77        NapiParseUtils::ParseString(env, urlObj, url);
78        if (url.size() > URL_MAXIMUM) {
79            WVLOG_E("The URL exceeds the maximum length of %{public}d", URL_MAXIMUM);
80            return false;
81        }
82
83        if (!regex_match(url, std::regex(URL_REGEXPR, std::regex_constants::icase))) {
84            WVLOG_E("ParsePrepareUrl error");
85            return false;
86        }
87
88        return true;
89    }
90
91    WVLOG_E("Unable to parse type from url object.");
92    return false;
93}
94
95bool ParseIP(napi_env env, napi_value urlObj, std::string& ip)
96{
97    napi_valuetype valueType = napi_null;
98    napi_typeof(env, urlObj, &valueType);
99
100    if (valueType == napi_string) {
101        NapiParseUtils::ParseString(env, urlObj, ip);
102        if (ip == "") {
103            WVLOG_E("The IP is null");
104            return false;
105        }
106
107        unsigned char buf[sizeof(struct in6_addr)];
108        if ((inet_pton(AF_INET, ip.c_str(), buf) == 1) || (inet_pton(AF_INET6, ip.c_str(), buf) == 1)) {
109            return true;
110        }
111        WVLOG_E("IP error.");
112        return false;
113    }
114
115    WVLOG_E("Unable to parse type from ip object.");
116    return false;
117}
118
119napi_valuetype GetArrayValueType(napi_env env, napi_value array, bool& isDouble)
120{
121    uint32_t arrayLength = 0;
122    napi_get_array_length(env, array, &arrayLength);
123    napi_valuetype valueTypeFirst = napi_undefined;
124    napi_valuetype valueTypeCur = napi_undefined;
125    for (uint32_t i = 0; i < arrayLength; ++i) {
126        napi_value obj = nullptr;
127        napi_get_element(env, array, i, &obj);
128        napi_typeof(env, obj, &valueTypeCur);
129        if (i == 0) {
130            valueTypeFirst = valueTypeCur;
131        }
132        if (valueTypeCur != napi_string && valueTypeCur != napi_number && valueTypeCur != napi_boolean) {
133            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
134            return napi_undefined;
135        }
136        if (valueTypeCur != valueTypeFirst) {
137            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
138            return napi_undefined;
139        }
140        if (valueTypeFirst == napi_number) {
141            int32_t elementInt32 = 0;
142            double elementDouble = 0.0;
143            bool isReadValue32 = napi_get_value_int32(env, obj, &elementInt32) == napi_ok;
144            bool isReadDouble = napi_get_value_double(env, obj, &elementDouble) == napi_ok;
145            constexpr double MINIMAL_ERROR = 0.000001;
146            if (isReadValue32 && isReadDouble) {
147                isDouble = abs(elementDouble - elementInt32 * 1.0) > MINIMAL_ERROR;
148            } else if (isReadDouble) {
149                isDouble = true;
150            }
151        }
152    }
153    return valueTypeFirst;
154}
155
156void SetArrayHandlerBoolean(napi_env env, napi_value array, WebMessageExt* webMessageExt)
157{
158    std::vector<bool> outValue;
159    if (!NapiParseUtils::ParseBooleanArray(env, array, outValue)) {
160        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
161        return;
162    }
163    webMessageExt->SetBooleanArray(outValue);
164}
165
166void SetArrayHandlerString(napi_env env, napi_value array, WebMessageExt* webMessageExt)
167{
168    std::vector<std::string> outValue;
169    if (!NapiParseUtils::ParseStringArray(env, array, outValue)) {
170        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
171        return;
172    }
173    webMessageExt->SetStringArray(outValue);
174}
175
176void SetArrayHandlerInteger(napi_env env, napi_value array, WebMessageExt* webMessageExt)
177{
178    std::vector<int64_t> outValue;
179    if (!NapiParseUtils::ParseInt64Array(env, array, outValue)) {
180        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
181        return;
182    }
183    webMessageExt->SetInt64Array(outValue);
184}
185
186void SetArrayHandlerDouble(napi_env env, napi_value array, WebMessageExt* webMessageExt)
187{
188    std::vector<double> outValue;
189    if (!NapiParseUtils::ParseDoubleArray(env, array, outValue)) {
190        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
191        return;
192    }
193    webMessageExt->SetDoubleArray(outValue);
194}
195
196WebviewController* GetWebviewController(napi_env env, napi_callback_info info)
197{
198    napi_value thisVar = nullptr;
199    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
200
201    WebviewController *webviewController = nullptr;
202    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
203    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
204        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
205        return nullptr;
206    }
207    return webviewController;
208}
209
210bool ParsePrepareRequestMethod(napi_env env, napi_value methodObj, std::string& method)
211{
212    napi_valuetype valueType = napi_null;
213    napi_typeof(env, methodObj, &valueType);
214
215    if (valueType == napi_string) {
216        NapiParseUtils::ParseString(env, methodObj, method);
217        if (method != "POST") {
218            WVLOG_E("The method %{public}s is not supported.", method.c_str());
219            return false;
220        }
221        return true;
222    }
223
224    WVLOG_E("Unable to parse type from method object.");
225    return false;
226}
227
228bool ParseHttpHeaders(napi_env env, napi_value headersArray, std::map<std::string, std::string>* headers)
229{
230    bool isArray = false;
231    napi_is_array(env, headersArray, &isArray);
232    if (isArray) {
233        uint32_t arrayLength = INTEGER_ZERO;
234        napi_get_array_length(env, headersArray, &arrayLength);
235        for (uint32_t i = 0; i < arrayLength; ++i) {
236            std::string key;
237            std::string value;
238            napi_value obj = nullptr;
239            napi_value keyObj = nullptr;
240            napi_value valueObj = nullptr;
241            napi_get_element(env, headersArray, i, &obj);
242            if (napi_get_named_property(env, obj, "headerKey", &keyObj) != napi_ok) {
243                continue;
244            }
245            if (napi_get_named_property(env, obj, "headerValue", &valueObj) != napi_ok) {
246                continue;
247            }
248            if (!NapiParseUtils::ParseString(env, keyObj, key) || !NapiParseUtils::ParseString(env, valueObj, value)) {
249                WVLOG_E("Unable to parse string from headers array object.");
250                return false;
251            }
252            if (key.empty()) {
253                WVLOG_E("Key from headers is empty.");
254                return false;
255            }
256            (*headers)[key] = value;
257        }
258    } else {
259        WVLOG_E("Unable to parse type from headers array object.");
260        return false;
261    }
262    return true;
263}
264
265bool CheckCacheKey(napi_env env, const std::string& cacheKey)
266{
267    for (char c : cacheKey) {
268        if (!isalnum(c)) {
269            WVLOG_E("BusinessError: 401. The character of 'cacheKey' must be number or letters.");
270            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
271            return false;
272        }
273    }
274    return true;
275}
276
277bool ParseCacheKeyList(napi_env env, napi_value cacheKeyArray, std::vector<std::string>* cacheKeyList)
278{
279    bool isArray = false;
280    napi_is_array(env, cacheKeyArray, &isArray);
281    if (!isArray) {
282        WVLOG_E("Unable to parse type from CacheKey array object.");
283        return false;
284    }
285    uint32_t arrayLength = INTEGER_ZERO;
286    napi_get_array_length(env, cacheKeyArray, &arrayLength);
287    if (arrayLength == 0) {
288        WVLOG_E("cacheKey array length is invalid");
289        return false;
290    }
291    for (uint32_t i = 0; i < arrayLength; ++i) {
292        napi_value cacheKeyItem = nullptr;
293        napi_get_element(env, cacheKeyArray, i, &cacheKeyItem);
294        std::string cacheKeyStr;
295        if (!NapiParseUtils::ParseString(env, cacheKeyItem, cacheKeyStr)) {
296            WVLOG_E("Unable to parse string from cacheKey array object.");
297            return false;
298        }
299        if (cacheKeyStr.empty()) {
300            WVLOG_E("Cache Key is empty.");
301            return false;
302        }
303        for (char c : cacheKeyStr) {
304            if (!isalnum(c)) {
305                WVLOG_E("Cache Key is invalid.");
306                return false;
307            }
308        }
309        cacheKeyList->emplace_back(cacheKeyStr);
310    }
311    return true;
312}
313
314std::shared_ptr<NWebEnginePrefetchArgs> ParsePrefetchArgs(napi_env env, napi_value preArgs)
315{
316    napi_value urlObj = nullptr;
317    std::string url;
318    napi_get_named_property(env, preArgs, "url", &urlObj);
319    if (!ParsePrepareUrl(env, urlObj, url)) {
320        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
321        return nullptr;
322    }
323
324    napi_value methodObj = nullptr;
325    std::string method;
326    napi_get_named_property(env, preArgs, "method", &methodObj);
327    if (!ParsePrepareRequestMethod(env, methodObj, method)) {
328        WVLOG_E("BusinessError: 401. The type of 'method' must be string 'POST'.");
329        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
330        return nullptr;
331    }
332
333    napi_value formDataObj = nullptr;
334    std::string formData;
335    napi_get_named_property(env, preArgs, "formData", &formDataObj);
336    if (!NapiParseUtils::ParseString(env, formDataObj, formData)) {
337        WVLOG_E("BusinessError: 401. The type of 'formData' must be string.");
338        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
339        return nullptr;
340    }
341    std::shared_ptr<NWebEnginePrefetchArgs> prefetchArgs = std::make_shared<NWebEnginePrefetchArgsImpl>(
342        url, method, formData);
343    return prefetchArgs;
344}
345
346PDFMarginConfig ParsePDFMarginConfigArgs(napi_env env, napi_value preArgs, double width, double height)
347{
348    napi_value marginTopObj = nullptr;
349    double marginTop = TEN_MILLIMETER_TO_INCH;
350    napi_get_named_property(env, preArgs, "marginTop", &marginTopObj);
351    if (!NapiParseUtils::ParseDouble(env, marginTopObj, marginTop)) {
352        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
353            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "marginTop", "number"));
354        return PDFMarginConfig();
355    }
356    marginTop = (marginTop >= height / HALF || marginTop <= 0.0) ? 0.0 : marginTop;
357
358    napi_value marginBottomObj = nullptr;
359    double marginBottom = TEN_MILLIMETER_TO_INCH;
360    napi_get_named_property(env, preArgs, "marginBottom", &marginBottomObj);
361    if (!NapiParseUtils::ParseDouble(env, marginBottomObj, marginBottom)) {
362        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
363            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "marginBottom", "number"));
364        return PDFMarginConfig();
365    }
366    marginBottom = (marginBottom >= height / HALF || marginBottom <= 0.0) ? 0.0 : marginBottom;
367
368    napi_value marginRightObj = nullptr;
369    double marginRight = TEN_MILLIMETER_TO_INCH;
370    napi_get_named_property(env, preArgs, "marginRight", &marginRightObj);
371    if (!NapiParseUtils::ParseDouble(env, marginRightObj, marginRight)) {
372        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
373            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "marginRight", "number"));
374        return PDFMarginConfig();
375    }
376    marginRight = (marginRight >= width / HALF || marginRight <= 0.0) ? 0.0 : marginRight;
377
378    napi_value marginLeftObj = nullptr;
379    double marginLeft = TEN_MILLIMETER_TO_INCH;
380    napi_get_named_property(env, preArgs, "marginLeft", &marginLeftObj);
381    if (!NapiParseUtils::ParseDouble(env, marginLeftObj, marginLeft)) {
382        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
383            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "marginLeft", "number"));
384        return PDFMarginConfig();
385    }
386    marginLeft = (marginLeft >= width / HALF || marginLeft <= 0.0) ? 0.0 : marginLeft;
387
388    return { marginTop, marginBottom, marginRight, marginLeft };
389}
390
391std::shared_ptr<NWebPDFConfigArgs> ParsePDFConfigArgs(napi_env env, napi_value preArgs)
392{
393    napi_value widthObj = nullptr;
394    double width = A4_WIDTH;
395    napi_get_named_property(env, preArgs, "width", &widthObj);
396    if (!NapiParseUtils::ParseDouble(env, widthObj, width)) {
397        BusinessError::ThrowErrorByErrcode(
398            env, PARAM_CHECK_ERROR, NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "width", "number"));
399        return nullptr;
400    }
401
402    napi_value heightObj = nullptr;
403    double height = A4_HEIGHT;
404    napi_get_named_property(env, preArgs, "height", &heightObj);
405    if (!NapiParseUtils::ParseDouble(env, heightObj, height)) {
406        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
407            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "height", "number"));
408        return nullptr;
409    }
410
411    napi_value scaleObj = nullptr;
412    double scale = 1.0;
413    napi_get_named_property(env, preArgs, "scale", &scaleObj);
414    NapiParseUtils::ParseDouble(env, scaleObj, scale);
415    scale = scale > SCALE_MAX ? SCALE_MAX : scale < SCALE_MIN ? SCALE_MIN : scale;
416
417    auto margin = ParsePDFMarginConfigArgs(env, preArgs, width, height);
418
419    napi_value shouldPrintBackgroundObj = nullptr;
420    bool shouldPrintBackground = false;
421    napi_get_named_property(env, preArgs, "shouldPrintBackground", &shouldPrintBackgroundObj);
422    NapiParseUtils::ParseBoolean(env, shouldPrintBackgroundObj, shouldPrintBackground);
423
424    std::shared_ptr<NWebPDFConfigArgs> pdfConfig = std::make_shared<NWebPDFConfigArgsImpl>(
425        width, height, scale, margin.top, margin.bottom, margin.right, margin.left, shouldPrintBackground);
426    return pdfConfig;
427}
428
429void JsErrorCallback(napi_env env, napi_ref jsCallback, int32_t err)
430{
431    napi_value jsError = nullptr;
432    napi_value jsResult = nullptr;
433
434    jsError = BusinessError::CreateError(env, err);
435    napi_get_undefined(env, &jsResult);
436    napi_value args[INTEGER_TWO] = {jsError, jsResult};
437
438    napi_value callback = nullptr;
439    napi_value callbackResult = nullptr;
440    napi_get_reference_value(env, jsCallback, &callback);
441    napi_call_function(env, nullptr, callback, INTEGER_TWO, args, &callbackResult);
442    napi_delete_reference(env, jsCallback);
443}
444
445bool ParseRegisterJavaScriptProxyParam(napi_env env, size_t argc, napi_value* argv,
446    RegisterJavaScriptProxyParam* param)
447{
448    std::string objName;
449    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], objName)) {
450        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
451            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "name", "string"));
452        return false;
453    }
454    std::vector<std::string> methodList;
455    if (!NapiParseUtils::ParseStringArray(env, argv[INTEGER_TWO], methodList)) {
456        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
457            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "methodList", "array"));
458        return false;
459    }
460    std::vector<std::string> asyncMethodList;
461    if (argc == INTEGER_FOUR && !NapiParseUtils::ParseStringArray(env, argv[INTEGER_THREE], asyncMethodList)) {
462        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
463        return false;
464    }
465    std::string permission;
466    if (argc == INTEGER_FIVE && !NapiParseUtils::ParseString(env, argv[INTEGER_FOUR], permission)) {
467        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
468            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "permission", "string"));
469        return false;
470    }
471    param->env = env;
472    param->obj = argv[INTEGER_ZERO];
473    param->objName = objName;
474    param->syncMethodList = methodList;
475    param->asyncMethodList = asyncMethodList;
476    param->permission = permission;
477    return true;
478}
479
480napi_value RemoveDownloadDelegateRef(napi_env env, napi_value thisVar)
481{
482    WebviewController *webviewController = nullptr;
483    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
484    if (webviewController == nullptr || !webviewController->IsInit()) {
485        WVLOG_E("create message port failed, napi unwrap webviewController failed");
486        return nullptr;
487    }
488
489    WebDownloadManager::RemoveDownloadDelegateRef(webviewController->GetWebId());
490    return nullptr;
491}
492
493} // namespace
494
495int32_t NapiWebviewController::maxFdNum_ = -1;
496std::atomic<int32_t> NapiWebviewController::usedFd_ {0};
497std::atomic<bool> g_inWebPageSnapshot {false};
498
499thread_local napi_ref g_classWebMsgPort;
500thread_local napi_ref g_historyListRef;
501thread_local napi_ref g_webMsgExtClassRef;
502thread_local napi_ref g_webPrintDocClassRef;
503napi_value NapiWebviewController::Init(napi_env env, napi_value exports)
504{
505    napi_property_descriptor properties[] = {
506        DECLARE_NAPI_STATIC_FUNCTION("initializeWebEngine", NapiWebviewController::InitializeWebEngine),
507        DECLARE_NAPI_STATIC_FUNCTION("setHttpDns", NapiWebviewController::SetHttpDns),
508        DECLARE_NAPI_STATIC_FUNCTION("setWebDebuggingAccess", NapiWebviewController::SetWebDebuggingAccess),
509        DECLARE_NAPI_STATIC_FUNCTION("setServiceWorkerWebSchemeHandler",
510                                     NapiWebviewController::SetServiceWorkerWebSchemeHandler),
511        DECLARE_NAPI_STATIC_FUNCTION("clearServiceWorkerWebSchemeHandler",
512                                     NapiWebviewController::ClearServiceWorkerWebSchemeHandler),
513        DECLARE_NAPI_FUNCTION("getWebDebuggingAccess", NapiWebviewController::InnerGetWebDebuggingAccess),
514        DECLARE_NAPI_FUNCTION("setWebId", NapiWebviewController::SetWebId),
515        DECLARE_NAPI_FUNCTION("jsProxy", NapiWebviewController::InnerJsProxy),
516        DECLARE_NAPI_FUNCTION("getCustomeSchemeCmdLine", NapiWebviewController::InnerGetCustomeSchemeCmdLine),
517        DECLARE_NAPI_FUNCTION("accessForward", NapiWebviewController::AccessForward),
518        DECLARE_NAPI_FUNCTION("accessBackward", NapiWebviewController::AccessBackward),
519        DECLARE_NAPI_FUNCTION("accessStep", NapiWebviewController::AccessStep),
520        DECLARE_NAPI_FUNCTION("clearHistory", NapiWebviewController::ClearHistory),
521        DECLARE_NAPI_FUNCTION("forward", NapiWebviewController::Forward),
522        DECLARE_NAPI_FUNCTION("backward", NapiWebviewController::Backward),
523        DECLARE_NAPI_FUNCTION("onActive", NapiWebviewController::OnActive),
524        DECLARE_NAPI_FUNCTION("onInactive", NapiWebviewController::OnInactive),
525        DECLARE_NAPI_FUNCTION("refresh", NapiWebviewController::Refresh),
526        DECLARE_NAPI_FUNCTION("zoomIn", NapiWebviewController::ZoomIn),
527        DECLARE_NAPI_FUNCTION("zoomOut", NapiWebviewController::ZoomOut),
528        DECLARE_NAPI_FUNCTION("getWebId", NapiWebviewController::GetWebId),
529        DECLARE_NAPI_FUNCTION("getUserAgent", NapiWebviewController::GetUserAgent),
530        DECLARE_NAPI_FUNCTION("getCustomUserAgent", NapiWebviewController::GetCustomUserAgent),
531        DECLARE_NAPI_FUNCTION("setCustomUserAgent", NapiWebviewController::SetCustomUserAgent),
532        DECLARE_NAPI_FUNCTION("getTitle", NapiWebviewController::GetTitle),
533        DECLARE_NAPI_FUNCTION("getPageHeight", NapiWebviewController::GetPageHeight),
534        DECLARE_NAPI_FUNCTION("backOrForward", NapiWebviewController::BackOrForward),
535        DECLARE_NAPI_FUNCTION("storeWebArchive", NapiWebviewController::StoreWebArchive),
536        DECLARE_NAPI_FUNCTION("createWebMessagePorts", NapiWebviewController::CreateWebMessagePorts),
537        DECLARE_NAPI_FUNCTION("postMessage", NapiWebviewController::PostMessage),
538        DECLARE_NAPI_FUNCTION("getHitTestValue", NapiWebviewController::GetHitTestValue),
539        DECLARE_NAPI_FUNCTION("requestFocus", NapiWebviewController::RequestFocus),
540        DECLARE_NAPI_FUNCTION("loadUrl", NapiWebviewController::LoadUrl),
541        DECLARE_NAPI_FUNCTION("postUrl", NapiWebviewController::PostUrl),
542        DECLARE_NAPI_FUNCTION("loadData", NapiWebviewController::LoadData),
543        DECLARE_NAPI_FUNCTION("getHitTest", NapiWebviewController::GetHitTest),
544        DECLARE_NAPI_FUNCTION("clearMatches", NapiWebviewController::ClearMatches),
545        DECLARE_NAPI_FUNCTION("searchNext", NapiWebviewController::SearchNext),
546        DECLARE_NAPI_FUNCTION("searchAllAsync", NapiWebviewController::SearchAllAsync),
547        DECLARE_NAPI_FUNCTION("clearSslCache", NapiWebviewController::ClearSslCache),
548        DECLARE_NAPI_FUNCTION("clearClientAuthenticationCache", NapiWebviewController::ClearClientAuthenticationCache),
549        DECLARE_NAPI_FUNCTION("stop", NapiWebviewController::Stop),
550        DECLARE_NAPI_FUNCTION("zoom", NapiWebviewController::Zoom),
551        DECLARE_NAPI_FUNCTION("registerJavaScriptProxy", NapiWebviewController::RegisterJavaScriptProxy),
552        DECLARE_NAPI_FUNCTION("innerCompleteWindowNew", NapiWebviewController::InnerCompleteWindowNew),
553        DECLARE_NAPI_FUNCTION("deleteJavaScriptRegister", NapiWebviewController::DeleteJavaScriptRegister),
554        DECLARE_NAPI_FUNCTION("runJavaScript", NapiWebviewController::RunJavaScript),
555        DECLARE_NAPI_FUNCTION("runJavaScriptExt", NapiWebviewController::RunJavaScriptExt),
556        DECLARE_NAPI_FUNCTION("getUrl", NapiWebviewController::GetUrl),
557        DECLARE_NAPI_FUNCTION("terminateRenderProcess", NapiWebviewController::TerminateRenderProcess),
558        DECLARE_NAPI_FUNCTION("getOriginalUrl", NapiWebviewController::GetOriginalUrl),
559        DECLARE_NAPI_FUNCTION("setNetworkAvailable", NapiWebviewController::SetNetworkAvailable),
560        DECLARE_NAPI_FUNCTION("innerGetWebId", NapiWebviewController::InnerGetWebId),
561        DECLARE_NAPI_FUNCTION("hasImage", NapiWebviewController::HasImage),
562        DECLARE_NAPI_FUNCTION("removeCache", NapiWebviewController::RemoveCache),
563        DECLARE_NAPI_FUNCTION("getFavicon", NapiWebviewController::GetFavicon),
564        DECLARE_NAPI_FUNCTION("getBackForwardEntries", NapiWebviewController::getBackForwardEntries),
565        DECLARE_NAPI_FUNCTION("serializeWebState", NapiWebviewController::SerializeWebState),
566        DECLARE_NAPI_FUNCTION("restoreWebState", NapiWebviewController::RestoreWebState),
567        DECLARE_NAPI_FUNCTION("pageDown", NapiWebviewController::ScrollPageDown),
568        DECLARE_NAPI_FUNCTION("pageUp", NapiWebviewController::ScrollPageUp),
569        DECLARE_NAPI_FUNCTION("scrollTo", NapiWebviewController::ScrollTo),
570        DECLARE_NAPI_FUNCTION("scrollBy", NapiWebviewController::ScrollBy),
571        DECLARE_NAPI_FUNCTION("slideScroll", NapiWebviewController::SlideScroll),
572        DECLARE_NAPI_FUNCTION("setScrollable", NapiWebviewController::SetScrollable),
573        DECLARE_NAPI_FUNCTION("getScrollable", NapiWebviewController::GetScrollable),
574        DECLARE_NAPI_STATIC_FUNCTION("customizeSchemes", NapiWebviewController::CustomizeSchemes),
575        DECLARE_NAPI_FUNCTION("innerSetHapPath", NapiWebviewController::InnerSetHapPath),
576        DECLARE_NAPI_FUNCTION("innerGetCertificate", NapiWebviewController::InnerGetCertificate),
577        DECLARE_NAPI_FUNCTION("setAudioMuted", NapiWebviewController::SetAudioMuted),
578        DECLARE_NAPI_FUNCTION("innerGetThisVar", NapiWebviewController::InnerGetThisVar),
579        DECLARE_NAPI_FUNCTION("prefetchPage", NapiWebviewController::PrefetchPage),
580        DECLARE_NAPI_FUNCTION("setDownloadDelegate", NapiWebviewController::SetDownloadDelegate),
581        DECLARE_NAPI_FUNCTION("startDownload", NapiWebviewController::StartDownload),
582        DECLARE_NAPI_STATIC_FUNCTION("prepareForPageLoad", NapiWebviewController::PrepareForPageLoad),
583        DECLARE_NAPI_FUNCTION("createWebPrintDocumentAdapter", NapiWebviewController::CreateWebPrintDocumentAdapter),
584        DECLARE_NAPI_STATIC_FUNCTION("setConnectionTimeout", NapiWebviewController::SetConnectionTimeout),
585        DECLARE_NAPI_FUNCTION("enableSafeBrowsing", NapiWebviewController::EnableSafeBrowsing),
586        DECLARE_NAPI_FUNCTION("isSafeBrowsingEnabled", NapiWebviewController::IsSafeBrowsingEnabled),
587        DECLARE_NAPI_FUNCTION("getSecurityLevel", NapiWebviewController::GetSecurityLevel),
588        DECLARE_NAPI_FUNCTION("isIncognitoMode", NapiWebviewController::IsIncognitoMode),
589        DECLARE_NAPI_FUNCTION("setPrintBackground", NapiWebviewController::SetPrintBackground),
590        DECLARE_NAPI_FUNCTION("getPrintBackground", NapiWebviewController::GetPrintBackground),
591        DECLARE_NAPI_FUNCTION("setWebSchemeHandler", NapiWebviewController::SetWebSchemeHandler),
592        DECLARE_NAPI_FUNCTION("clearWebSchemeHandler", NapiWebviewController::ClearWebSchemeHandler),
593        DECLARE_NAPI_FUNCTION("enableIntelligentTrackingPrevention",
594            NapiWebviewController::EnableIntelligentTrackingPrevention),
595        DECLARE_NAPI_FUNCTION("isIntelligentTrackingPreventionEnabled",
596            NapiWebviewController::IsIntelligentTrackingPreventionEnabled),
597        DECLARE_NAPI_STATIC_FUNCTION("addIntelligentTrackingPreventionBypassingList",
598            NapiWebviewController::AddIntelligentTrackingPreventionBypassingList),
599        DECLARE_NAPI_STATIC_FUNCTION("removeIntelligentTrackingPreventionBypassingList",
600            NapiWebviewController::RemoveIntelligentTrackingPreventionBypassingList),
601        DECLARE_NAPI_STATIC_FUNCTION("clearIntelligentTrackingPreventionBypassingList",
602            NapiWebviewController::ClearIntelligentTrackingPreventionBypassingList),
603        DECLARE_NAPI_FUNCTION("getLastJavascriptProxyCallingFrameUrl",
604            NapiWebviewController::GetLastJavascriptProxyCallingFrameUrl),
605        DECLARE_NAPI_STATIC_FUNCTION("getDefaultUserAgent", NapiWebviewController::GetDefaultUserAgent),
606        DECLARE_NAPI_STATIC_FUNCTION("pauseAllTimers", NapiWebviewController::PauseAllTimers),
607        DECLARE_NAPI_STATIC_FUNCTION("resumeAllTimers", NapiWebviewController::ResumeAllTimers),
608        DECLARE_NAPI_FUNCTION("startCamera", NapiWebviewController::StartCamera),
609        DECLARE_NAPI_FUNCTION("stopCamera", NapiWebviewController::StopCamera),
610        DECLARE_NAPI_FUNCTION("closeCamera", NapiWebviewController::CloseCamera),
611        DECLARE_NAPI_FUNCTION("closeAllMediaPresentations", NapiWebviewController::CloseAllMediaPresentations),
612        DECLARE_NAPI_FUNCTION("stopAllMedia", NapiWebviewController::StopAllMedia),
613        DECLARE_NAPI_FUNCTION("resumeAllMedia", NapiWebviewController::ResumeAllMedia),
614        DECLARE_NAPI_FUNCTION("pauseAllMedia", NapiWebviewController::PauseAllMedia),
615        DECLARE_NAPI_FUNCTION("getMediaPlaybackState", NapiWebviewController::GetMediaPlaybackState),
616        DECLARE_NAPI_FUNCTION("onCreateNativeMediaPlayer", NapiWebviewController::OnCreateNativeMediaPlayer),
617        DECLARE_NAPI_STATIC_FUNCTION("prefetchResource", NapiWebviewController::PrefetchResource),
618        DECLARE_NAPI_STATIC_FUNCTION("clearPrefetchedResource", NapiWebviewController::ClearPrefetchedResource),
619        DECLARE_NAPI_STATIC_FUNCTION("setRenderProcessMode", NapiWebviewController::SetRenderProcessMode),
620        DECLARE_NAPI_STATIC_FUNCTION("getRenderProcessMode", NapiWebviewController::GetRenderProcessMode),
621        DECLARE_NAPI_FUNCTION("precompileJavaScript", NapiWebviewController::PrecompileJavaScript),
622        DECLARE_NAPI_FUNCTION("injectOfflineResources", NapiWebviewController::InjectOfflineResources),
623        DECLARE_NAPI_STATIC_FUNCTION("setHostIP", NapiWebviewController::SetHostIP),
624        DECLARE_NAPI_STATIC_FUNCTION("clearHostIP", NapiWebviewController::ClearHostIP),
625        DECLARE_NAPI_STATIC_FUNCTION("warmupServiceWorker", NapiWebviewController::WarmupServiceWorker),
626        DECLARE_NAPI_FUNCTION("getSurfaceId", NapiWebviewController::GetSurfaceId),
627        DECLARE_NAPI_STATIC_FUNCTION("enableWholeWebPageDrawing", NapiWebviewController::EnableWholeWebPageDrawing),
628        DECLARE_NAPI_FUNCTION("enableAdsBlock", NapiWebviewController::EnableAdsBlock),
629        DECLARE_NAPI_FUNCTION("isAdsBlockEnabled", NapiWebviewController::IsAdsBlockEnabled),
630        DECLARE_NAPI_FUNCTION("isAdsBlockEnabledForCurPage", NapiWebviewController::IsAdsBlockEnabledForCurPage),
631        DECLARE_NAPI_FUNCTION("webPageSnapshot", NapiWebviewController::WebPageSnapshot),
632        DECLARE_NAPI_FUNCTION("setUrlTrustList", NapiWebviewController::SetUrlTrustList),
633        DECLARE_NAPI_FUNCTION("setPathAllowingUniversalAccess",
634            NapiWebviewController::SetPathAllowingUniversalAccess),
635        DECLARE_NAPI_STATIC_FUNCTION("enableBackForwardCache", NapiWebviewController::EnableBackForwardCache),
636        DECLARE_NAPI_FUNCTION("setBackForwardCacheOptions", NapiWebviewController::SetBackForwardCacheOptions),
637        DECLARE_NAPI_FUNCTION("scrollByWithResult", NapiWebviewController::ScrollByWithResult),
638        DECLARE_NAPI_FUNCTION("updateInstanceId", NapiWebviewController::UpdateInstanceId),
639        DECLARE_NAPI_STATIC_FUNCTION("trimMemoryByPressureLevel",
640            NapiWebviewController::TrimMemoryByPressureLevel),
641        DECLARE_NAPI_FUNCTION("getScrollOffset",
642            NapiWebviewController::GetScrollOffset),
643        DECLARE_NAPI_FUNCTION("createPdf", NapiWebviewController::RunCreatePDFExt),
644    };
645    napi_value constructor = nullptr;
646    napi_define_class(env, WEBVIEW_CONTROLLER_CLASS_NAME.c_str(), WEBVIEW_CONTROLLER_CLASS_NAME.length(),
647        NapiWebviewController::JsConstructor, nullptr, sizeof(properties) / sizeof(properties[0]),
648        properties, &constructor);
649    NAPI_ASSERT(env, constructor != nullptr, "define js class WebviewController failed");
650    napi_status status = napi_set_named_property(env, exports, "WebviewController", constructor);
651    NAPI_ASSERT(env, status == napi_ok, "set property WebviewController failed");
652
653    napi_value webMsgTypeEnum = nullptr;
654    napi_property_descriptor webMsgTypeProperties[] = {
655        DECLARE_NAPI_STATIC_PROPERTY("NOT_SUPPORT", NapiParseUtils::ToInt32Value(env,
656            static_cast<int32_t>(WebMessageType::NOTSUPPORT))),
657        DECLARE_NAPI_STATIC_PROPERTY("STRING", NapiParseUtils::ToInt32Value(env,
658            static_cast<int32_t>(WebMessageType::STRING))),
659        DECLARE_NAPI_STATIC_PROPERTY("NUMBER", NapiParseUtils::ToInt32Value(env,
660            static_cast<int32_t>(WebMessageType::NUMBER))),
661        DECLARE_NAPI_STATIC_PROPERTY("BOOLEAN", NapiParseUtils::ToInt32Value(env,
662            static_cast<int32_t>(WebMessageType::BOOLEAN))),
663        DECLARE_NAPI_STATIC_PROPERTY("ARRAY_BUFFER", NapiParseUtils::ToInt32Value(env,
664            static_cast<int32_t>(WebMessageType::ARRAYBUFFER))),
665        DECLARE_NAPI_STATIC_PROPERTY("ARRAY", NapiParseUtils::ToInt32Value(env,
666            static_cast<int32_t>(WebMessageType::ARRAY))),
667        DECLARE_NAPI_STATIC_PROPERTY("ERROR", NapiParseUtils::ToInt32Value(env,
668            static_cast<int32_t>(WebMessageType::ERROR)))
669    };
670    napi_define_class(env, WEB_PORT_MSG_ENUM_NAME.c_str(), WEB_PORT_MSG_ENUM_NAME.length(),
671        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(webMsgTypeProperties) /
672        sizeof(webMsgTypeProperties[0]), webMsgTypeProperties, &webMsgTypeEnum);
673    napi_set_named_property(env, exports, WEB_PORT_MSG_ENUM_NAME.c_str(), webMsgTypeEnum);
674
675    napi_value webMsgExtClass = nullptr;
676    napi_property_descriptor webMsgExtClsProperties[] = {
677        DECLARE_NAPI_FUNCTION("getType", NapiWebMessageExt::GetType),
678        DECLARE_NAPI_FUNCTION("getString", NapiWebMessageExt::GetString),
679        DECLARE_NAPI_FUNCTION("getNumber", NapiWebMessageExt::GetNumber),
680        DECLARE_NAPI_FUNCTION("getBoolean", NapiWebMessageExt::GetBoolean),
681        DECLARE_NAPI_FUNCTION("getArrayBuffer", NapiWebMessageExt::GetArrayBuffer),
682        DECLARE_NAPI_FUNCTION("getArray", NapiWebMessageExt::GetArray),
683        DECLARE_NAPI_FUNCTION("getError", NapiWebMessageExt::GetError),
684        DECLARE_NAPI_FUNCTION("setType", NapiWebMessageExt::SetType),
685        DECLARE_NAPI_FUNCTION("setString", NapiWebMessageExt::SetString),
686        DECLARE_NAPI_FUNCTION("setNumber", NapiWebMessageExt::SetNumber),
687        DECLARE_NAPI_FUNCTION("setBoolean", NapiWebMessageExt::SetBoolean),
688        DECLARE_NAPI_FUNCTION("setArrayBuffer", NapiWebMessageExt::SetArrayBuffer),
689        DECLARE_NAPI_FUNCTION("setArray", NapiWebMessageExt::SetArray),
690        DECLARE_NAPI_FUNCTION("setError", NapiWebMessageExt::SetError)
691    };
692    napi_define_class(env, WEB_EXT_MSG_CLASS_NAME.c_str(), WEB_EXT_MSG_CLASS_NAME.length(),
693        NapiWebMessageExt::JsConstructor, nullptr, sizeof(webMsgExtClsProperties) / sizeof(webMsgExtClsProperties[0]),
694        webMsgExtClsProperties, &webMsgExtClass);
695    napi_create_reference(env, webMsgExtClass, 1, &g_webMsgExtClassRef);
696    napi_set_named_property(env, exports, WEB_EXT_MSG_CLASS_NAME.c_str(), webMsgExtClass);
697
698    napi_value securityLevelEnum = nullptr;
699    napi_property_descriptor securityLevelProperties[] = {
700        DECLARE_NAPI_STATIC_PROPERTY("NONE", NapiParseUtils::ToInt32Value(env,
701            static_cast<int32_t>(SecurityLevel::NONE))),
702        DECLARE_NAPI_STATIC_PROPERTY("SECURE", NapiParseUtils::ToInt32Value(env,
703            static_cast<int32_t>(SecurityLevel::SECURE))),
704        DECLARE_NAPI_STATIC_PROPERTY("WARNING", NapiParseUtils::ToInt32Value(env,
705            static_cast<int32_t>(SecurityLevel::WARNING))),
706        DECLARE_NAPI_STATIC_PROPERTY("DANGEROUS", NapiParseUtils::ToInt32Value(env,
707            static_cast<int32_t>(SecurityLevel::DANGEROUS)))
708    };
709    napi_define_class(env, WEB_SECURITY_LEVEL_ENUM_NAME.c_str(), WEB_SECURITY_LEVEL_ENUM_NAME.length(),
710        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(securityLevelProperties) /
711        sizeof(securityLevelProperties[0]), securityLevelProperties, &securityLevelEnum);
712    napi_set_named_property(env, exports, WEB_SECURITY_LEVEL_ENUM_NAME.c_str(), securityLevelEnum);
713
714    napi_value msgPortCons = nullptr;
715    napi_property_descriptor msgPortProperties[] = {
716        DECLARE_NAPI_FUNCTION("close", NapiWebMessagePort::Close),
717        DECLARE_NAPI_FUNCTION("postMessageEvent", NapiWebMessagePort::PostMessageEvent),
718        DECLARE_NAPI_FUNCTION("onMessageEvent", NapiWebMessagePort::OnMessageEvent),
719        DECLARE_NAPI_FUNCTION("postMessageEventExt", NapiWebMessagePort::PostMessageEventExt),
720        DECLARE_NAPI_FUNCTION("onMessageEventExt", NapiWebMessagePort::OnMessageEventExt)
721    };
722    NAPI_CALL(env, napi_define_class(env, WEB_MESSAGE_PORT_CLASS_NAME.c_str(), WEB_MESSAGE_PORT_CLASS_NAME.length(),
723        NapiWebMessagePort::JsConstructor, nullptr, sizeof(msgPortProperties) / sizeof(msgPortProperties[0]),
724        msgPortProperties, &msgPortCons));
725    NAPI_CALL(env, napi_create_reference(env, msgPortCons, 1, &g_classWebMsgPort));
726    NAPI_CALL(env, napi_set_named_property(env, exports, WEB_MESSAGE_PORT_CLASS_NAME.c_str(), msgPortCons));
727
728    napi_value hitTestTypeEnum = nullptr;
729    napi_property_descriptor hitTestTypeProperties[] = {
730        DECLARE_NAPI_STATIC_PROPERTY("EditText", NapiParseUtils::ToInt32Value(env,
731            static_cast<int32_t>(WebHitTestType::EDIT))),
732        DECLARE_NAPI_STATIC_PROPERTY("Email", NapiParseUtils::ToInt32Value(env,
733            static_cast<int32_t>(WebHitTestType::EMAIL))),
734        DECLARE_NAPI_STATIC_PROPERTY("HttpAnchor", NapiParseUtils::ToInt32Value(env,
735            static_cast<int32_t>(WebHitTestType::HTTP))),
736        DECLARE_NAPI_STATIC_PROPERTY("HttpAnchorImg", NapiParseUtils::ToInt32Value(env,
737            static_cast<int32_t>(WebHitTestType::HTTP_IMG))),
738        DECLARE_NAPI_STATIC_PROPERTY("Img", NapiParseUtils::ToInt32Value(env,
739            static_cast<int32_t>(WebHitTestType::IMG))),
740        DECLARE_NAPI_STATIC_PROPERTY("Map", NapiParseUtils::ToInt32Value(env,
741            static_cast<int32_t>(WebHitTestType::MAP))),
742        DECLARE_NAPI_STATIC_PROPERTY("Phone", NapiParseUtils::ToInt32Value(env,
743            static_cast<int32_t>(WebHitTestType::PHONE))),
744        DECLARE_NAPI_STATIC_PROPERTY("Unknown", NapiParseUtils::ToInt32Value(env,
745            static_cast<int32_t>(WebHitTestType::UNKNOWN))),
746    };
747    napi_define_class(env, WEB_HITTESTTYPE_V9_ENUM_NAME.c_str(), WEB_HITTESTTYPE_V9_ENUM_NAME.length(),
748        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(hitTestTypeProperties) /
749        sizeof(hitTestTypeProperties[0]), hitTestTypeProperties, &hitTestTypeEnum);
750    napi_set_named_property(env, exports, WEB_HITTESTTYPE_V9_ENUM_NAME.c_str(), hitTestTypeEnum);
751
752    napi_define_class(env, WEB_HITTESTTYPE_ENUM_NAME.c_str(), WEB_HITTESTTYPE_ENUM_NAME.length(),
753        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(hitTestTypeProperties) /
754        sizeof(hitTestTypeProperties[0]), hitTestTypeProperties, &hitTestTypeEnum);
755    napi_set_named_property(env, exports, WEB_HITTESTTYPE_ENUM_NAME.c_str(), hitTestTypeEnum);
756
757    napi_value secureDnsModeEnum = nullptr;
758    napi_property_descriptor secureDnsModeProperties[] = {
759        DECLARE_NAPI_STATIC_PROPERTY("Off", NapiParseUtils::ToInt32Value(env,
760            static_cast<int32_t>(SecureDnsModeType::OFF))),
761        DECLARE_NAPI_STATIC_PROPERTY("Auto", NapiParseUtils::ToInt32Value(env,
762            static_cast<int32_t>(SecureDnsModeType::AUTO))),
763        DECLARE_NAPI_STATIC_PROPERTY("SecureOnly", NapiParseUtils::ToInt32Value(env,
764            static_cast<int32_t>(SecureDnsModeType::SECURE_ONLY))),
765        DECLARE_NAPI_STATIC_PROPERTY("OFF", NapiParseUtils::ToInt32Value(env,
766            static_cast<int32_t>(SecureDnsModeType::OFF))),
767        DECLARE_NAPI_STATIC_PROPERTY("AUTO", NapiParseUtils::ToInt32Value(env,
768            static_cast<int32_t>(SecureDnsModeType::AUTO))),
769        DECLARE_NAPI_STATIC_PROPERTY("SECURE_ONLY", NapiParseUtils::ToInt32Value(env,
770            static_cast<int32_t>(SecureDnsModeType::SECURE_ONLY))),
771    };
772    napi_define_class(env, WEB_SECURE_DNS_MODE_ENUM_NAME.c_str(), WEB_SECURE_DNS_MODE_ENUM_NAME.length(),
773        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(secureDnsModeProperties) /
774        sizeof(secureDnsModeProperties[0]), secureDnsModeProperties, &secureDnsModeEnum);
775    napi_set_named_property(env, exports, WEB_SECURE_DNS_MODE_ENUM_NAME.c_str(), secureDnsModeEnum);
776
777    napi_value historyList = nullptr;
778    napi_property_descriptor historyListProperties[] = {
779        DECLARE_NAPI_FUNCTION("getItemAtIndex", NapiWebHistoryList::GetItem)
780    };
781    napi_define_class(env, WEB_HISTORY_LIST_CLASS_NAME.c_str(), WEB_HISTORY_LIST_CLASS_NAME.length(),
782        NapiWebHistoryList::JsConstructor, nullptr, sizeof(historyListProperties) / sizeof(historyListProperties[0]),
783        historyListProperties, &historyList);
784    napi_create_reference(env, historyList, 1, &g_historyListRef);
785    napi_set_named_property(env, exports, WEB_HISTORY_LIST_CLASS_NAME.c_str(), historyList);
786
787    napi_value webPrintDoc = nullptr;
788    napi_property_descriptor WebPrintDocumentClass[] = {
789        DECLARE_NAPI_FUNCTION("onStartLayoutWrite", NapiWebPrintDocument::OnStartLayoutWrite),
790        DECLARE_NAPI_FUNCTION("onJobStateChanged", NapiWebPrintDocument::OnJobStateChanged),
791    };
792    napi_define_class(env, WEB_PRINT_DOCUMENT_CLASS_NAME.c_str(), WEB_PRINT_DOCUMENT_CLASS_NAME.length(),
793        NapiWebPrintDocument::JsConstructor, nullptr,
794        sizeof(WebPrintDocumentClass) / sizeof(WebPrintDocumentClass[0]),
795        WebPrintDocumentClass, &webPrintDoc);
796    napi_create_reference(env, webPrintDoc, 1, &g_webPrintDocClassRef);
797    napi_set_named_property(env, exports, WEB_PRINT_DOCUMENT_CLASS_NAME.c_str(), webPrintDoc);
798
799    napi_value renderProcessModeEnum = nullptr;
800    napi_property_descriptor renderProcessModeProperties[] = {
801        DECLARE_NAPI_STATIC_PROPERTY("SINGLE", NapiParseUtils::ToInt32Value(env,
802            static_cast<int32_t>(RenderProcessMode::SINGLE_MODE))),
803        DECLARE_NAPI_STATIC_PROPERTY("MULTIPLE", NapiParseUtils::ToInt32Value(env,
804            static_cast<int32_t>(RenderProcessMode::MULTIPLE_MODE))),
805    };
806    napi_define_class(env, WEB_RENDER_PROCESS_MODE_ENUM_NAME.c_str(), WEB_RENDER_PROCESS_MODE_ENUM_NAME.length(),
807        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(renderProcessModeProperties) /
808        sizeof(renderProcessModeProperties[0]), renderProcessModeProperties, &renderProcessModeEnum);
809    napi_set_named_property(env, exports, WEB_RENDER_PROCESS_MODE_ENUM_NAME.c_str(), renderProcessModeEnum);
810
811    napi_value offlineResourceTypeEnum = nullptr;
812    napi_property_descriptor offlineResourceTypeProperties[] = {
813        DECLARE_NAPI_STATIC_PROPERTY("IMAGE", NapiParseUtils::ToInt32Value(env,
814            static_cast<int32_t>(OfflineResourceType::IMAGE))),
815        DECLARE_NAPI_STATIC_PROPERTY("CSS", NapiParseUtils::ToInt32Value(env,
816            static_cast<int32_t>(OfflineResourceType::CSS))),
817        DECLARE_NAPI_STATIC_PROPERTY("CLASSIC_JS", NapiParseUtils::ToInt32Value(env,
818            static_cast<int32_t>(OfflineResourceType::CLASSIC_JS))),
819        DECLARE_NAPI_STATIC_PROPERTY("MODULE_JS", NapiParseUtils::ToInt32Value(env,
820            static_cast<int32_t>(OfflineResourceType::MODULE_JS))),
821    };
822    napi_define_class(env, OFFLINE_RESOURCE_TYPE_ENUM_NAME.c_str(), OFFLINE_RESOURCE_TYPE_ENUM_NAME.length(),
823        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(offlineResourceTypeProperties) /
824        sizeof(offlineResourceTypeProperties[0]), offlineResourceTypeProperties, &offlineResourceTypeEnum);
825    napi_set_named_property(env, exports, OFFLINE_RESOURCE_TYPE_ENUM_NAME.c_str(), offlineResourceTypeEnum);
826
827    napi_value pressureLevelEnum = nullptr;
828    napi_property_descriptor pressureLevelProperties[] = {
829        DECLARE_NAPI_STATIC_PROPERTY("MEMORY_PRESSURE_LEVEL_MODERATE", NapiParseUtils::ToInt32Value(env,
830            static_cast<int32_t>(PressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE))),
831        DECLARE_NAPI_STATIC_PROPERTY("MEMORY_PRESSURE_LEVEL_CRITICAL", NapiParseUtils::ToInt32Value(env,
832            static_cast<int32_t>(PressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL))),
833    };
834    napi_define_class(env, WEB_PRESSURE_LEVEL_ENUM_NAME.c_str(), WEB_PRESSURE_LEVEL_ENUM_NAME.length(),
835        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(pressureLevelProperties) /
836        sizeof(pressureLevelProperties[0]), pressureLevelProperties, &pressureLevelEnum);
837    napi_set_named_property(env, exports, WEB_PRESSURE_LEVEL_ENUM_NAME.c_str(), pressureLevelEnum);
838
839    napi_value scrollTypeEnum = nullptr;
840    napi_property_descriptor scrollTypeProperties[] = {
841        DECLARE_NAPI_STATIC_PROPERTY("EVENT", NapiParseUtils::ToInt32Value(env,
842            static_cast<int32_t>(ScrollType::EVENT))),
843    };
844    napi_define_class(env, WEB_SCROLL_TYPE_ENUM_NAME.c_str(), WEB_SCROLL_TYPE_ENUM_NAME.length(),
845        NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(scrollTypeProperties) /
846        sizeof(scrollTypeProperties[0]), scrollTypeProperties, &scrollTypeEnum);
847    napi_set_named_property(env, exports, WEB_SCROLL_TYPE_ENUM_NAME.c_str(), scrollTypeEnum);
848
849    WebviewJavaScriptExecuteCallback::InitJSExcute(env, exports);
850    WebviewCreatePDFExecuteCallback::InitJSExcute(env, exports);
851    return exports;
852}
853
854napi_value NapiWebviewController::JsConstructor(napi_env env, napi_callback_info info)
855{
856    WVLOG_I("NapiWebviewController::JsConstructor start");
857    napi_value thisVar = nullptr;
858
859    size_t argc = INTEGER_ONE;
860    napi_value argv[INTEGER_ONE] = { 0 };
861    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
862
863    WebviewController *webviewController;
864    std::string webTag;
865    if (argc == 1) {
866        NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], webTag);
867        if (webTag.empty()) {
868            WVLOG_E("native webTag is empty");
869            return nullptr;
870        }
871        webviewController = new (std::nothrow) WebviewController(webTag);
872        WVLOG_I("new webview controller webname:%{public}s", webTag.c_str());
873    } else {
874        webTag = WebviewController::GenerateWebTag();
875        webviewController = new (std::nothrow) WebviewController(webTag);
876    }
877    WebviewController::webTagSet_.insert(webTag);
878
879    if (webviewController == nullptr) {
880        WVLOG_E("new webview controller failed");
881        return nullptr;
882    }
883    napi_status status = napi_wrap(
884        env, thisVar, webviewController,
885        [](napi_env env, void *data, void *hint) {
886            WebviewController *webviewController = static_cast<WebviewController *>(data);
887            delete webviewController;
888        },
889        nullptr, nullptr);
890    if (status != napi_ok) {
891        WVLOG_E("Wrap native webviewController failed.");
892        return nullptr;
893    }
894    return thisVar;
895}
896
897napi_value NapiWebviewController::InitializeWebEngine(napi_env env, napi_callback_info info)
898{
899    WVLOG_D("InitializeWebEngine invoked.");
900
901    // obtain bundle path
902    std::shared_ptr<AbilityRuntime::ApplicationContext> ctx =
903        AbilityRuntime::ApplicationContext::GetApplicationContext();
904    if (!ctx) {
905        WVLOG_E("Failed to init web engine due to nil application context.");
906        return nullptr;
907    }
908
909    // load so
910    const std::string& bundlePath = ctx->GetBundleCodeDir();
911    NWebHelper::Instance().SetBundlePath(bundlePath);
912    if (!NWebHelper::Instance().InitAndRun(true)) {
913        WVLOG_E("Failed to init web engine due to NWebHelper failure.");
914        return nullptr;
915    }
916
917    napi_value result = nullptr;
918    NAPI_CALL(env, napi_get_undefined(env, &result));
919    WVLOG_I("NWebHelper initialized, init web engine done, bundle_path: %{public}s", bundlePath.c_str());
920    return result;
921}
922
923napi_value NapiWebviewController::SetHttpDns(napi_env env, napi_callback_info info)
924{
925    napi_value thisVar = nullptr;
926    napi_value result = nullptr;
927    size_t argc = INTEGER_TWO;
928    napi_value argv[INTEGER_TWO] = { 0 };
929    int dohMode;
930    std::string dohConfig;
931
932    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
933    if (argc != INTEGER_TWO) {
934        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
935            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "two"));
936        return result;
937    }
938
939    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], dohMode)) {
940        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
941            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "secureDnsMode", "SecureDnsMode"));
942        return result;
943    }
944
945    if (dohMode < static_cast<int>(SecureDnsModeType::OFF) ||
946        dohMode > static_cast<int>(SecureDnsModeType::SECURE_ONLY)) {
947        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
948            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "secureDnsMode"));
949        return result;
950    }
951
952    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], dohConfig)) {
953        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
954            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "secureDnsConfig", "string"));
955        return result;
956    }
957
958    if (dohConfig.rfind("https", 0) != 0 && dohConfig.rfind("HTTPS", 0) != 0) {
959        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
960            "BusinessError 401: Parameter error. Parameter secureDnsConfig must start with 'http' or 'https'.");
961        return result;
962    }
963
964    std::shared_ptr<NWebDOHConfigImpl> config = std::make_shared<NWebDOHConfigImpl>();
965    config->SetMode(dohMode);
966    config->SetConfig(dohConfig);
967    WVLOG_I("set http dns mode:%{public}d doh_config:%{public}s", dohMode, dohConfig.c_str());
968
969    NWebHelper::Instance().SetHttpDns(config);
970
971    NAPI_CALL(env, napi_get_undefined(env, &result));
972    return result;
973}
974
975napi_value NapiWebviewController::SetWebDebuggingAccess(napi_env env, napi_callback_info info)
976{
977    WVLOG_D("SetWebDebuggingAccess start");
978    napi_value result = nullptr;
979    if (OHOS::system::GetBoolParameter("web.debug.devtools", false)) {
980        return result;
981    }
982    napi_value thisVar = nullptr;
983    size_t argc = INTEGER_ONE;
984    napi_value argv[INTEGER_ONE] = {0};
985
986    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
987    if (argc != INTEGER_ONE) {
988        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
989            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
990        return result;
991    }
992
993    bool webDebuggingAccess = false;
994    if (!NapiParseUtils::ParseBoolean(env, argv[0], webDebuggingAccess)) {
995        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
996            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "webDebuggingAccess", "boolean"));
997        return result;
998    }
999    WebviewController::webDebuggingAccess_ = webDebuggingAccess;
1000
1001    NAPI_CALL(env, napi_get_undefined(env, &result));
1002    return result;
1003}
1004
1005napi_value NapiWebviewController::EnableSafeBrowsing(napi_env env, napi_callback_info info)
1006{
1007    WVLOG_D("EnableSafeBrowsing start");
1008    napi_value result = nullptr;
1009    napi_value thisVar = nullptr;
1010    size_t argc = INTEGER_ONE;
1011    napi_value argv[INTEGER_ONE] = {0};
1012
1013    NAPI_CALL(env, napi_get_undefined(env, &result));
1014    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1015    if (argc != INTEGER_ONE) {
1016        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1017            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1018        return result;
1019    }
1020
1021    bool safeBrowsingEnable = false;
1022    if (!NapiParseUtils::ParseBoolean(env, argv[0], safeBrowsingEnable)) {
1023        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1024            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "enable", "boolean"));
1025        return result;
1026    }
1027
1028    WebviewController *controller = nullptr;
1029    napi_unwrap(env, thisVar, (void **)&controller);
1030    if (!controller) {
1031        return result;
1032    }
1033    if (!controller->IsInit()) {
1034        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1035        return result;
1036    }
1037    controller->EnableSafeBrowsing(safeBrowsingEnable);
1038    return result;
1039}
1040
1041napi_value NapiWebviewController::IsSafeBrowsingEnabled(napi_env env, napi_callback_info info)
1042{
1043    WVLOG_D("IsSafeBrowsingEnabled start");
1044    napi_value result = nullptr;
1045    WebviewController *webviewController = GetWebviewController(env, info);
1046    if (!webviewController) {
1047        return nullptr;
1048    }
1049
1050    bool isSafeBrowsingEnabled = webviewController->IsSafeBrowsingEnabled();
1051    NAPI_CALL(env, napi_get_boolean(env, isSafeBrowsingEnabled, &result));
1052    return result;
1053}
1054
1055napi_value NapiWebviewController::InnerGetWebDebuggingAccess(napi_env env, napi_callback_info info)
1056{
1057    WVLOG_D("InnerGetWebDebuggingAccess start");
1058    bool webDebuggingAccess = WebviewController::webDebuggingAccess_;
1059    napi_value result = nullptr;
1060    napi_get_boolean(env, webDebuggingAccess, &result);
1061    return result;
1062}
1063
1064napi_value NapiWebviewController::InnerGetThisVar(napi_env env, napi_callback_info info)
1065{
1066    WVLOG_D("InnerGetThisVar start");
1067    napi_value thisVar = nullptr;
1068    napi_value result = nullptr;
1069    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1070    WebviewController *webviewController = nullptr;
1071    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1072    if ((!webviewController) || (status != napi_ok)) {
1073        WVLOG_E("webviewController is nullptr.");
1074        napi_create_int64(env, 0, &result);
1075    } else {
1076        napi_create_int64(env, reinterpret_cast<int64_t>(webviewController), &result);
1077    }
1078    return result;
1079}
1080
1081napi_value NapiWebviewController::SetWebId(napi_env env, napi_callback_info info)
1082{
1083    napi_value thisVar = nullptr;
1084    size_t argc = INTEGER_ONE;
1085    napi_value argv[INTEGER_ONE];
1086    void* data = nullptr;
1087    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1088
1089    int32_t webId = -1;
1090    if (!NapiParseUtils::ParseInt32(env, argv[0], webId)) {
1091        WVLOG_E("Parse web id failed.");
1092        return nullptr;
1093    }
1094    WebviewController *webviewController = nullptr;
1095    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1096    if ((!webviewController) || (status != napi_ok)) {
1097        WVLOG_E("webviewController is nullptr.");
1098        return nullptr;
1099    }
1100    webviewController->SetWebId(webId);
1101    return thisVar;
1102}
1103
1104napi_value NapiWebviewController::InnerSetHapPath(napi_env env, napi_callback_info info)
1105{
1106    napi_value result = nullptr;
1107    NAPI_CALL(env, napi_get_undefined(env, &result));
1108    napi_value thisVar = nullptr;
1109    size_t argc = INTEGER_ONE;
1110    napi_value argv[INTEGER_ONE];
1111    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1112    if (argc != INTEGER_ONE) {
1113        WVLOG_E("Failed to run InnerSetHapPath beacuse of wrong Param number.");
1114        return result;
1115    }
1116    std::string hapPath;
1117    if (!NapiParseUtils::ParseString(env, argv[0], hapPath)) {
1118        WVLOG_E("Parse hap path failed.");
1119        return result;
1120    }
1121    WebviewController *webviewController = nullptr;
1122    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1123    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1124        WVLOG_E("Wrap webviewController failed. WebviewController must be associated with a Web component.");
1125        return result;
1126    }
1127    webviewController->InnerSetHapPath(hapPath);
1128    return result;
1129}
1130
1131napi_value NapiWebviewController::InnerJsProxy(napi_env env, napi_callback_info info)
1132{
1133    napi_value thisVar = nullptr;
1134    napi_value result = nullptr;
1135    size_t argc = INTEGER_FIVE;
1136    napi_value argv[INTEGER_FIVE] = { 0 };
1137    napi_get_undefined(env, &result);
1138    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1139    if (argc != INTEGER_FIVE) {
1140        WVLOG_E("Failed to run InnerJsProxy beacuse of wrong Param number.");
1141        return result;
1142    }
1143    napi_valuetype valueType = napi_undefined;
1144    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
1145    if (valueType != napi_object) {
1146        WVLOG_E("Failed to run InnerJsProxy beacuse of wrong Param type.");
1147        return result;
1148    }
1149    std::string objName;
1150    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], objName)) {
1151        WVLOG_E("Failed to run InnerJsProxy beacuse of wrong object name.");
1152        return result;
1153    }
1154    std::vector<std::string> methodList;
1155    bool hasSyncMethod = NapiParseUtils::ParseStringArray(env, argv[INTEGER_TWO], methodList);
1156    std::vector<std::string> asyncMethodList;
1157    bool hasAsyncMethod = NapiParseUtils::ParseStringArray(env, argv[INTEGER_THREE], asyncMethodList);
1158    if (!hasSyncMethod && !hasAsyncMethod) {
1159        WVLOG_E("Failed to run InnerJsProxy beacuse of empty method lists.");
1160        return result;
1161    }
1162    std::string permission = "";
1163    NapiParseUtils::ParseString(env, argv[INTEGER_FOUR], permission);
1164    WebviewController* controller = nullptr;
1165    napi_unwrap(env, thisVar, (void **)&controller);
1166    if (!controller || !controller->IsInit()) {
1167        WVLOG_E("Failed to run InnerJsProxy. The WebviewController must be associted with a Web component.");
1168        return result;
1169    }
1170    controller->SetNWebJavaScriptResultCallBack();
1171    RegisterJavaScriptProxyParam param;
1172    param.env = env;
1173    param.obj = argv[INTEGER_ZERO];
1174    param.objName = objName;
1175    param.syncMethodList = methodList;
1176    param.asyncMethodList = asyncMethodList;
1177    param.permission = permission;
1178    controller->RegisterJavaScriptProxy(param);
1179    return result;
1180}
1181
1182napi_value NapiWebviewController::InnerGetCustomeSchemeCmdLine(napi_env env, napi_callback_info info)
1183{
1184    WebviewController::existNweb_ = true;
1185    napi_value result = nullptr;
1186    const std::string& cmdLine = WebviewController::customeSchemeCmdLine_;
1187    napi_create_string_utf8(env, cmdLine.c_str(), cmdLine.length(), &result);
1188    return result;
1189}
1190
1191napi_value NapiWebviewController::AccessForward(napi_env env, napi_callback_info info)
1192{
1193    napi_value result = nullptr;
1194    WebviewController *webviewController = GetWebviewController(env, info);
1195    if (!webviewController) {
1196        return nullptr;
1197    }
1198
1199    bool access = webviewController->AccessForward();
1200    NAPI_CALL(env, napi_get_boolean(env, access, &result));
1201    return result;
1202}
1203
1204napi_value NapiWebviewController::AccessBackward(napi_env env, napi_callback_info info)
1205{
1206    napi_value result = nullptr;
1207    WebviewController *webviewController = GetWebviewController(env, info);
1208    if (!webviewController) {
1209        return nullptr;
1210    }
1211
1212    bool access = webviewController->AccessBackward();
1213    NAPI_CALL(env, napi_get_boolean(env, access, &result));
1214    return result;
1215}
1216
1217napi_value NapiWebviewController::Forward(napi_env env, napi_callback_info info)
1218{
1219    napi_value result = nullptr;
1220    WebviewController *webviewController = GetWebviewController(env, info);
1221    if (!webviewController) {
1222        return nullptr;
1223    }
1224
1225    webviewController->Forward();
1226    NAPI_CALL(env, napi_get_undefined(env, &result));
1227    return result;
1228}
1229
1230napi_value NapiWebviewController::Backward(napi_env env, napi_callback_info info)
1231{
1232    napi_value result = nullptr;
1233    WebviewController *webviewController = GetWebviewController(env, info);
1234    if (!webviewController) {
1235        return nullptr;
1236    }
1237
1238    webviewController->Backward();
1239    NAPI_CALL(env, napi_get_undefined(env, &result));
1240    return result;
1241}
1242
1243napi_value NapiWebviewController::AccessStep(napi_env env, napi_callback_info info)
1244{
1245    napi_value thisVar = nullptr;
1246    napi_value result = nullptr;
1247    size_t argc = INTEGER_ONE;
1248    napi_value argv[INTEGER_ONE];
1249    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1250    if (argc != INTEGER_ONE) {
1251        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1252            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1253        return nullptr;
1254    }
1255
1256    int32_t step = INTEGER_ZERO;
1257    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], step)) {
1258        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1259            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "step", "number"));
1260        return nullptr;
1261    }
1262
1263    WebviewController *webviewController = nullptr;
1264    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1265    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1266        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1267        return nullptr;
1268    }
1269
1270    bool access = webviewController->AccessStep(step);
1271    NAPI_CALL(env, napi_get_boolean(env, access, &result));
1272    return result;
1273}
1274
1275napi_value NapiWebviewController::ClearHistory(napi_env env, napi_callback_info info)
1276{
1277    napi_value result = nullptr;
1278    WebviewController *webviewController = GetWebviewController(env, info);
1279    if (!webviewController) {
1280        return nullptr;
1281    }
1282
1283    webviewController->ClearHistory();
1284    NAPI_CALL(env, napi_get_undefined(env, &result));
1285    return result;
1286}
1287
1288napi_value NapiWebviewController::OnActive(napi_env env, napi_callback_info info)
1289{
1290    napi_value result = nullptr;
1291    WebviewController *webviewController = GetWebviewController(env, info);
1292    if (!webviewController) {
1293        WVLOG_E("NapiWebviewController::OnActive get controller failed");
1294        return nullptr;
1295    }
1296
1297    webviewController->OnActive();
1298    WVLOG_I("The web component has been successfully activated");
1299    NAPI_CALL(env, napi_get_undefined(env, &result));
1300    return result;
1301}
1302
1303napi_value NapiWebviewController::OnInactive(napi_env env, napi_callback_info info)
1304{
1305    napi_value result = nullptr;
1306    WebviewController *webviewController = GetWebviewController(env, info);
1307    if (!webviewController) {
1308        WVLOG_E("NapiWebviewController::OnInactive get controller failed");
1309        return nullptr;
1310    }
1311
1312    webviewController->OnInactive();
1313    WVLOG_I("The web component has been successfully inactivated");
1314    NAPI_CALL(env, napi_get_undefined(env, &result));
1315    return result;
1316}
1317
1318napi_value NapiWebviewController::Refresh(napi_env env, napi_callback_info info)
1319{
1320    napi_value result = nullptr;
1321    WebviewController *webviewController = GetWebviewController(env, info);
1322    if (!webviewController) {
1323        return nullptr;
1324    }
1325
1326    webviewController->Refresh();
1327    NAPI_CALL(env, napi_get_undefined(env, &result));
1328    return result;
1329}
1330
1331
1332napi_value NapiWebMessageExt::JsConstructor(napi_env env, napi_callback_info info)
1333{
1334    WVLOG_D("NapiWebMessageExt::JsConstructor");
1335    napi_value thisVar = nullptr;
1336    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1337
1338    auto webMsg = std::make_shared<OHOS::NWeb::NWebMessage>(NWebValue::Type::NONE);
1339    WebMessageExt *webMessageExt = new (std::nothrow) WebMessageExt(webMsg);
1340    if (webMessageExt == nullptr) {
1341        WVLOG_E("new msg port failed");
1342        return nullptr;
1343    }
1344    NAPI_CALL(env, napi_wrap(env, thisVar, webMessageExt,
1345        [](napi_env env, void *data, void *hint) {
1346            WebMessageExt *webMessageExt = static_cast<WebMessageExt *>(data);
1347            if (webMessageExt) {
1348                delete webMessageExt;
1349            }
1350        },
1351        nullptr, nullptr));
1352    return thisVar;
1353}
1354
1355napi_value NapiWebMessageExt::GetType(napi_env env, napi_callback_info info)
1356{
1357    WVLOG_D("NapiWebMessageExt::GetType start");
1358    napi_value thisVar = nullptr;
1359    napi_value result = nullptr;
1360    napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1361    if (status != napi_status::napi_ok) {
1362        WVLOG_E("napi_get_cb_info status not ok");
1363        return result;
1364    }
1365
1366    if (thisVar == nullptr) {
1367        WVLOG_E("napi_get_cb_info thisVar is nullptr");
1368        return result;
1369    }
1370
1371    WebMessageExt *webMessageExt = nullptr;
1372    status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1373    if ((!webMessageExt) || (status != napi_ok)) {
1374        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1375        return nullptr;
1376    }
1377
1378    int32_t type = webMessageExt->GetType();
1379    status = napi_create_int32(env, type, &result);
1380    if (status != napi_status::napi_ok) {
1381        WVLOG_E("napi_create_int32 failed.");
1382        return result;
1383    }
1384    return result;
1385}
1386
1387napi_value NapiWebMessageExt::GetString(napi_env env, napi_callback_info info)
1388{
1389    WVLOG_D(" GetString webJsMessageExt start");
1390    napi_value thisVar = nullptr;
1391    napi_value result = nullptr;
1392    size_t argc = INTEGER_ONE;
1393    napi_value argv[INTEGER_ONE] = { 0 };
1394
1395    WebMessageExt *webJsMessageExt = nullptr;
1396    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1397    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1398    if (webJsMessageExt == nullptr) {
1399        WVLOG_E("unwrap webJsMessageExt failed.");
1400        return result;
1401    }
1402
1403    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::STRING)) {
1404        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1405        return nullptr;
1406    }
1407
1408    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1409    return result;
1410}
1411
1412napi_value NapiWebMessageExt::GetNumber(napi_env env, napi_callback_info info)
1413{
1414    WVLOG_D("GetNumber webJsMessageExt start");
1415    napi_value thisVar = nullptr;
1416    napi_value result = nullptr;
1417    size_t argc = INTEGER_ONE;
1418    napi_value argv[INTEGER_ONE] = { 0 };
1419
1420    WebMessageExt *webJsMessageExt = nullptr;
1421    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1422    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1423    if (webJsMessageExt == nullptr) {
1424        WVLOG_E("unwrap webJsMessageExt failed.");
1425        return result;
1426    }
1427
1428    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::NUMBER)) {
1429        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1430        WVLOG_E("GetNumber webJsMessageExt failed,not match");
1431        return nullptr;
1432    }
1433
1434    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1435    return result;
1436}
1437
1438napi_value NapiWebMessageExt::GetBoolean(napi_env env, napi_callback_info info)
1439{
1440    napi_value thisVar = nullptr;
1441    napi_value result = nullptr;
1442    size_t argc = INTEGER_ONE;
1443    napi_value argv[INTEGER_ONE] = { 0 };
1444
1445    WebMessageExt *webJsMessageExt = nullptr;
1446    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1447    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1448    if (webJsMessageExt == nullptr) {
1449        WVLOG_E("unwrap webJsMessageExt failed.");
1450        return result;
1451    }
1452
1453    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::BOOLEAN)) {
1454        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1455        return nullptr;
1456    }
1457
1458    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1459    return result;
1460}
1461
1462napi_value NapiWebMessageExt::GetArrayBuffer(napi_env env, napi_callback_info info)
1463{
1464    napi_value thisVar = nullptr;
1465    napi_value result = nullptr;
1466    size_t argc = INTEGER_ONE;
1467    napi_value argv[INTEGER_ONE] = { 0 };
1468
1469    WebMessageExt *webJsMessageExt = nullptr;
1470    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1471    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1472    if (webJsMessageExt == nullptr) {
1473        WVLOG_E("unwrap webJsMessageExt failed.");
1474        return result;
1475    }
1476
1477    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::ARRAYBUFFER)) {
1478        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1479        return nullptr;
1480    }
1481    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1482    return result;
1483}
1484
1485napi_value NapiWebMessageExt::GetArray(napi_env env, napi_callback_info info)
1486{
1487    napi_value thisVar = nullptr;
1488    napi_value result = nullptr;
1489    size_t argc = INTEGER_ONE;
1490    napi_value argv[INTEGER_ONE] = { 0 };
1491
1492    WebMessageExt *webJsMessageExt = nullptr;
1493    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1494    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1495    if (webJsMessageExt == nullptr) {
1496        WVLOG_E("unwrap webJsMessageExt failed.");
1497        return result;
1498    }
1499
1500    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::ARRAY)) {
1501        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1502        return nullptr;
1503    }
1504
1505    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1506    return result;
1507}
1508
1509napi_value NapiWebMessageExt::GetError(napi_env env, napi_callback_info info)
1510{
1511    napi_value thisVar = nullptr;
1512    napi_value result = nullptr;
1513    size_t argc = INTEGER_ONE;
1514    napi_value argv[INTEGER_ONE] = { 0 };
1515
1516    WebMessageExt *webJsMessageExt = nullptr;
1517    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1518    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webJsMessageExt));
1519    if (webJsMessageExt == nullptr) {
1520        WVLOG_E("unwrap webJsMessageExt failed.");
1521        return result;
1522    }
1523
1524    if (webJsMessageExt->GetType() != static_cast<int32_t>(WebMessageType::ERROR)) {
1525        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1526        return nullptr;
1527    }
1528
1529    NapiParseUtils::ConvertNWebToNapiValue(env, webJsMessageExt->GetData(), result);
1530    return result;
1531}
1532
1533napi_value NapiWebMessageExt::SetType(napi_env env, napi_callback_info info)
1534{
1535    WVLOG_D("NapiWebMessageExt::SetType");
1536    napi_value thisVar = nullptr;
1537    napi_value result = nullptr;
1538    size_t argc = INTEGER_ONE;
1539    napi_value argv[INTEGER_ONE] = { 0 };
1540    int type = -1;
1541    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1542    if (status != napi_ok) {
1543        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1544            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "type"));
1545        WVLOG_E("NapiWebMessageExt::SetType napi_get_cb_info failed");
1546        return result;
1547    }
1548    if (thisVar == nullptr) {
1549        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1550            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NOT_NULL, "type"));
1551        WVLOG_E("NapiWebMessageExt::SetType thisVar is null");
1552        return result;
1553    }
1554    if (argc != INTEGER_ONE) {
1555        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1556            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1557        return result;
1558    }
1559    if (!NapiParseUtils::ParseInt32(env, argv[0], type)) {
1560        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, ParamCheckErrorMsgTemplate::TYPE_ALL_INT);
1561        return result;
1562    }
1563    if (type <= static_cast<int>(WebMessageType::NOTSUPPORT) || type > static_cast<int>(WebMessageType::ERROR)) {
1564        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1565        return result;
1566    }
1567    WebMessageExt *webMessageExt = nullptr;
1568    status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1569    if (status != napi_ok) {
1570        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1571            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "type"));
1572        WVLOG_E("NapiWebMessageExt::SetType napi_unwrap failed");
1573        return result;
1574    }
1575    if (!webMessageExt) {
1576        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1577            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NOT_NULL, "type"));
1578        WVLOG_E("NapiWebMessageExt::SetType webMessageExt is null");
1579        return result;
1580    }
1581    webMessageExt->SetType(type);
1582    return result;
1583}
1584
1585napi_value NapiWebMessageExt::SetString(napi_env env, napi_callback_info info)
1586{
1587    WVLOG_D("NapiWebMessageExt::SetString start");
1588    napi_value thisVar = nullptr;
1589    napi_value result = nullptr;
1590    size_t argc = INTEGER_ONE;
1591    napi_value argv[INTEGER_ONE] = { 0 };
1592    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1593    if (argc != INTEGER_ONE) {
1594        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1595            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1596        return result;
1597    }
1598
1599    std::string value;
1600    if (!NapiParseUtils::ParseString(env, argv[0], value)) {
1601        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1602            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "string"));
1603        return result;
1604    }
1605    WebMessageExt *webMessageExt = nullptr;
1606    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1607    if ((!webMessageExt) || (status != napi_ok)) {
1608        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1609            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1610        return result;
1611    }
1612
1613    int32_t type = webMessageExt->GetType();
1614    if (type != static_cast<int32_t>(WebMessageType::STRING)) {
1615        WVLOG_E("web message SetString error type:%{public}d", type);
1616        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1617        return result;
1618    }
1619    webMessageExt->SetString(value);
1620    return result;
1621}
1622
1623napi_value NapiWebMessageExt::SetNumber(napi_env env, napi_callback_info info)
1624{
1625    WVLOG_D("NapiWebMessageExt::SetNumber start");
1626    napi_value thisVar = nullptr;
1627    napi_value result = nullptr;
1628    size_t argc = INTEGER_ONE;
1629    napi_value argv[INTEGER_ONE] = { 0 };
1630    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1631    if (argc != INTEGER_ONE) {
1632        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1633            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1634        return result;
1635    }
1636
1637    double value = 0;
1638    if (!NapiParseUtils::ParseDouble(env, argv[0], value)) {
1639        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1640            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "number"));
1641        return result;
1642    }
1643
1644    WebMessageExt *webMessageExt = nullptr;
1645    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1646    if ((!webMessageExt) || (status != napi_ok)) {
1647        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1648            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1649        return result;
1650    }
1651
1652    int32_t type = webMessageExt->GetType();
1653    if (type != static_cast<int32_t>(WebMessageType::NUMBER)) {
1654        WVLOG_E("web message SetNumber error type:%{public}d", type);
1655        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1656        return result;
1657    }
1658    webMessageExt->SetNumber(value);
1659    return result;
1660}
1661
1662napi_value NapiWebMessageExt::SetBoolean(napi_env env, napi_callback_info info)
1663{
1664    WVLOG_D("NapiWebMessageExt::SetBoolean start");
1665    napi_value thisVar = nullptr;
1666    napi_value result = nullptr;
1667    size_t argc = INTEGER_ONE;
1668    napi_value argv[INTEGER_ONE] = { 0 };
1669    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1670    if (argc != INTEGER_ONE) {
1671        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1672            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1673        return result;
1674    }
1675
1676    bool value = 0;
1677    if (!NapiParseUtils::ParseBoolean(env, argv[0], value)) {
1678        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1679            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "boolean"));
1680        return result;
1681    }
1682
1683    WebMessageExt *webMessageExt = nullptr;
1684    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1685    if ((!webMessageExt) || (status != napi_ok)) {
1686        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1687            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1688        return result;
1689    }
1690
1691    int32_t type = webMessageExt->GetType();
1692    if (type != static_cast<int32_t>(WebMessageType::BOOLEAN)) {
1693        WVLOG_E("web message SetBoolean error type:%{public}d", type);
1694        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1695        return result;
1696    }
1697    webMessageExt->SetBoolean(value);
1698    return result;
1699}
1700
1701napi_value NapiWebMessageExt::SetArrayBuffer(napi_env env, napi_callback_info info)
1702{
1703    WVLOG_D("NapiWebMessageExt::SetArrayBuffer start");
1704    napi_value thisVar = nullptr;
1705    napi_value result = nullptr;
1706    size_t argc = INTEGER_ONE;
1707    napi_value argv[INTEGER_ONE] = { 0 };
1708    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1709    if (argc != INTEGER_ONE) {
1710        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1711            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1712        return result;
1713    }
1714
1715    bool isArrayBuffer = false;
1716    NAPI_CALL(env, napi_is_arraybuffer(env, argv[INTEGER_ZERO], &isArrayBuffer));
1717    if (!isArrayBuffer) {
1718        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1719            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "arrayBuffer"));
1720        return result;
1721    }
1722
1723    uint8_t *arrBuf = nullptr;
1724    size_t byteLength = 0;
1725    napi_get_arraybuffer_info(env, argv[INTEGER_ZERO], (void**)&arrBuf, &byteLength);
1726    std::vector<uint8_t> vecData(arrBuf, arrBuf + byteLength);
1727    WebMessageExt *webMessageExt = nullptr;
1728    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1729    if ((!webMessageExt) || (status != napi_ok)) {
1730        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1731            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1732        return result;
1733    }
1734
1735    int32_t type = webMessageExt->GetType();
1736    if (type != static_cast<int32_t>(WebMessageType::ARRAYBUFFER)) {
1737        WVLOG_E("web message SetArrayBuffer error type:%{public}d", type);
1738        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1739        return result;
1740    }
1741    webMessageExt->SetArrayBuffer(vecData);
1742    return result;
1743}
1744
1745napi_value NapiWebMessageExt::SetArray(napi_env env, napi_callback_info info)
1746{
1747    WVLOG_D("NapiWebMessageExt::SetArray start");
1748    napi_value thisVar = nullptr;
1749    napi_value result = nullptr;
1750    size_t argc = INTEGER_ONE;
1751    napi_value argv[INTEGER_ONE] = { 0 };
1752    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1753    if (argc != INTEGER_ONE) {
1754        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1755            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1756        return result;
1757    }
1758    bool isArray = false;
1759    NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ZERO], &isArray));
1760    if (!isArray) {
1761        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1762            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "array"));
1763        return result;
1764    }
1765    WebMessageExt *webMessageExt = nullptr;
1766    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1767    if ((!webMessageExt) || (status != napi_ok)) {
1768        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1769            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1770        return result;
1771    }
1772    int32_t type = webMessageExt->GetType();
1773    if (type != static_cast<int32_t>(WebMessageType::ARRAY)) {
1774        WVLOG_E("web message SetArray error type:%{public}d", type);
1775        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1776        return result;
1777    }
1778    bool isDouble = false;
1779    napi_valuetype valueType = GetArrayValueType(env, argv[INTEGER_ZERO], isDouble);
1780    if (valueType == napi_undefined) {
1781        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1782            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "number"));
1783        return result;
1784    }
1785    using SetArrayHandler = std::function<void(napi_env, napi_value, WebMessageExt*)>;
1786    const std::unordered_map<napi_valuetype, SetArrayHandler> functionMap = {
1787        { napi_boolean, SetArrayHandlerBoolean },
1788        { napi_string, SetArrayHandlerString },
1789        { napi_number, [isDouble](napi_env env, napi_value array, WebMessageExt* msgExt) {
1790            isDouble ? SetArrayHandlerDouble(env, array, msgExt)
1791                     : SetArrayHandlerInteger(env, array, msgExt);
1792        } }
1793    };
1794    auto it = functionMap.find(valueType);
1795    if (it != functionMap.end()) {
1796        it->second(env, argv[INTEGER_ZERO], webMessageExt);
1797    }
1798    return result;
1799}
1800
1801napi_value NapiWebMessageExt::SetError(napi_env env, napi_callback_info info)
1802{
1803    WVLOG_D("NapiWebMessageExt::SetError start");
1804    napi_value thisVar = nullptr;
1805    napi_value result = nullptr;
1806    size_t argc = INTEGER_ONE;
1807    napi_value argv[INTEGER_ONE] = { 0 };
1808    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1809    if (argc != INTEGER_ONE) {
1810        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1811            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
1812        return result;
1813    }
1814
1815    bool isError = false;
1816    NAPI_CALL(env, napi_is_error(env, argv[INTEGER_ZERO], &isError));
1817    if (!isError) {
1818        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1819            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "message", "error"));
1820        return result;
1821    }
1822
1823    napi_value nameObj = 0;
1824    napi_get_named_property(env, argv[INTEGER_ZERO], "name", &nameObj);
1825    std::string nameVal;
1826    if (!NapiParseUtils::ParseString(env, nameObj, nameVal)) {
1827        return result;
1828    }
1829
1830    napi_value msgObj = 0;
1831    napi_get_named_property(env, argv[INTEGER_ZERO], "message", &msgObj);
1832    std::string msgVal;
1833    if (!NapiParseUtils::ParseString(env, msgObj, msgVal)) {
1834        return result;
1835    }
1836
1837    WebMessageExt *webMessageExt = nullptr;
1838    napi_status status = napi_unwrap(env, thisVar, (void **)&webMessageExt);
1839    if ((!webMessageExt) || (status != napi_ok)) {
1840        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1841            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
1842        return result;
1843    }
1844
1845    int32_t type = webMessageExt->GetType();
1846    if (type != static_cast<int32_t>(WebMessageType::ERROR)) {
1847        WVLOG_E("web message SetError error type:%{public}d", type);
1848        BusinessError::ThrowErrorByErrcode(env, TYPE_NOT_MATCH_WITCH_VALUE);
1849        return result;
1850    }
1851    webMessageExt->SetError(nameVal, msgVal);
1852    return result;
1853}
1854
1855napi_value NapiWebviewController::CreateWebMessagePorts(napi_env env, napi_callback_info info)
1856{
1857    WVLOG_D("create web message port");
1858    napi_value thisVar = nullptr;
1859    napi_value result = nullptr;
1860    size_t argc = INTEGER_ONE;
1861    napi_value argv[INTEGER_ONE] = { 0 };
1862    bool isExtentionType = false;
1863    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1864    if (argc != INTEGER_ZERO && argc != INTEGER_ONE) {
1865        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1866            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "zero", "one"));
1867        return result;
1868    }
1869
1870    if (argc == INTEGER_ONE) {
1871        if (!NapiParseUtils::ParseBoolean(env, argv[0], isExtentionType)) {
1872            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1873                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "isExtentionType", "boolean"));
1874            return result;
1875        }
1876    }
1877
1878    WebviewController *webviewController = nullptr;
1879    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
1880    if (webviewController == nullptr || !webviewController->IsInit()) {
1881        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1882        WVLOG_E("create message port failed, napi unwrap webviewController failed");
1883        return nullptr;
1884    }
1885    int32_t nwebId = webviewController->GetWebId();
1886    std::vector<std::string> ports = webviewController->CreateWebMessagePorts();
1887    if (ports.size() != INTEGER_TWO) {
1888        WVLOG_E("create web message port failed");
1889        return result;
1890    }
1891    napi_value msgPortcons = nullptr;
1892    NAPI_CALL(env, napi_get_reference_value(env, g_classWebMsgPort, &msgPortcons));
1893    napi_create_array(env, &result);
1894    napi_value consParam[INTEGER_TWO][INTEGER_THREE] = {{0}};
1895    for (uint32_t i = 0; i < INTEGER_TWO; i++) {
1896        napi_value msgPortObj = nullptr;
1897        NAPI_CALL(env, napi_create_int32(env, nwebId, &consParam[i][INTEGER_ZERO]));
1898        NAPI_CALL(env, napi_create_string_utf8(env, ports[i].c_str(), ports[i].length(), &consParam[i][INTEGER_ONE]));
1899        NAPI_CALL(env, napi_get_boolean(env, isExtentionType, &consParam[i][INTEGER_TWO]));
1900        NAPI_CALL(env, napi_new_instance(env, msgPortcons, INTEGER_THREE, consParam[i], &msgPortObj));
1901        napi_value jsExtention;
1902        napi_get_boolean(env, isExtentionType, &jsExtention);
1903        napi_set_named_property(env, msgPortObj, "isExtentionType", jsExtention);
1904
1905        napi_set_element(env, result, i, msgPortObj);
1906    }
1907
1908    return result;
1909}
1910
1911bool GetSendPorts(napi_env env, napi_value argv, std::vector<std::string>& sendPorts)
1912{
1913    uint32_t arrayLen = 0;
1914    napi_get_array_length(env, argv, &arrayLen);
1915    if (arrayLen == 0) {
1916        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1917        return false;
1918    }
1919
1920    napi_valuetype valueType = napi_undefined;
1921    for (uint32_t i = 0; i < arrayLen; i++) {
1922        napi_value portItem = nullptr;
1923        napi_get_element(env, argv, i, &portItem);
1924        napi_typeof(env, portItem, &valueType);
1925        if (valueType != napi_object) {
1926            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1927            return false;
1928        }
1929        WebMessagePort *msgPort = nullptr;
1930        napi_status status = napi_unwrap(env, portItem, (void **)&msgPort);
1931        if ((!msgPort) || (status != napi_ok)) {
1932            WVLOG_E("post port to html failed, napi unwrap msg port fail");
1933            return false;
1934        }
1935        std::string portHandle = msgPort->GetPortHandle();
1936        sendPorts.emplace_back(portHandle);
1937    }
1938    return true;
1939}
1940
1941napi_value NapiWebviewController::PostMessage(napi_env env, napi_callback_info info)
1942{
1943    WVLOG_D("post message port");
1944    napi_value thisVar = nullptr;
1945    napi_value result = nullptr;
1946    size_t argc = INTEGER_THREE;
1947    napi_value argv[INTEGER_THREE];
1948    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
1949    if (argc != INTEGER_THREE) {
1950        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1951            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "three"));
1952        return result;
1953    }
1954
1955    std::string portName;
1956    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], portName)) {
1957        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1958            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "name", "string"));
1959        return result;
1960    }
1961
1962    bool isArray = false;
1963    NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ONE], &isArray));
1964    if (!isArray) {
1965        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1966            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "ports", "array"));
1967        return result;
1968    }
1969    std::vector<std::string> sendPorts;
1970    if (!GetSendPorts(env, argv[INTEGER_ONE], sendPorts)) {
1971        WVLOG_E("post port to html failed, getSendPorts fail");
1972        return result;
1973    }
1974
1975    std::string urlStr;
1976    if (!NapiParseUtils::ParseString(env, argv[INTEGER_TWO], urlStr)) {
1977        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
1978            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "uri", "string"));
1979        return result;
1980    }
1981
1982    WebviewController *webviewController = nullptr;
1983    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
1984    if (webviewController == nullptr || !webviewController->IsInit()) {
1985        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1986        WVLOG_E("post port to html failed, napi unwrap webviewController failed");
1987        return nullptr;
1988    }
1989
1990    webviewController->PostWebMessage(portName, sendPorts, urlStr);
1991    NAPI_CALL(env, napi_get_undefined(env, &result));
1992
1993    return result;
1994}
1995
1996napi_value NapiWebMessagePort::JsConstructor(napi_env env, napi_callback_info info)
1997{
1998    WVLOG_D("web message port construct");
1999    napi_value thisVar = nullptr;
2000    size_t argc = INTEGER_THREE;
2001    napi_value argv[INTEGER_THREE] = {0};
2002    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2003
2004    int32_t webId = -1;
2005    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], webId)) {
2006        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2007        return nullptr;
2008    }
2009
2010    std::string portHandle;
2011    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], portHandle)) {
2012        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2013        return nullptr;
2014    }
2015
2016    bool isExtentionType = false;
2017    if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_TWO], isExtentionType)) {
2018        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2019        return nullptr;
2020    }
2021
2022    WebMessagePort *msgPort = new (std::nothrow) WebMessagePort(webId, portHandle, isExtentionType);
2023    if (msgPort == nullptr) {
2024        WVLOG_E("new msg port failed");
2025        return nullptr;
2026    }
2027    NAPI_CALL(env, napi_wrap(env, thisVar, msgPort,
2028        [](napi_env env, void *data, void *hint) {
2029            WebMessagePort *msgPort = static_cast<WebMessagePort *>(data);
2030            delete msgPort;
2031        },
2032        nullptr, nullptr));
2033    return thisVar;
2034}
2035
2036napi_value NapiWebMessagePort::Close(napi_env env, napi_callback_info info)
2037{
2038    WVLOG_D("close message port");
2039    napi_value thisVar = nullptr;
2040    napi_value result = nullptr;
2041    NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
2042
2043    WebMessagePort *msgPort = nullptr;
2044    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
2045    if (msgPort == nullptr) {
2046        WVLOG_E("close message port failed, napi unwrap msg port failed");
2047        return nullptr;
2048    }
2049    ErrCode ret = msgPort->ClosePort();
2050    if (ret != NO_ERROR) {
2051        BusinessError::ThrowErrorByErrcode(env, ret);
2052        return result;
2053    }
2054    NAPI_CALL(env, napi_get_undefined(env, &result));
2055
2056    return result;
2057}
2058
2059bool PostMessageEventMsgHandler(napi_env env, napi_value argv, napi_valuetype valueType, bool isArrayBuffer,
2060    std::shared_ptr<NWebMessage> webMsg)
2061{
2062    if (valueType == napi_string) {
2063        size_t bufferSize = 0;
2064        napi_get_value_string_utf8(env, argv, nullptr, 0, &bufferSize);
2065        if (bufferSize > UINT_MAX) {
2066            WVLOG_E("String length is too long");
2067            return false;
2068        }
2069        char* stringValue = new (std::nothrow) char[bufferSize + 1];
2070        if (stringValue == nullptr) {
2071            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2072            return false;
2073        }
2074        size_t jsStringLength = 0;
2075        napi_get_value_string_utf8(env, argv, stringValue, bufferSize + 1, &jsStringLength);
2076        std::string message(stringValue);
2077        delete [] stringValue;
2078        stringValue = nullptr;
2079
2080        webMsg->SetType(NWebValue::Type::STRING);
2081        webMsg->SetString(message);
2082    } else if (isArrayBuffer) {
2083        uint8_t *arrBuf = nullptr;
2084        size_t byteLength = 0;
2085        napi_get_arraybuffer_info(env, argv, (void**)&arrBuf, &byteLength);
2086        std::vector<uint8_t> vecData(arrBuf, arrBuf + byteLength);
2087        webMsg->SetType(NWebValue::Type::BINARY);
2088        webMsg->SetBinary(vecData);
2089    }
2090    return true;
2091}
2092
2093napi_value NapiWebMessagePort::PostMessageEvent(napi_env env, napi_callback_info info)
2094{
2095    WVLOG_D("message port post message");
2096    napi_value thisVar = nullptr;
2097    napi_value result = nullptr;
2098    size_t argc = INTEGER_ONE;
2099    napi_value argv[INTEGER_ONE];
2100    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2101    if (argc != INTEGER_ONE) {
2102        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2103            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2104        return result;
2105    }
2106    napi_valuetype valueType = napi_undefined;
2107    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
2108
2109    bool isArrayBuffer = false;
2110    NAPI_CALL(env, napi_is_arraybuffer(env, argv[INTEGER_ZERO], &isArrayBuffer));
2111    if (valueType != napi_string && !isArrayBuffer) {
2112        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2113            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
2114        return result;
2115    }
2116
2117    auto webMsg = std::make_shared<OHOS::NWeb::NWebMessage>(NWebValue::Type::NONE);
2118    if (!PostMessageEventMsgHandler(env, argv[INTEGER_ZERO], valueType, isArrayBuffer, webMsg)) {
2119        WVLOG_E("post message failed, PostMessageEventMsgHandler failed");
2120        return result;
2121    }
2122
2123    WebMessagePort *msgPort = nullptr;
2124    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
2125    if (msgPort == nullptr) {
2126        WVLOG_E("post message failed, napi unwrap msg port failed");
2127        return nullptr;
2128    }
2129    ErrCode ret = msgPort->PostPortMessage(webMsg);
2130    if (ret != NO_ERROR) {
2131        BusinessError::ThrowErrorByErrcode(env, ret);
2132        return result;
2133    }
2134    NAPI_CALL(env, napi_get_undefined(env, &result));
2135
2136    return result;
2137}
2138
2139napi_value NapiWebMessagePort::PostMessageEventExt(napi_env env, napi_callback_info info)
2140{
2141    WVLOG_D("message PostMessageEventExt start");
2142    napi_value thisVar = nullptr;
2143    napi_value result = nullptr;
2144    size_t argc = INTEGER_ONE;
2145    napi_value argv[INTEGER_ONE];
2146    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2147    if (argc != INTEGER_ONE) {
2148        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2149            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2150        return result;
2151    }
2152    napi_valuetype valueType = napi_undefined;
2153    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
2154    if (valueType != napi_object) {
2155        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2156            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
2157        return result;
2158    }
2159
2160    WebMessageExt *webMessageExt = nullptr;
2161    NAPI_CALL(env, napi_unwrap(env, argv[INTEGER_ZERO], (void **)&webMessageExt));
2162    if (webMessageExt == nullptr) {
2163        WVLOG_E("post message failed, napi unwrap msg port failed");
2164        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2165            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NOT_NULL, "message"));
2166        return nullptr;
2167    }
2168
2169    WebMessagePort *msgPort = nullptr;
2170    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
2171    if (msgPort == nullptr) {
2172        WVLOG_E("post message failed, napi unwrap msg port failed");
2173        return nullptr;
2174    }
2175
2176    if (!msgPort->IsExtentionType()) {
2177        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2178            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "message"));
2179        return result;
2180    }
2181
2182    ErrCode ret = msgPort->PostPortMessage(webMessageExt->GetData());
2183    if (ret != NO_ERROR) {
2184        BusinessError::ThrowErrorByErrcode(env, ret);
2185        return result;
2186    }
2187    NAPI_CALL(env, napi_get_undefined(env, &result));
2188
2189    return result;
2190}
2191
2192
2193napi_value NapiWebMessagePort::OnMessageEventExt(napi_env env, napi_callback_info info)
2194{
2195    WVLOG_D("message port set OnMessageEventExt callback");
2196    napi_value thisVar = nullptr;
2197    napi_value result = nullptr;
2198    size_t argc = INTEGER_ONE;
2199    napi_value argv[INTEGER_ONE];
2200    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2201    if (argc != INTEGER_ONE) {
2202        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2203            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2204        return result;
2205    }
2206    napi_valuetype valueType = napi_undefined;
2207    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
2208    if (valueType != napi_function) {
2209        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2210            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
2211        return result;
2212    }
2213
2214    napi_ref onMsgEventFunc = nullptr;
2215    NAPI_CALL(env, napi_create_reference(env, argv[INTEGER_ZERO], INTEGER_ONE, &onMsgEventFunc));
2216
2217    auto callbackImpl = std::make_shared<NWebValueCallbackImpl>(env, onMsgEventFunc, true);
2218
2219    WebMessagePort *msgPort = nullptr;
2220    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
2221    if (msgPort == nullptr) {
2222        WVLOG_E("set message event callback failed, napi unwrap msg port failed");
2223        napi_delete_reference(env, onMsgEventFunc);
2224        return nullptr;
2225    }
2226    ErrCode ret = msgPort->SetPortMessageCallback(callbackImpl);
2227    if (ret != NO_ERROR) {
2228        BusinessError::ThrowErrorByErrcode(env, ret);
2229    }
2230    NAPI_CALL(env, napi_get_undefined(env, &result));
2231    return result;
2232}
2233
2234bool UvWebMsgOnReceiveCbDataHandler(NapiWebMessagePort::WebMsgPortParam *data, napi_value& result)
2235{
2236    if (data->extention_) {
2237        napi_value webMsgExt = nullptr;
2238        napi_status status = napi_get_reference_value(data->env_, g_webMsgExtClassRef, &webMsgExt);
2239        if (status != napi_status::napi_ok) {
2240            WVLOG_E("napi_get_reference_value failed.");
2241            return false;
2242        }
2243        status = napi_new_instance(data->env_, webMsgExt, 0, NULL, &result);
2244        if (status != napi_status::napi_ok) {
2245            WVLOG_E("napi_new_instance failed.");
2246            return false;
2247        }
2248
2249        WebMessageExt *webMessageExt = new (std::nothrow) WebMessageExt(data->msg_);
2250        if (webMessageExt == nullptr) {
2251            WVLOG_E("new WebMessageExt failed.");
2252            return false;
2253        }
2254
2255        status = napi_wrap(data->env_, result, webMessageExt,
2256            [](napi_env env, void *data, void *hint) {
2257                WebMessageExt *webMessageExt = static_cast<WebMessageExt *>(data);
2258                delete webMessageExt;
2259            },
2260            nullptr, nullptr);
2261        if (status != napi_status::napi_ok) {
2262            WVLOG_E("napi_wrap failed.");
2263            return false;
2264        }
2265    } else {
2266        NapiParseUtils::ConvertNWebToNapiValue(data->env_, data->msg_, result);
2267    }
2268    return true;
2269}
2270
2271void NWebValueCallbackImpl::UvWebMessageOnReceiveValueCallback(uv_work_t *work, int status)
2272{
2273    if (work == nullptr) {
2274        WVLOG_E("uv work is null");
2275        return;
2276    }
2277    NapiWebMessagePort::WebMsgPortParam *data = reinterpret_cast<NapiWebMessagePort::WebMsgPortParam*>(work->data);
2278    if (data == nullptr) {
2279        WVLOG_E("WebMsgPortParam is null");
2280        delete work;
2281        work = nullptr;
2282        return;
2283    }
2284    napi_handle_scope scope = nullptr;
2285    napi_open_handle_scope(data->env_, &scope);
2286    if (scope == nullptr) {
2287        delete work;
2288        work = nullptr;
2289        return;
2290    }
2291    napi_value result[INTEGER_ONE] = {0};
2292    if (!UvWebMsgOnReceiveCbDataHandler(data, result[INTEGER_ZERO])) {
2293        delete work;
2294        work = nullptr;
2295        napi_close_handle_scope(data->env_, scope);
2296        return;
2297    }
2298
2299    napi_value onMsgEventFunc = nullptr;
2300    napi_get_reference_value(data->env_, data->callback_, &onMsgEventFunc);
2301    napi_value placeHodler = nullptr;
2302    napi_call_function(data->env_, nullptr, onMsgEventFunc, INTEGER_ONE, &result[INTEGER_ZERO], &placeHodler);
2303
2304    std::unique_lock<std::mutex> lock(data->mutex_);
2305    data->ready_ = true;
2306    data->condition_.notify_all();
2307    napi_close_handle_scope(data->env_, scope);
2308}
2309
2310static void InvokeWebMessageCallback(NapiWebMessagePort::WebMsgPortParam *data)
2311{
2312    napi_handle_scope scope = nullptr;
2313    napi_open_handle_scope(data->env_, &scope);
2314    if (scope == nullptr) {
2315        WVLOG_E("scope is null");
2316        return;
2317    }
2318    napi_value result[INTEGER_ONE] = {0};
2319    if (!UvWebMsgOnReceiveCbDataHandler(data, result[INTEGER_ZERO])) {
2320        WVLOG_E("get result failed");
2321        napi_close_handle_scope(data->env_, scope);
2322        return;
2323    }
2324
2325    napi_value onMsgEventFunc = nullptr;
2326    napi_get_reference_value(data->env_, data->callback_, &onMsgEventFunc);
2327    napi_value placeHodler = nullptr;
2328    napi_call_function(data->env_, nullptr, onMsgEventFunc, INTEGER_ONE, &result[INTEGER_ZERO], &placeHodler);
2329
2330    napi_close_handle_scope(data->env_, scope);
2331}
2332
2333void NWebValueCallbackImpl::OnReceiveValue(std::shared_ptr<NWebMessage> result)
2334{
2335    WVLOG_D("message port received msg");
2336    uv_loop_s *loop = nullptr;
2337    uv_work_t *work = nullptr;
2338    napi_get_uv_event_loop(env_, &loop);
2339    auto engine = reinterpret_cast<NativeEngine*>(env_);
2340    if (loop == nullptr) {
2341        WVLOG_E("get uv event loop failed");
2342        return;
2343    }
2344    work = new (std::nothrow) uv_work_t;
2345    if (work == nullptr) {
2346        WVLOG_E("new uv work failed");
2347        return;
2348    }
2349    NapiWebMessagePort::WebMsgPortParam *param = new (std::nothrow) NapiWebMessagePort::WebMsgPortParam();
2350    if (param == nullptr) {
2351        WVLOG_E("new WebMsgPortParam failed");
2352        delete work;
2353        return;
2354    }
2355    param->env_ = env_;
2356    param->callback_ = callback_;
2357    param->msg_ = result;
2358    param->extention_ = extention_;
2359    if (pthread_self() == engine->GetTid()) {
2360        InvokeWebMessageCallback(param);
2361    } else {
2362        work->data = reinterpret_cast<void*>(param);
2363        uv_queue_work_with_qos(
2364            loop, work, [](uv_work_t* work) {}, UvWebMessageOnReceiveValueCallback, uv_qos_user_initiated);
2365
2366        {
2367            std::unique_lock<std::mutex> lock(param->mutex_);
2368            param->condition_.wait(lock, [&param] { return param->ready_; });
2369        }
2370    }
2371
2372    if (param != nullptr) {
2373        delete param;
2374        param = nullptr;
2375    }
2376    if (work != nullptr) {
2377        delete work;
2378        work = nullptr;
2379    }
2380}
2381
2382void UvNWebValueCallbackImplThreadWoker(uv_work_t *work, int status)
2383{
2384    if (work == nullptr) {
2385        WVLOG_E("uv work is null");
2386        return;
2387    }
2388    NapiWebMessagePort::WebMsgPortParam *data = reinterpret_cast<NapiWebMessagePort::WebMsgPortParam*>(work->data);
2389    if (data == nullptr) {
2390        WVLOG_E("WebMsgPortParam is null");
2391        delete work;
2392        return;
2393    }
2394
2395    napi_delete_reference(data->env_, data->callback_);
2396    delete data;
2397    data = nullptr;
2398    delete work;
2399    work = nullptr;
2400}
2401
2402NWebValueCallbackImpl::~NWebValueCallbackImpl()
2403{
2404    WVLOG_D("~NWebValueCallbackImpl");
2405    uv_loop_s *loop = nullptr;
2406    uv_work_t *work = nullptr;
2407    napi_get_uv_event_loop(env_, &loop);
2408    if (loop == nullptr) {
2409        WVLOG_E("get uv event loop failed");
2410        return;
2411    }
2412    work = new (std::nothrow) uv_work_t;
2413    if (work == nullptr) {
2414        WVLOG_E("new uv work failed");
2415        return;
2416    }
2417    NapiWebMessagePort::WebMsgPortParam *param = new (std::nothrow) NapiWebMessagePort::WebMsgPortParam();
2418    if (param == nullptr) {
2419        WVLOG_E("new WebMsgPortParam failed");
2420        delete work;
2421        return;
2422    }
2423    param->env_ = env_;
2424    param->callback_ = callback_;
2425    work->data = reinterpret_cast<void*>(param);
2426    int ret = uv_queue_work_with_qos(
2427        loop, work, [](uv_work_t *work) {}, UvNWebValueCallbackImplThreadWoker, uv_qos_user_initiated);
2428    if (ret != 0) {
2429        if (param != nullptr) {
2430            delete param;
2431            param = nullptr;
2432        }
2433        if (work != nullptr) {
2434            delete work;
2435            work = nullptr;
2436        }
2437    }
2438}
2439
2440napi_value NapiWebMessagePort::OnMessageEvent(napi_env env, napi_callback_info info)
2441{
2442    WVLOG_D("message port set OnMessageEvent callback");
2443    napi_value thisVar = nullptr;
2444    napi_value result = nullptr;
2445    size_t argc = INTEGER_ONE;
2446    napi_value argv[INTEGER_ONE];
2447    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2448    if (argc != INTEGER_ONE) {
2449        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2450            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2451        return result;
2452    }
2453    napi_valuetype valueType = napi_undefined;
2454    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
2455    if (valueType != napi_function) {
2456        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2457            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
2458        return result;
2459    }
2460
2461    napi_ref onMsgEventFunc = nullptr;
2462    NAPI_CALL(env, napi_create_reference(env, argv[INTEGER_ZERO], INTEGER_ONE, &onMsgEventFunc));
2463
2464    auto callbackImpl = std::make_shared<NWebValueCallbackImpl>(env, onMsgEventFunc, false);
2465
2466    WebMessagePort *msgPort = nullptr;
2467    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
2468    if (msgPort == nullptr) {
2469        WVLOG_E("set message event callback failed, napi unwrap msg port failed");
2470        return nullptr;
2471    }
2472    ErrCode ret = msgPort->SetPortMessageCallback(callbackImpl);
2473    if (ret != NO_ERROR) {
2474        BusinessError::ThrowErrorByErrcode(env, ret);
2475    }
2476    NAPI_CALL(env, napi_get_undefined(env, &result));
2477    return result;
2478}
2479
2480napi_value NapiWebviewController::ZoomIn(napi_env env, napi_callback_info info)
2481{
2482    napi_value result = nullptr;
2483    WebviewController *webviewController = GetWebviewController(env, info);
2484    if (!webviewController) {
2485        return nullptr;
2486    }
2487
2488    ErrCode ret = webviewController->ZoomIn();
2489    if (ret != NO_ERROR) {
2490        if (ret == NWEB_ERROR) {
2491            WVLOG_E("ZoomIn failed.");
2492            return nullptr;
2493        }
2494        BusinessError::ThrowErrorByErrcode(env, ret);
2495    }
2496
2497    NAPI_CALL(env, napi_get_undefined(env, &result));
2498    return result;
2499}
2500
2501napi_value NapiWebviewController::ZoomOut(napi_env env, napi_callback_info info)
2502{
2503    napi_value result = nullptr;
2504    WebviewController *webviewController = GetWebviewController(env, info);
2505    if (!webviewController) {
2506        return nullptr;
2507    }
2508
2509    ErrCode ret = webviewController->ZoomOut();
2510    if (ret != NO_ERROR) {
2511        if (ret == NWEB_ERROR) {
2512            WVLOG_E("ZoomOut failed.");
2513            return nullptr;
2514        }
2515        BusinessError::ThrowErrorByErrcode(env, ret);
2516    }
2517
2518    NAPI_CALL(env, napi_get_undefined(env, &result));
2519    return result;
2520}
2521
2522napi_value NapiWebviewController::GetWebId(napi_env env, napi_callback_info info)
2523{
2524    napi_value result = nullptr;
2525    WebviewController *webviewController = GetWebviewController(env, info);
2526    if (!webviewController) {
2527        return nullptr;
2528    }
2529
2530    int32_t webId = webviewController->GetWebId();
2531    napi_create_int32(env, webId, &result);
2532
2533    return result;
2534}
2535
2536napi_value NapiWebviewController::GetUserAgent(napi_env env, napi_callback_info info)
2537{
2538    napi_value result = nullptr;
2539    WebviewController *webviewController = GetWebviewController(env, info);
2540    if (!webviewController) {
2541        return nullptr;
2542    }
2543
2544    std::string userAgent = "";
2545    userAgent = webviewController->GetUserAgent();
2546    napi_create_string_utf8(env, userAgent.c_str(), userAgent.length(), &result);
2547
2548    return result;
2549}
2550
2551napi_value NapiWebviewController::GetCustomUserAgent(napi_env env, napi_callback_info info)
2552{
2553    napi_value thisVar = nullptr;
2554    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
2555
2556    WebviewController *webviewController = nullptr;
2557    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2558    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2559        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2560        return nullptr;
2561    }
2562
2563    napi_value result = nullptr;
2564    std::string userAgent = webviewController->GetCustomUserAgent();
2565    napi_create_string_utf8(env, userAgent.c_str(), userAgent.length(), &result);
2566    return result;
2567}
2568
2569napi_value NapiWebviewController::SetCustomUserAgent(napi_env env, napi_callback_info info)
2570{
2571    napi_value thisVar = nullptr;
2572    napi_value result = nullptr;
2573    size_t argc = INTEGER_ONE;
2574    napi_value argv[INTEGER_ONE];
2575    NAPI_CALL(env, napi_get_undefined(env, &result));
2576
2577    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2578    if (argc != INTEGER_ONE) {
2579        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2580            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2581        return result;
2582    }
2583
2584    std::string userAgent;
2585    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], userAgent)) {
2586        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2587            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "userAgent", "string"));
2588        return result;
2589    }
2590
2591    WebviewController *webviewController = nullptr;
2592    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2593    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2594        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2595        return result;
2596    }
2597    ErrCode ret = webviewController->SetCustomUserAgent(userAgent);
2598    if (ret != NO_ERROR) {
2599        BusinessError::ThrowErrorByErrcode(env, ret);
2600    }
2601    return result;
2602}
2603
2604napi_value NapiWebviewController::GetTitle(napi_env env, napi_callback_info info)
2605{
2606    napi_value result = nullptr;
2607    WebviewController *webviewController = GetWebviewController(env, info);
2608    if (!webviewController) {
2609        return nullptr;
2610    }
2611
2612    std::string title = "";
2613    title = webviewController->GetTitle();
2614    napi_create_string_utf8(env, title.c_str(), title.length(), &result);
2615
2616    return result;
2617}
2618
2619napi_value NapiWebviewController::GetPageHeight(napi_env env, napi_callback_info info)
2620{
2621    napi_value result = nullptr;
2622    WebviewController *webviewController = GetWebviewController(env, info);
2623    if (!webviewController) {
2624        return nullptr;
2625    }
2626
2627    int32_t pageHeight = webviewController->GetPageHeight();
2628    napi_create_int32(env, pageHeight, &result);
2629
2630    return result;
2631}
2632
2633napi_value NapiWebviewController::BackOrForward(napi_env env, napi_callback_info info)
2634{
2635    napi_value thisVar = nullptr;
2636    napi_value result = nullptr;
2637    size_t argc = INTEGER_ONE;
2638    napi_value argv[INTEGER_ONE] = {0};
2639    void* data = nullptr;
2640    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2641
2642    if (argc != INTEGER_ONE) {
2643        WVLOG_E("Requires 1 parameters.");
2644        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2645            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
2646        return nullptr;
2647    }
2648
2649    int32_t step = -1;
2650    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], step)) {
2651        WVLOG_E("Parameter is not integer number type.");
2652        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2653            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "step", "number"));
2654        return nullptr;
2655    }
2656
2657    WebviewController *webviewController = nullptr;
2658    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2659    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2660        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2661        return nullptr;
2662    }
2663
2664    ErrCode ret = webviewController->BackOrForward(step);
2665    if (ret != NO_ERROR) {
2666        BusinessError::ThrowErrorByErrcode(env, ret);
2667    }
2668
2669    NAPI_CALL(env, napi_get_undefined(env, &result));
2670    return result;
2671}
2672
2673napi_value NapiWebviewController::StoreWebArchive(napi_env env, napi_callback_info info)
2674{
2675    napi_value thisVar = nullptr;
2676    napi_value result = nullptr;
2677    size_t argc = INTEGER_ONE;
2678    size_t argcPromise = INTEGER_TWO;
2679    size_t argcCallback = INTEGER_THREE;
2680    napi_value argv[INTEGER_THREE] = { 0 };
2681
2682    napi_get_undefined(env, &result);
2683    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2684
2685    if (argc != argcPromise && argc != argcCallback) {
2686        BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
2687            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "two", "three"));
2688        return result;
2689    }
2690    std::string baseName;
2691    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], baseName)) {
2692        BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
2693            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "baseName", "string"));
2694        return result;
2695    }
2696
2697    if (baseName.empty()) {
2698        BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
2699            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NOT_NULL, "baseName"));
2700        return result;
2701    }
2702
2703    bool autoName = false;
2704    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2705    if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_ONE], autoName)) {
2706        BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
2707            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "autoName", "boolean"));
2708        return result;
2709    }
2710
2711    if (argc == argcCallback) {
2712        napi_valuetype valueType = napi_null;
2713        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2714        napi_typeof(env, argv[argcCallback - 1], &valueType);
2715        if (valueType != napi_function) {
2716            BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
2717                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
2718            return result;
2719        }
2720    }
2721    return StoreWebArchiveInternal(env, info, baseName, autoName);
2722}
2723
2724napi_value NapiWebviewController::StoreWebArchiveInternal(napi_env env, napi_callback_info info,
2725    const std::string &baseName, bool autoName)
2726{
2727    napi_value thisVar = nullptr;
2728    size_t argc = INTEGER_ONE;
2729    size_t argcPromise = INTEGER_TWO;
2730    size_t argcCallback = INTEGER_THREE;
2731    napi_value argv[INTEGER_THREE] = {0};
2732
2733    napi_value result = nullptr;
2734    napi_get_undefined(env, &result);
2735    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2736
2737    WebviewController *webviewController = nullptr;
2738    napi_unwrap(env, thisVar, (void **)&webviewController);
2739
2740    if (!webviewController || !webviewController->IsInit()) {
2741        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2742        return result;
2743    }
2744
2745    if (argc == argcCallback) {
2746        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2747        napi_ref jsCallback = nullptr;
2748        napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
2749
2750        if (jsCallback) {
2751            webviewController->StoreWebArchiveCallback(baseName, autoName, env, std::move(jsCallback));
2752        }
2753        return result;
2754    } else if (argc == argcPromise) {
2755        napi_deferred deferred = nullptr;
2756        napi_value promise = nullptr;
2757        napi_create_promise(env, &deferred, &promise);
2758        if (promise && deferred) {
2759            webviewController->StoreWebArchivePromise(baseName, autoName, env, deferred);
2760        }
2761        return promise;
2762    }
2763    return result;
2764}
2765
2766napi_value NapiWebviewController::GetHitTestValue(napi_env env, napi_callback_info info)
2767{
2768    napi_value result = nullptr;
2769    WebviewController *webviewController = GetWebviewController(env, info);
2770    if (!webviewController) {
2771        return nullptr;
2772    }
2773
2774    std::shared_ptr<HitTestResult> nwebResult = webviewController->GetHitTestValue();
2775
2776    napi_create_object(env, &result);
2777
2778    napi_value type;
2779    if (nwebResult) {
2780        napi_create_uint32(env, nwebResult->GetType(), &type);
2781    } else {
2782        napi_create_uint32(env, HitTestResult::UNKNOWN_TYPE, &type);
2783    }
2784    napi_set_named_property(env, result, "type", type);
2785
2786    napi_value extra;
2787    if (nwebResult) {
2788        napi_create_string_utf8(env, nwebResult->GetExtra().c_str(), NAPI_AUTO_LENGTH, &extra);
2789    } else {
2790        napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &extra);
2791    }
2792    napi_set_named_property(env, result, "extra", extra);
2793
2794    return result;
2795}
2796
2797napi_value NapiWebviewController::RequestFocus(napi_env env, napi_callback_info info)
2798{
2799    napi_value result = nullptr;
2800    WebviewController *webviewController = GetWebviewController(env, info);
2801    if (!webviewController) {
2802        return nullptr;
2803    }
2804
2805    webviewController->RequestFocus();
2806    NAPI_CALL(env, napi_get_undefined(env, &result));
2807    return result;
2808}
2809
2810napi_value NapiWebviewController::PostUrl(napi_env env, napi_callback_info info)
2811{
2812    WVLOG_D("NapiWebMessageExt::PostUrl start");
2813    napi_value thisVar = nullptr;
2814    napi_value result = nullptr;
2815    size_t argc = INTEGER_TWO;
2816    napi_value argv[INTEGER_TWO] = { 0 };
2817    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2818    if (argc != INTEGER_TWO) {
2819        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2820            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "two"));
2821        return result;
2822    }
2823
2824    WebviewController *webviewController = nullptr;
2825    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2826    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2827        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2828        return nullptr;
2829    }
2830
2831    std::string url;
2832    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], url)) {
2833        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2834            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "url", "string"));
2835        return result;
2836    }
2837
2838    bool isArrayBuffer = false;
2839    NAPI_CALL(env, napi_is_arraybuffer(env, argv[INTEGER_ONE], &isArrayBuffer));
2840    if (!isArrayBuffer) {
2841        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2842            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "postData", "array"));
2843        return result;
2844    }
2845
2846    char *arrBuf = nullptr;
2847    size_t byteLength = 0;
2848    napi_get_arraybuffer_info(env, argv[INTEGER_ONE], (void **)&arrBuf, &byteLength);
2849
2850    std::vector<char> postData(arrBuf, arrBuf + byteLength);
2851    ErrCode ret = webviewController->PostUrl(url, postData);
2852    if (ret != NO_ERROR) {
2853        if (ret == NWEB_ERROR) {
2854            WVLOG_E("PostData failed");
2855            return result;
2856        }
2857        BusinessError::ThrowErrorByErrcode(env, ret);
2858        return result;
2859    }
2860    NAPI_CALL(env, napi_get_undefined(env, &result));
2861    return result;
2862}
2863
2864napi_value NapiWebviewController::LoadUrl(napi_env env, napi_callback_info info)
2865{
2866    napi_value thisVar = nullptr;
2867    napi_value result = nullptr;
2868    size_t argc = INTEGER_TWO;
2869    napi_value argv[INTEGER_TWO];
2870    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2871    if ((argc != INTEGER_ONE) && (argc != INTEGER_TWO)) {
2872        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2873            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "one", "two"));
2874        return nullptr;
2875    }
2876    WebviewController *webviewController = nullptr;
2877    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2878    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2879        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2880        return nullptr;
2881    }
2882    napi_valuetype webSrcType;
2883    napi_typeof(env, argv[INTEGER_ZERO], &webSrcType);
2884    if (webSrcType != napi_string && webSrcType != napi_object) {
2885        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2886            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_TYPE_INVALID, "url"));
2887        return nullptr;
2888    }
2889    std::string webSrc;
2890    if (!webviewController->ParseUrl(env, argv[INTEGER_ZERO], webSrc)) {
2891        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
2892        return nullptr;
2893    }
2894    if (argc == INTEGER_ONE) {
2895        ErrCode ret = webviewController->LoadUrl(webSrc);
2896        if (ret != NO_ERROR) {
2897            if (ret == NWEB_ERROR) {
2898                return nullptr;
2899            }
2900            BusinessError::ThrowErrorByErrcode(env, ret);
2901            return nullptr;
2902        }
2903        NAPI_CALL(env, napi_get_undefined(env, &result));
2904        return result;
2905    }
2906    return LoadUrlWithHttpHeaders(env, info, webSrc, argv, webviewController);
2907}
2908
2909napi_value NapiWebviewController::LoadUrlWithHttpHeaders(napi_env env, napi_callback_info info, const std::string& url,
2910    const napi_value* argv, WebviewController* webviewController)
2911{
2912    napi_value result = nullptr;
2913    std::map<std::string, std::string> httpHeaders;
2914    napi_value array = argv[INTEGER_ONE];
2915    bool isArray = false;
2916    napi_is_array(env, array, &isArray);
2917    if (isArray) {
2918        uint32_t arrayLength = INTEGER_ZERO;
2919        napi_get_array_length(env, array, &arrayLength);
2920        for (uint32_t i = 0; i < arrayLength; ++i) {
2921            std::string key;
2922            std::string value;
2923            napi_value obj = nullptr;
2924            napi_value keyObj = nullptr;
2925            napi_value valueObj = nullptr;
2926            napi_get_element(env, array, i, &obj);
2927            if (napi_get_named_property(env, obj, "headerKey", &keyObj) != napi_ok) {
2928                continue;
2929            }
2930            if (napi_get_named_property(env, obj, "headerValue", &valueObj) != napi_ok) {
2931                continue;
2932            }
2933            NapiParseUtils::ParseString(env, keyObj, key);
2934            NapiParseUtils::ParseString(env, valueObj, value);
2935            httpHeaders[key] = value;
2936        }
2937    } else {
2938        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2939        return nullptr;
2940    }
2941
2942    ErrCode ret = webviewController->LoadUrl(url, httpHeaders);
2943    if (ret != NO_ERROR) {
2944        if (ret == NWEB_ERROR) {
2945            WVLOG_E("LoadUrl failed.");
2946            return nullptr;
2947        }
2948        BusinessError::ThrowErrorByErrcode(env, ret);
2949        return nullptr;
2950    }
2951    NAPI_CALL(env, napi_get_undefined(env, &result));
2952    return result;
2953}
2954
2955napi_value NapiWebviewController::LoadData(napi_env env, napi_callback_info info)
2956{
2957    napi_value thisVar = nullptr;
2958    napi_value result = nullptr;
2959    size_t argc = INTEGER_FIVE;
2960    napi_value argv[INTEGER_FIVE];
2961    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2962    if ((argc != INTEGER_THREE) && (argc != INTEGER_FOUR) &&
2963        (argc != INTEGER_FIVE)) {
2964        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
2965            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "three", "four"));
2966        return nullptr;
2967    }
2968    WebviewController *webviewController = nullptr;
2969    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2970    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2971        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2972        return nullptr;
2973    }
2974    std::string data;
2975    std::string mimeType;
2976    std::string encoding;
2977    std::string baseUrl;
2978    std::string historyUrl;
2979    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], data) ||
2980        !NapiParseUtils::ParseString(env, argv[INTEGER_ONE], mimeType) ||
2981        !NapiParseUtils::ParseString(env, argv[INTEGER_TWO], encoding)) {
2982        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, ParamCheckErrorMsgTemplate::TYPE_ALL_STRING);
2983        return nullptr;
2984    }
2985    if ((argc >= INTEGER_FOUR) && !NapiParseUtils::ParseString(env, argv[INTEGER_THREE], baseUrl)) {
2986        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, ParamCheckErrorMsgTemplate::TYPE_ALL_STRING);
2987        return nullptr;
2988    }
2989    if ((argc == INTEGER_FIVE) && !NapiParseUtils::ParseString(env, argv[INTEGER_FOUR], historyUrl)) {
2990        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, ParamCheckErrorMsgTemplate::TYPE_ALL_STRING);
2991        return nullptr;
2992    }
2993    ErrCode ret = webviewController->LoadData(data, mimeType, encoding, baseUrl, historyUrl);
2994    if (ret != NO_ERROR) {
2995        if (ret == NWEB_ERROR) {
2996            WVLOG_E("LoadData failed.");
2997            return nullptr;
2998        }
2999        BusinessError::ThrowErrorByErrcode(env, ret);
3000        return nullptr;
3001    }
3002    NAPI_CALL(env, napi_get_undefined(env, &result));
3003    return result;
3004}
3005
3006napi_value NapiWebviewController::GetHitTest(napi_env env, napi_callback_info info)
3007{
3008    napi_value result = nullptr;
3009    WebviewController *webviewController = GetWebviewController(env, info);
3010    if (!webviewController) {
3011        return nullptr;
3012    }
3013
3014    int32_t type = webviewController->GetHitTest();
3015    napi_create_int32(env, type, &result);
3016    return result;
3017}
3018
3019napi_value NapiWebviewController::ClearMatches(napi_env env, napi_callback_info info)
3020{
3021    napi_value thisVar = nullptr;
3022    napi_value result = nullptr;
3023
3024    NAPI_CALL(env, napi_get_undefined(env, &result));
3025    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3026
3027    WebviewController *controller = nullptr;
3028    napi_unwrap(env, thisVar, (void **)&controller);
3029    if (!controller || !controller->IsInit()) {
3030        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3031        return result;
3032    }
3033    controller->ClearMatches();
3034    return result;
3035}
3036
3037napi_value NapiWebviewController::SearchNext(napi_env env, napi_callback_info info)
3038{
3039    napi_value thisVar = nullptr;
3040    napi_value result = nullptr;
3041    size_t argc = INTEGER_ONE;
3042    napi_value argv[INTEGER_ONE] = { 0 };
3043
3044    NAPI_CALL(env, napi_get_undefined(env, &result));
3045    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3046    if (argc != INTEGER_ONE) {
3047        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3048            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3049        return result;
3050    }
3051    bool forward;
3052    if (!NapiParseUtils::ParseBoolean(env, argv[0], forward)) {
3053        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3054            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "forward", "boolean"));
3055        return result;
3056    }
3057
3058    WebviewController *controller = nullptr;
3059    napi_unwrap(env, thisVar, (void **)&controller);
3060    if (!controller || !controller->IsInit()) {
3061        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3062        return result;
3063    }
3064    controller->SearchNext(forward);
3065    return result;
3066}
3067
3068napi_value NapiWebviewController::SearchAllAsync(napi_env env, napi_callback_info info)
3069{
3070    napi_value thisVar = nullptr;
3071    napi_value result = nullptr;
3072    size_t argc = INTEGER_ONE;
3073    napi_value argv[INTEGER_ONE] = { 0 };
3074
3075    NAPI_CALL(env, napi_get_undefined(env, &result));
3076    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3077    if (argc != INTEGER_ONE) {
3078        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3079            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3080        return result;
3081    }
3082    std::string searchString;
3083    if (!NapiParseUtils::ParseString(env, argv[0], searchString)) {
3084        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3085            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "searchString", "number"));
3086        return result;
3087    }
3088
3089    WebviewController *controller = nullptr;
3090    napi_unwrap(env, thisVar, (void **)&controller);
3091    if (!controller || !controller->IsInit()) {
3092        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3093        return result;
3094    }
3095    controller->SearchAllAsync(searchString);
3096    return result;
3097}
3098
3099napi_value NapiWebviewController::ClearSslCache(napi_env env, napi_callback_info info)
3100{
3101    napi_value thisVar = nullptr;
3102    napi_value result = nullptr;
3103
3104    NAPI_CALL(env, napi_get_undefined(env, &result));
3105    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3106
3107    WebviewController *controller = nullptr;
3108    napi_unwrap(env, thisVar, (void **)&controller);
3109    if (!controller || !controller->IsInit()) {
3110        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3111        return result;
3112    }
3113    controller->ClearSslCache();
3114    return result;
3115}
3116
3117napi_value NapiWebviewController::ClearClientAuthenticationCache(napi_env env, napi_callback_info info)
3118{
3119    napi_value thisVar = nullptr;
3120    napi_value result = nullptr;
3121
3122    NAPI_CALL(env, napi_get_undefined(env, &result));
3123    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3124
3125    WebviewController *controller = nullptr;
3126    napi_unwrap(env, thisVar, (void **)&controller);
3127    if (!controller || !controller->IsInit()) {
3128        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3129        return result;
3130    }
3131    controller->ClearClientAuthenticationCache();
3132
3133    return result;
3134}
3135
3136napi_value NapiWebviewController::Stop(napi_env env, napi_callback_info info)
3137{
3138    napi_value thisVar = nullptr;
3139    napi_value result = nullptr;
3140    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3141
3142    WebviewController *controller = nullptr;
3143    napi_unwrap(env, thisVar, (void **)&controller);
3144    if (!controller || !controller->IsInit()) {
3145        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3146        return result;
3147    }
3148    controller->Stop();
3149
3150    NAPI_CALL(env, napi_get_undefined(env, &result));
3151    return result;
3152}
3153
3154napi_value NapiWebviewController::Zoom(napi_env env, napi_callback_info info)
3155{
3156    napi_value thisVar = nullptr;
3157    napi_value result = nullptr;
3158    size_t argc = INTEGER_ONE;
3159    napi_value argv[INTEGER_ONE] = { 0 };
3160
3161    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3162    if (argc != INTEGER_ONE) {
3163        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3164            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3165        return result;
3166    }
3167    float factor = 0.0;
3168    if (!NapiParseUtils::ParseFloat(env, argv[0], factor)) {
3169        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3170            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "factor", "number"));
3171        return result;
3172    }
3173
3174    WebviewController *controller = nullptr;
3175    napi_unwrap(env, thisVar, (void **)&controller);
3176    if (!controller || !controller->IsInit()) {
3177        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3178        return result;
3179    }
3180
3181    ErrCode ret = controller->Zoom(factor);
3182    if (ret != NO_ERROR) {
3183        if (ret == NWEB_ERROR) {
3184            WVLOG_E("Zoom failed.");
3185            return result;
3186        }
3187        BusinessError::ThrowErrorByErrcode(env, ret);
3188    }
3189
3190    NAPI_CALL(env, napi_get_undefined(env, &result));
3191    return result;
3192}
3193
3194napi_value NapiWebviewController::InnerCompleteWindowNew(napi_env env, napi_callback_info info)
3195{
3196    napi_value thisVar = nullptr;
3197    size_t argc = INTEGER_ONE;
3198    napi_value argv[INTEGER_ONE];
3199    void* data = nullptr;
3200    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3201
3202    int32_t parentNwebId = -1;
3203    if (!NapiParseUtils::ParseInt32(env, argv[0], parentNwebId) || parentNwebId == -1) {
3204        WVLOG_E("Parse parent nweb id failed.");
3205        return nullptr;
3206    }
3207    WebviewController* webviewController = nullptr;
3208    napi_status status = napi_unwrap(env, thisVar, (void**)&webviewController);
3209    if ((!webviewController) || (status != napi_ok)) {
3210        WVLOG_E("webviewController is nullptr.");
3211        return nullptr;
3212    }
3213    webviewController->InnerCompleteWindowNew(parentNwebId);
3214    return thisVar;
3215}
3216
3217napi_value NapiWebviewController::RegisterJavaScriptProxy(napi_env env, napi_callback_info info)
3218{
3219    napi_value thisVar = nullptr;
3220    napi_value result = nullptr;
3221    size_t argc = INTEGER_FIVE;
3222    napi_value argv[INTEGER_FIVE] = { 0 };
3223    napi_get_undefined(env, &result);
3224    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3225    if (argc != INTEGER_THREE && argc != INTEGER_FOUR && argc != INTEGER_FIVE) {
3226        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3227            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_THREE, "three", "four", "five"));
3228        return result;
3229    }
3230    napi_valuetype valueType = napi_undefined;
3231    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
3232    if (valueType != napi_object) {
3233        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3234            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "object", "object"));
3235        return result;
3236    }
3237    RegisterJavaScriptProxyParam param;
3238    if (!ParseRegisterJavaScriptProxyParam(env, argc, argv, &param)) {
3239        return result;
3240    }
3241    WebviewController* controller = nullptr;
3242    napi_unwrap(env, thisVar, (void **)&controller);
3243    if (!controller || !controller->IsInit()) {
3244        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3245        return result;
3246    }
3247    controller->SetNWebJavaScriptResultCallBack();
3248    controller->RegisterJavaScriptProxy(param);
3249    return result;
3250}
3251
3252napi_value NapiWebviewController::DeleteJavaScriptRegister(napi_env env, napi_callback_info info)
3253{
3254    napi_value thisVar = nullptr;
3255    napi_value result = nullptr;
3256    size_t argc = INTEGER_ONE;
3257    napi_value argv[INTEGER_ONE] = { 0 };
3258
3259    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3260    if (argc != INTEGER_ONE) {
3261        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3262            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3263        return result;
3264    }
3265
3266    std::string objName;
3267    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], objName)) {
3268        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3269            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "name", "string"));
3270        return result;
3271    }
3272
3273    WebviewController *controller = nullptr;
3274    napi_unwrap(env, thisVar, (void **)&controller);
3275    if (!controller || !controller->IsInit()) {
3276        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3277        return result;
3278    }
3279    ErrCode ret = controller->DeleteJavaScriptRegister(objName, {});
3280    if (ret != NO_ERROR) {
3281        BusinessError::ThrowErrorByErrcode(env, ret);
3282        return result;
3283    }
3284
3285    NAPI_CALL(env, napi_get_undefined(env, &result));
3286    return result;
3287}
3288
3289napi_value NapiWebviewController::RunJavaScript(napi_env env, napi_callback_info info)
3290{
3291    return RunJS(env, info, false);
3292}
3293
3294napi_value NapiWebviewController::RunJavaScriptExt(napi_env env, napi_callback_info info)
3295{
3296    return RunJS(env, info, true);
3297}
3298
3299napi_value NapiWebviewController::RunJS(napi_env env, napi_callback_info info, bool extention)
3300{
3301    napi_value thisVar = nullptr;
3302    napi_value result = nullptr;
3303    size_t argc = INTEGER_ONE;
3304    size_t argcPromise = INTEGER_ONE;
3305    size_t argcCallback = INTEGER_TWO;
3306    napi_value argv[INTEGER_TWO] = { 0 };
3307
3308    napi_get_undefined(env, &result);
3309    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3310
3311    if (argc != argcPromise && argc != argcCallback) {
3312        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3313            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "two"));
3314        return result;
3315    }
3316
3317    if (argc == argcCallback) {
3318        napi_valuetype valueType = napi_null;
3319        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3320        napi_typeof(env, argv[argcCallback - 1], &valueType);
3321        if (valueType != napi_function) {
3322            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3323                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
3324            return result;
3325        }
3326    }
3327
3328    if (maxFdNum_ == -1) {
3329        maxFdNum_ =
3330            std::atoi(NWebAdapterHelper::Instance().ParsePerfConfig("flowBufferConfig", "maxFdNumber").c_str());
3331    }
3332
3333    if (usedFd_.load() < maxFdNum_) {
3334        return RunJavaScriptInternalExt(env, info, extention);
3335    }
3336
3337    std::string script;
3338    napi_valuetype valueType = napi_undefined;
3339    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
3340    bool parseResult = (valueType == napi_string) ? NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], script) :
3341        NapiParseUtils::ParseArrayBuffer(env, argv[INTEGER_ZERO], script);
3342    if (!parseResult) {
3343        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3344            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "script", "string"));
3345        return result;
3346    }
3347    return RunJavaScriptInternal(env, info, script, extention);
3348}
3349
3350napi_value NapiWebviewController::RunCreatePDFExt(napi_env env, napi_callback_info info)
3351{
3352    napi_value thisVar = nullptr;
3353    napi_value result = nullptr;
3354    size_t argc = INTEGER_ONE;
3355    size_t argcPromise = INTEGER_ONE;
3356    size_t argcCallback = INTEGER_TWO;
3357    napi_value argv[INTEGER_TWO] = { 0 };
3358
3359    napi_get_undefined(env, &result);
3360    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3361
3362    WebviewController* webviewController = nullptr;
3363    napi_unwrap(env, thisVar, (void**)&webviewController);
3364
3365    if (!webviewController || !webviewController->IsInit()) {
3366        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3367        return result;
3368    }
3369
3370    std::shared_ptr<NWebPDFConfigArgs> pdfConfig = ParsePDFConfigArgs(env, argv[INTEGER_ZERO]);
3371    if (pdfConfig == nullptr) {
3372        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
3373        return nullptr;
3374    }
3375
3376    if (argc == argcCallback) {
3377        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3378        napi_ref jsCallback = nullptr;
3379        napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
3380
3381        if (jsCallback) {
3382            webviewController->CreatePDFCallbackExt(env, pdfConfig, std::move(jsCallback));
3383        }
3384        return result;
3385    } else if (argc == argcPromise) {
3386        napi_deferred deferred = nullptr;
3387        napi_value promise = nullptr;
3388        napi_create_promise(env, &deferred, &promise);
3389        if (promise && deferred) {
3390            webviewController->CreatePDFPromiseExt(env, pdfConfig, deferred);
3391        }
3392        return promise;
3393    }
3394    return result;
3395}
3396
3397napi_value NapiWebviewController::RunJavaScriptInternal(napi_env env, napi_callback_info info,
3398    const std::string &script, bool extention)
3399{
3400    napi_value thisVar = nullptr;
3401    size_t argc = INTEGER_ONE;
3402    size_t argcPromise = INTEGER_ONE;
3403    size_t argcCallback = INTEGER_TWO;
3404    napi_value argv[INTEGER_TWO] = {0};
3405
3406    napi_value result = nullptr;
3407    napi_get_undefined(env, &result);
3408    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3409
3410    WebviewController *webviewController = nullptr;
3411    napi_unwrap(env, thisVar, (void **)&webviewController);
3412
3413    if (!webviewController || !webviewController->IsInit()) {
3414        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3415        return result;
3416    }
3417
3418    if (argc == argcCallback) {
3419        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3420        napi_ref jsCallback = nullptr;
3421        napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
3422
3423        if (jsCallback) {
3424            webviewController->RunJavaScriptCallback(script, env, std::move(jsCallback), extention);
3425        }
3426        return result;
3427    } else if (argc == argcPromise) {
3428        napi_deferred deferred = nullptr;
3429        napi_value promise = nullptr;
3430        napi_create_promise(env, &deferred, &promise);
3431        if (promise && deferred) {
3432            webviewController->RunJavaScriptPromise(script, env, deferred, extention);
3433        }
3434        return promise;
3435    }
3436    return result;
3437}
3438
3439ErrCode NapiWebviewController::ConstructFlowbuf(napi_env env, napi_value argv, int& fd, size_t& scriptLength)
3440{
3441    auto flowbufferAdapter = OhosAdapterHelper::GetInstance().CreateFlowbufferAdapter();
3442    if (!flowbufferAdapter) {
3443        return NWebError::NEW_OOM;
3444    }
3445    flowbufferAdapter->StartPerformanceBoost();
3446
3447    napi_valuetype valueType = napi_undefined;
3448    napi_typeof(env, argv, &valueType);
3449
3450    ErrCode constructResult = (valueType == napi_string) ?
3451        NapiParseUtils::ConstructStringFlowbuf(env, argv, fd, scriptLength) :
3452        NapiParseUtils::ConstructArrayBufFlowbuf(env, argv, fd, scriptLength);
3453    return constructResult;
3454}
3455
3456napi_value NapiWebviewController::RunJSBackToOriginal(napi_env env, napi_callback_info info,
3457    bool extention, napi_value argv, napi_value result)
3458{
3459    std::string script;
3460    napi_valuetype valueType = napi_undefined;
3461    napi_typeof(env, argv, &valueType);
3462    bool parseResult = (valueType == napi_string) ? NapiParseUtils::ParseString(env, argv, script) :
3463        NapiParseUtils::ParseArrayBuffer(env, argv, script);
3464    if (!parseResult) {
3465        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
3466        return result;
3467    }
3468    return RunJavaScriptInternal(env, info, script, extention);
3469}
3470
3471napi_value NapiWebviewController::RunJavaScriptInternalExt(napi_env env, napi_callback_info info, bool extention)
3472{
3473    napi_value thisVar = nullptr;
3474    napi_value result = nullptr;
3475    size_t argc = INTEGER_ONE;
3476    size_t argcPromise = INTEGER_ONE;
3477    size_t argcCallback = INTEGER_TWO;
3478    napi_value argv[INTEGER_TWO] = {0};
3479
3480    napi_get_undefined(env, &result);
3481    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3482
3483    int fd;
3484    size_t scriptLength;
3485    ErrCode constructResult = ConstructFlowbuf(env, argv[INTEGER_ZERO], fd, scriptLength);
3486    if (constructResult != NO_ERROR) {
3487        return RunJSBackToOriginal(env, info, extention, argv[INTEGER_ZERO], result);
3488    }
3489    usedFd_++;
3490
3491    WebviewController *webviewController = nullptr;
3492    napi_unwrap(env, thisVar, (void **)&webviewController);
3493
3494    if (!webviewController || !webviewController->IsInit()) {
3495        close(fd);
3496        usedFd_--;
3497        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3498        return result;
3499    }
3500
3501    if (argc == argcCallback) {
3502        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3503        napi_ref jsCallback = nullptr;
3504        napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
3505
3506        if (jsCallback) {
3507            // RunJavaScriptCallbackExt will close fd after IPC
3508            webviewController->RunJavaScriptCallbackExt(fd, scriptLength, env, std::move(jsCallback), extention);
3509        }
3510        usedFd_--;
3511        return result;
3512    } else if (argc == argcPromise) {
3513        napi_deferred deferred = nullptr;
3514        napi_value promise = nullptr;
3515        napi_create_promise(env, &deferred, &promise);
3516        if (promise && deferred) {
3517            // RunJavaScriptCallbackExt will close fd after IPC
3518            webviewController->RunJavaScriptPromiseExt(fd, scriptLength, env, deferred, extention);
3519        }
3520        usedFd_--;
3521        return promise;
3522    }
3523    close(fd);
3524    usedFd_--;
3525    return result;
3526}
3527
3528napi_value NapiWebviewController::GetUrl(napi_env env, napi_callback_info info)
3529{
3530    napi_value result = nullptr;
3531    WebviewController *webviewController = GetWebviewController(env, info);
3532    if (!webviewController) {
3533        return nullptr;
3534    }
3535
3536    std::string url = "";
3537    url = webviewController->GetUrl();
3538    napi_create_string_utf8(env, url.c_str(), url.length(), &result);
3539
3540    return result;
3541}
3542
3543napi_value NapiWebviewController::GetOriginalUrl(napi_env env, napi_callback_info info)
3544{
3545    napi_value result = nullptr;
3546    WebviewController *webviewController = GetWebviewController(env, info);
3547    if (!webviewController) {
3548        return nullptr;
3549    }
3550
3551    std::string url = "";
3552    url = webviewController->GetOriginalUrl();
3553    napi_create_string_utf8(env, url.c_str(), url.length(), &result);
3554    return result;
3555}
3556
3557napi_value NapiWebviewController::TerminateRenderProcess(napi_env env, napi_callback_info info)
3558{
3559    napi_value result = nullptr;
3560    WebviewController *webviewController = GetWebviewController(env, info);
3561    if (!webviewController) {
3562        return nullptr;
3563    }
3564    bool ret = false;
3565    ret = webviewController->TerminateRenderProcess();
3566    NAPI_CALL(env, napi_get_boolean(env, ret, &result));
3567    return result;
3568}
3569
3570napi_value NapiWebviewController::SetNetworkAvailable(napi_env env, napi_callback_info info)
3571{
3572    napi_value thisVar = nullptr;
3573    napi_value result = nullptr;
3574    size_t argc = INTEGER_ONE;
3575    napi_value argv[INTEGER_ONE] = { 0 };
3576    bool enable;
3577
3578    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3579    if (argc != INTEGER_ONE) {
3580        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3581            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3582        return result;
3583    }
3584
3585    if (!NapiParseUtils::ParseBoolean(env, argv[0], enable)) {
3586        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3587            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "enable", "booleane"));
3588        return result;
3589    }
3590
3591    WebviewController *webviewController = nullptr;
3592    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
3593    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
3594        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3595        return nullptr;
3596    }
3597    webviewController->PutNetworkAvailable(enable);
3598    return result;
3599}
3600
3601napi_value NapiWebviewController::InnerGetWebId(napi_env env, napi_callback_info info)
3602{
3603    napi_value thisVar = nullptr;
3604    napi_value result = nullptr;
3605    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3606
3607    WebviewController *webviewController = nullptr;
3608    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
3609    int32_t webId = -1;
3610    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
3611        WVLOG_E("Init error. The WebviewController must be associated with a Web component.");
3612        napi_create_int32(env, webId, &result);
3613        return result;
3614    }
3615
3616    webId = webviewController->GetWebId();
3617    napi_create_int32(env, webId, &result);
3618
3619    return result;
3620}
3621
3622napi_value NapiWebviewController::HasImage(napi_env env, napi_callback_info info)
3623{
3624    napi_value thisVar = nullptr;
3625    napi_value result = nullptr;
3626    size_t argc = INTEGER_ONE;
3627    size_t argcPromiseParaNum = INTEGER_ZERO;
3628    size_t argcCallbackParaNum = INTEGER_ONE;
3629    napi_value argv[INTEGER_ONE] = { 0 };
3630
3631    napi_get_undefined(env, &result);
3632    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3633
3634    if (argc != argcPromiseParaNum && argc != argcCallbackParaNum) {
3635        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3636            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "zero", "one"));
3637        return result;
3638    }
3639
3640    if (argc == argcCallbackParaNum) {
3641        napi_valuetype valueType = napi_null;
3642        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3643        napi_typeof(env, argv[argcCallbackParaNum - 1], &valueType);
3644        if (valueType != napi_function) {
3645            NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
3646                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
3647            return result;
3648        }
3649    }
3650    return HasImageInternal(env, info);
3651}
3652
3653napi_value NapiWebviewController::HasImageInternal(napi_env env, napi_callback_info info)
3654{
3655    napi_value thisVar = nullptr;
3656    size_t argc = INTEGER_ONE;
3657    size_t argcPromiseParaNum = INTEGER_ZERO;
3658    size_t argcCallbackParaNum = INTEGER_ONE;
3659    napi_value argv[INTEGER_ONE] = { 0 };
3660
3661    napi_value result = nullptr;
3662    napi_get_undefined(env, &result);
3663    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3664
3665    WebviewController *webviewController = nullptr;
3666    napi_unwrap(env, thisVar, (void **)&webviewController);
3667
3668    if (!webviewController || !webviewController->IsInit()) {
3669        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3670        return result;
3671    }
3672
3673    if (argc == argcCallbackParaNum) {
3674        napi_ref jsCallback = nullptr;
3675        napi_create_reference(env, argv[argcCallbackParaNum - 1], 1, &jsCallback);
3676
3677        if (jsCallback) {
3678            ErrCode ret = webviewController->HasImagesCallback(env, std::move(jsCallback));
3679            if (ret == NWEB_ERROR) {
3680                return nullptr;
3681            } else if (ret != NO_ERROR) {
3682                BusinessError::ThrowErrorByErrcode(env, ret);
3683                return nullptr;
3684            }
3685        }
3686        return result;
3687    } else if (argc == argcPromiseParaNum) {
3688        napi_deferred deferred = nullptr;
3689        napi_value promise = nullptr;
3690        napi_create_promise(env, &deferred, &promise);
3691        if (promise && deferred) {
3692            ErrCode ret = webviewController->HasImagesPromise(env, deferred);
3693            if (ret == NWEB_ERROR) {
3694                return nullptr;
3695            } else if (ret != NO_ERROR) {
3696                BusinessError::ThrowErrorByErrcode(env, ret);
3697                return nullptr;
3698            }
3699        }
3700        return promise;
3701    }
3702    return result;
3703}
3704
3705napi_value NapiWebviewController::RemoveCache(napi_env env, napi_callback_info info)
3706{
3707    napi_value thisVar = nullptr;
3708    napi_value result = nullptr;
3709    size_t argc = INTEGER_ONE;
3710    napi_value argv[INTEGER_ONE] = { 0 };
3711    bool includeDiskFiles;
3712
3713    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3714    if (argc != INTEGER_ONE) {
3715        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3716            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3717        return result;
3718    }
3719
3720    if (!NapiParseUtils::ParseBoolean(env, argv[0], includeDiskFiles)) {
3721        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3722            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "clearRom", "boolean"));
3723        return result;
3724    }
3725
3726    WebviewController *webviewController = nullptr;
3727    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
3728    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
3729        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3730        return nullptr;
3731    }
3732    webviewController->RemoveCache(includeDiskFiles);
3733    return result;
3734}
3735
3736napi_value NapiWebviewController::IsIncognitoMode(napi_env env, napi_callback_info info)
3737{
3738    napi_value result = nullptr;
3739    WebviewController *webviewController = GetWebviewController(env, info);
3740    if (!webviewController) {
3741        return nullptr;
3742    }
3743
3744    bool incognitoMode = false;
3745    incognitoMode = webviewController->IsIncognitoMode();
3746    NAPI_CALL(env, napi_get_boolean(env, incognitoMode, &result));
3747    return result;
3748}
3749
3750napi_value NapiWebHistoryList::JsConstructor(napi_env env, napi_callback_info info)
3751{
3752    napi_value thisVar = nullptr;
3753    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3754    return thisVar;
3755}
3756
3757Media::PixelFormat getColorType(ImageColorType colorType)
3758{
3759    Media::PixelFormat pixelFormat_;
3760    switch (colorType) {
3761        case ImageColorType::COLOR_TYPE_UNKNOWN:
3762            pixelFormat_ = Media::PixelFormat::UNKNOWN;
3763            break;
3764        case ImageColorType::COLOR_TYPE_RGBA_8888:
3765            pixelFormat_ = Media::PixelFormat::RGBA_8888;
3766            break;
3767        case ImageColorType::COLOR_TYPE_BGRA_8888:
3768            pixelFormat_ = Media::PixelFormat::BGRA_8888;
3769            break;
3770        default:
3771            pixelFormat_ = Media::PixelFormat::UNKNOWN;
3772            break;
3773    }
3774    return pixelFormat_;
3775}
3776
3777Media::AlphaType getAlphaType(ImageAlphaType alphaType)
3778{
3779    Media::AlphaType alphaType_;
3780    switch (alphaType) {
3781        case ImageAlphaType::ALPHA_TYPE_UNKNOWN:
3782            alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
3783            break;
3784        case ImageAlphaType::ALPHA_TYPE_OPAQUE:
3785            alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
3786            break;
3787        case ImageAlphaType::ALPHA_TYPE_PREMULTIPLIED:
3788            alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
3789            break;
3790        case ImageAlphaType::ALPHA_TYPE_POSTMULTIPLIED:
3791            alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
3792            break;
3793        default:
3794            alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
3795            break;
3796    }
3797    return alphaType_;
3798}
3799
3800napi_value NapiWebHistoryList::GetFavicon(napi_env env, std::shared_ptr<NWebHistoryItem> item)
3801{
3802    napi_value result = nullptr;
3803    void *data = nullptr;
3804    int32_t width = 0;
3805    int32_t height = 0;
3806    ImageColorType colorType = ImageColorType::COLOR_TYPE_UNKNOWN;
3807    ImageAlphaType alphaType = ImageAlphaType::ALPHA_TYPE_UNKNOWN;
3808    bool isGetFavicon = item->GetFavicon(&data, width, height, colorType, alphaType);
3809    napi_get_null(env, &result);
3810
3811    if (!isGetFavicon) {
3812        return result;
3813    }
3814
3815    Media::InitializationOptions opt;
3816    opt.size.width = width;
3817    opt.size.height = height;
3818    opt.pixelFormat = getColorType(colorType);
3819    opt.alphaType = getAlphaType(alphaType);
3820    opt.editable = true;
3821    auto pixelMap = Media::PixelMap::Create(opt);
3822    if (pixelMap == nullptr) {
3823        return result;
3824    }
3825    uint64_t stride = static_cast<uint64_t>(width) << 2;
3826    uint64_t bufferSize = stride * static_cast<uint64_t>(height);
3827    pixelMap->WritePixels(static_cast<const uint8_t *>(data), bufferSize);
3828    std::shared_ptr<Media::PixelMap> pixelMapToJs(pixelMap.release());
3829    napi_value jsPixelMap = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMapToJs);
3830    return jsPixelMap;
3831}
3832
3833napi_value NapiWebHistoryList::GetItem(napi_env env, napi_callback_info info)
3834{
3835    napi_value thisVar = nullptr;
3836    napi_value result = nullptr;
3837    size_t argc = INTEGER_ONE;
3838    napi_value argv[INTEGER_ONE] = { 0 };
3839    int32_t index;
3840    WebHistoryList *historyList = nullptr;
3841
3842    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
3843    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&historyList));
3844    if (historyList == nullptr) {
3845        WVLOG_E("unwrap historyList failed.");
3846        return result;
3847    }
3848    if (argc != INTEGER_ONE) {
3849        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3850            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
3851        return result;
3852    }
3853    if (!NapiParseUtils::ParseInt32(env, argv[0], index)) {
3854        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3855            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NOT_NULL_TWO, "index", "int"));
3856        return result;
3857    }
3858    if (index >= historyList->GetListSize() || index < 0) {
3859        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
3860            "BusinessError 401: Parameter error. The value of index must be greater than or equal to 0");
3861        return result;
3862    }
3863
3864    std::shared_ptr<NWebHistoryItem> item = historyList->GetItem(index);
3865    if (!item) {
3866        return result;
3867    }
3868
3869    napi_create_object(env, &result);
3870    std::string historyUrl = item->GetHistoryUrl();
3871    std::string historyRawUrl = item->GetHistoryRawUrl();
3872    std::string title = item->GetHistoryTitle();
3873
3874    napi_value js_historyUrl;
3875    napi_create_string_utf8(env, historyUrl.c_str(), historyUrl.length(), &js_historyUrl);
3876    napi_set_named_property(env, result, "historyUrl", js_historyUrl);
3877
3878    napi_value js_historyRawUrl;
3879    napi_create_string_utf8(env, historyRawUrl.c_str(), historyRawUrl.length(), &js_historyRawUrl);
3880    napi_set_named_property(env, result, "historyRawUrl", js_historyRawUrl);
3881
3882    napi_value js_title;
3883    napi_create_string_utf8(env, title.c_str(), title.length(), &js_title);
3884    napi_set_named_property(env, result, "title", js_title);
3885
3886    napi_value js_icon = GetFavicon(env, item);
3887    napi_set_named_property(env, result, "icon", js_icon);
3888    return result;
3889}
3890
3891napi_value NapiWebviewController::getBackForwardEntries(napi_env env, napi_callback_info info)
3892{
3893    napi_value thisVar = nullptr;
3894    napi_value result = nullptr;
3895    WebviewController *webviewController = nullptr;
3896
3897    NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
3898    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
3899    if (webviewController == nullptr || !webviewController->IsInit()) {
3900        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3901        return nullptr;
3902    }
3903
3904    std::shared_ptr<NWebHistoryList> list = webviewController->GetHistoryList();
3905    if (!list) {
3906        return result;
3907    }
3908
3909    int32_t currentIndex = list->GetCurrentIndex();
3910    int32_t size = list->GetListSize();
3911
3912    napi_value historyList = nullptr;
3913    NAPI_CALL(env, napi_get_reference_value(env, g_historyListRef, &historyList));
3914    NAPI_CALL(env, napi_new_instance(env, historyList, 0, NULL, &result));
3915
3916    napi_value js_currentIndex;
3917    napi_create_int32(env, currentIndex, &js_currentIndex);
3918    napi_set_named_property(env, result, "currentIndex", js_currentIndex);
3919
3920    napi_value js_size;
3921    napi_create_int32(env, size, &js_size);
3922    napi_set_named_property(env, result, "size", js_size);
3923
3924    WebHistoryList *webHistoryList = new (std::nothrow) WebHistoryList(list);
3925    if (webHistoryList == nullptr) {
3926        return result;
3927    }
3928
3929    NAPI_CALL(env, napi_wrap(env, result, webHistoryList,
3930        [](napi_env env, void *data, void *hint) {
3931            WebHistoryList *webHistoryList = static_cast<WebHistoryList *>(data);
3932            delete webHistoryList;
3933        },
3934        nullptr, nullptr));
3935
3936    return result;
3937}
3938
3939napi_value NapiWebviewController::GetFavicon(napi_env env, napi_callback_info info)
3940{
3941    napi_value thisVar = nullptr;
3942    napi_value result = nullptr;
3943    napi_get_null(env, &result);
3944    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3945
3946    WebviewController *webviewController = nullptr;
3947    napi_unwrap(env, thisVar, (void **)&webviewController);
3948
3949    if (!webviewController || !webviewController->IsInit()) {
3950        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3951        return result;
3952    }
3953
3954    const void *data = nullptr;
3955    size_t width = 0;
3956    size_t height = 0;
3957    ImageColorType colorType = ImageColorType::COLOR_TYPE_UNKNOWN;
3958    ImageAlphaType alphaType = ImageAlphaType::ALPHA_TYPE_UNKNOWN;
3959    bool isGetFavicon = webviewController->GetFavicon(&data, width, height, colorType, alphaType);
3960    if (!isGetFavicon) {
3961        return result;
3962    }
3963
3964    Media::InitializationOptions opt;
3965    opt.size.width = static_cast<int32_t>(width);
3966    opt.size.height = static_cast<int32_t>(height);
3967    opt.pixelFormat = getColorType(colorType);
3968    opt.alphaType = getAlphaType(alphaType);
3969    opt.editable = true;
3970    auto pixelMap = Media::PixelMap::Create(opt);
3971    if (pixelMap == nullptr) {
3972        return result;
3973    }
3974    uint64_t stride = static_cast<uint64_t>(width) << 2;
3975    uint64_t bufferSize = stride * static_cast<uint64_t>(height);
3976    pixelMap->WritePixels(static_cast<const uint8_t *>(data), bufferSize);
3977    std::shared_ptr<Media::PixelMap> pixelMapToJs(pixelMap.release());
3978    napi_value jsPixelMap = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMapToJs);
3979    return jsPixelMap;
3980}
3981
3982napi_value NapiWebviewController::SerializeWebState(napi_env env, napi_callback_info info)
3983{
3984    napi_value thisVar = nullptr;
3985    napi_value result = nullptr;
3986    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
3987    napi_get_null(env, &result);
3988
3989    WebviewController *webviewController = nullptr;
3990    napi_unwrap(env, thisVar, (void **)&webviewController);
3991    if (!webviewController || !webviewController->IsInit()) {
3992        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
3993        return result;
3994    }
3995
3996    void *data = nullptr;
3997    napi_value buffer = nullptr;
3998    auto webState = webviewController->SerializeWebState();
3999
4000    NAPI_CALL(env, napi_create_arraybuffer(env, webState.size(), &data, &buffer));
4001    int retCode = memcpy_s(data, webState.size(), webState.data(), webState.size());
4002    if (retCode != 0) {
4003        return result;
4004    }
4005    NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, webState.size(), buffer, 0, &result));
4006    return result;
4007}
4008
4009napi_value NapiWebviewController::RestoreWebState(napi_env env, napi_callback_info info)
4010{
4011    napi_value thisVar = nullptr;
4012    napi_value result = nullptr;
4013    size_t argc = INTEGER_ONE;
4014    napi_value argv[INTEGER_ONE] = { 0 };
4015    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
4016    napi_get_null(env, &result);
4017
4018    WebviewController *webviewController = nullptr;
4019    napi_unwrap(env, thisVar, (void **)&webviewController);
4020    if (!webviewController || !webviewController->IsInit()) {
4021        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4022        return result;
4023    }
4024
4025    bool isTypedArray = false;
4026    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4027    if (argc != INTEGER_ONE) {
4028        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4029            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4030        return result;
4031    }
4032    NAPI_CALL(env, napi_is_typedarray(env, argv[0], &isTypedArray));
4033    if (!isTypedArray) {
4034        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4035            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "state", "uint8Array"));
4036        return result;
4037    }
4038
4039    napi_typedarray_type type;
4040    size_t length = 0;
4041    napi_value buffer = nullptr;
4042    size_t offset = 0;
4043    NAPI_CALL(env, napi_get_typedarray_info(env, argv[0], &type, &length, nullptr, &buffer, &offset));
4044    if (type != napi_uint8_array) {
4045        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4046            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "state", "uint8Array"));
4047        return result;
4048    }
4049    uint8_t *data = nullptr;
4050    size_t total = 0;
4051    NAPI_CALL(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total));
4052    length = std::min<size_t>(length, total - offset);
4053    std::vector<uint8_t> state(length);
4054    int retCode = memcpy_s(state.data(), state.size(), &data[offset], length);
4055    if (retCode != 0) {
4056        return result;
4057    }
4058    webviewController->RestoreWebState(state);
4059    return result;
4060}
4061
4062napi_value NapiWebviewController::ScrollPageDown(napi_env env, napi_callback_info info)
4063{
4064    napi_value thisVar = nullptr;
4065    napi_value result = nullptr;
4066    size_t argc = INTEGER_ONE;
4067    napi_value argv[INTEGER_ONE] = { 0 };
4068    bool bottom;
4069
4070    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4071    if (argc != INTEGER_ONE) {
4072        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4073            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4074        return result;
4075    }
4076
4077    if (!NapiParseUtils::ParseBoolean(env, argv[0], bottom)) {
4078        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4079            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "bottom", "booleane"));
4080        return result;
4081    }
4082
4083    WebviewController *webviewController = nullptr;
4084    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4085    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4086        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4087        return nullptr;
4088    }
4089    webviewController->ScrollPageDown(bottom);
4090    return result;
4091}
4092
4093napi_value NapiWebviewController::ScrollPageUp(napi_env env, napi_callback_info info)
4094{
4095    napi_value thisVar = nullptr;
4096    napi_value result = nullptr;
4097    size_t argc = INTEGER_ONE;
4098    napi_value argv[INTEGER_ONE] = { 0 };
4099    bool top;
4100
4101    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4102    if (argc != INTEGER_ONE) {
4103        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4104            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4105        return result;
4106    }
4107
4108    if (!NapiParseUtils::ParseBoolean(env, argv[0], top)) {
4109        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4110            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "top", "booleane"));
4111        return result;
4112    }
4113
4114    WebviewController *webviewController = nullptr;
4115    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4116    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4117        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4118        return nullptr;
4119    }
4120    webviewController->ScrollPageUp(top);
4121    return result;
4122}
4123
4124bool CheckSchemeName(const std::string& schemeName)
4125{
4126    if (schemeName.empty() || schemeName.size() > MAX_CUSTOM_SCHEME_NAME_LENGTH) {
4127        WVLOG_E("Invalid scheme name length");
4128        return false;
4129    }
4130    for (auto it = schemeName.begin(); it != schemeName.end(); it++) {
4131        char chr = *it;
4132        if (!((chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9') ||
4133            (chr == '.') || (chr == '+') || (chr == '-'))) {
4134            WVLOG_E("invalid character %{public}c", chr);
4135            return false;
4136        }
4137    }
4138    return true;
4139}
4140
4141void SetCustomizeSchemeOption(Scheme& scheme)
4142{
4143    std::map<int, std::function<bool(const Scheme&)>> schemeProperties = {
4144        {0, [](const Scheme& scheme) { return scheme.isStandard; }},
4145        {1, [](const Scheme& scheme) { return scheme.isLocal; }},
4146        {2, [](const Scheme& scheme) { return scheme.isDisplayIsolated; }},
4147        {3, [](const Scheme& scheme) { return scheme.isSecure; }},
4148        {4, [](const Scheme& scheme) { return scheme.isSupportCORS; }},
4149        {5, [](const Scheme& scheme) { return scheme.isCspBypassing; }},
4150        {6, [](const Scheme& scheme) { return scheme.isSupportFetch; }},
4151        {7, [](const Scheme& scheme) { return scheme.isCodeCacheSupported; }}
4152    };
4153
4154    for (const auto& property : schemeProperties) {
4155        if (property.second(scheme)) {
4156            scheme.option += 1 << property.first;
4157        }
4158    }
4159}
4160
4161bool SetCustomizeScheme(napi_env env, napi_value obj, Scheme& scheme)
4162{
4163    std::map<std::string, std::function<void(Scheme&, bool)>> schemeBooleanProperties = {
4164        {"isSupportCORS", [](Scheme& scheme, bool value) { scheme.isSupportCORS = value; }},
4165        {"isSupportFetch", [](Scheme& scheme, bool value) { scheme.isSupportFetch = value; }},
4166        {"isStandard", [](Scheme& scheme, bool value) { scheme.isStandard = value; }},
4167        {"isLocal", [](Scheme& scheme, bool value) { scheme.isLocal = value; }},
4168        {"isDisplayIsolated", [](Scheme& scheme, bool value) { scheme.isDisplayIsolated = value; }},
4169        {"isSecure", [](Scheme& scheme, bool value) { scheme.isSecure = value; }},
4170        {"isCspBypassing", [](Scheme& scheme, bool value) { scheme.isCspBypassing = value; }},
4171        {"isCodeCacheSupported", [](Scheme& scheme, bool value) { scheme.isCodeCacheSupported = value; }}
4172    };
4173
4174    for (const auto& property : schemeBooleanProperties) {
4175        napi_value propertyObj = nullptr;
4176        napi_get_named_property(env, obj, property.first.c_str(), &propertyObj);
4177        bool schemeProperty = false;
4178        if (!NapiParseUtils::ParseBoolean(env, propertyObj, schemeProperty)) {
4179            if (property.first == "isSupportCORS" || property.first == "isSupportFetch") {
4180                return false;
4181            }
4182        }
4183        property.second(scheme, schemeProperty);
4184    }
4185
4186    napi_value schemeNameObj = nullptr;
4187    if (napi_get_named_property(env, obj, "schemeName", &schemeNameObj) != napi_ok) {
4188        return false;
4189    }
4190    if (!NapiParseUtils::ParseString(env, schemeNameObj, scheme.name)) {
4191        return false;
4192    }
4193
4194    if (!CheckSchemeName(scheme.name)) {
4195        return false;
4196    }
4197
4198    SetCustomizeSchemeOption(scheme);
4199    return true;
4200}
4201
4202int32_t CustomizeSchemesArrayDataHandler(napi_env env, napi_value array)
4203{
4204    uint32_t arrayLength = 0;
4205    napi_get_array_length(env, array, &arrayLength);
4206    if (arrayLength > MAX_CUSTOM_SCHEME_SIZE) {
4207        return PARAM_CHECK_ERROR;
4208    }
4209    std::vector<Scheme> schemeVector;
4210    for (uint32_t i = 0; i < arrayLength; ++i) {
4211        napi_value obj = nullptr;
4212        napi_get_element(env, array, i, &obj);
4213        Scheme scheme;
4214        bool result = SetCustomizeScheme(env, obj, scheme);
4215        if (!result) {
4216            return PARAM_CHECK_ERROR;
4217        }
4218        schemeVector.push_back(scheme);
4219    }
4220    int32_t registerResult;
4221    for (auto it = schemeVector.begin(); it != schemeVector.end(); ++it) {
4222        registerResult = OH_ArkWeb_RegisterCustomSchemes(it->name.c_str(), it->option);
4223        if (registerResult != NO_ERROR) {
4224            return registerResult;
4225        }
4226    }
4227    return NO_ERROR;
4228}
4229
4230napi_value NapiWebviewController::CustomizeSchemes(napi_env env, napi_callback_info info)
4231{
4232    if (WebviewController::existNweb_) {
4233        WVLOG_E("There exist web component which has been already created.");
4234    }
4235
4236    napi_value result = nullptr;
4237    napi_value thisVar = nullptr;
4238    size_t argc = INTEGER_ONE;
4239    napi_value argv[INTEGER_ONE];
4240    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4241    if (argc != INTEGER_ONE) {
4242        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4243            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4244        return nullptr;
4245    }
4246    napi_value array = argv[INTEGER_ZERO];
4247    bool isArray = false;
4248    napi_is_array(env, array, &isArray);
4249    if (!isArray) {
4250        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4251            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "schemes", "array"));
4252        return nullptr;
4253    }
4254    int32_t registerResult = CustomizeSchemesArrayDataHandler(env, array);
4255    if (registerResult == NO_ERROR) {
4256        NAPI_CALL(env, napi_get_undefined(env, &result));
4257        return result;
4258    }
4259    if (registerResult == PARAM_CHECK_ERROR) {
4260        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4261            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "schemeName", "string"));
4262        return nullptr;
4263    }
4264    BusinessError::ThrowErrorByErrcode(env, REGISTER_CUSTOM_SCHEME_FAILED);
4265    return nullptr;
4266}
4267
4268napi_value NapiWebviewController::ScrollTo(napi_env env, napi_callback_info info)
4269{
4270    napi_value thisVar = nullptr;
4271    napi_value result = nullptr;
4272    size_t argc = INTEGER_THREE;
4273    napi_value argv[INTEGER_THREE] = { 0 };
4274    float x;
4275    float y;
4276    int32_t duration;
4277
4278    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4279    if (argc != INTEGER_TWO && argc != INTEGER_THREE) {
4280        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4281            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "two", "three"));
4282        return result;
4283    }
4284
4285    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], x)) {
4286        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4287            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "x", "number"));
4288        return result;
4289    }
4290
4291    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], y)) {
4292        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4293            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "y", "number"));
4294        return result;
4295    }
4296
4297    if (argc == INTEGER_THREE) {
4298        if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_TWO], duration)) {
4299            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4300                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "duration", "number"));
4301            return result;
4302        }
4303    }
4304
4305    WebviewController *webviewController = nullptr;
4306    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4307    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4308        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4309        return nullptr;
4310    }
4311    if (argc == INTEGER_THREE) {
4312        webviewController->ScrollToWithAnime(x, y, duration);
4313    } else {
4314        webviewController->ScrollTo(x, y);
4315    }
4316    return result;
4317}
4318
4319napi_value NapiWebviewController::ScrollBy(napi_env env, napi_callback_info info)
4320{
4321    napi_value thisVar = nullptr;
4322    napi_value result = nullptr;
4323    size_t argc = INTEGER_THREE;
4324    napi_value argv[INTEGER_THREE] = { 0 };
4325    float deltaX;
4326    float deltaY;
4327    int32_t duration = 0;
4328
4329    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4330    if (argc != INTEGER_TWO && argc != INTEGER_THREE) {
4331        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4332            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "two", "three"));
4333        return result;
4334    }
4335
4336    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], deltaX)) {
4337        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4338            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "deltaX", "number"));
4339        return result;
4340    }
4341
4342    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], deltaY)) {
4343        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4344            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "deltaY", "number"));
4345        return result;
4346    }
4347
4348    if (argc == INTEGER_THREE) {
4349        if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_TWO], duration)) {
4350            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4351                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "duration", "number"));
4352            return result;
4353        }
4354    }
4355
4356    WebviewController *webviewController = nullptr;
4357    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4358    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4359        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4360        return nullptr;
4361    }
4362    if (argc == INTEGER_THREE) {
4363        webviewController->ScrollByWithAnime(deltaX, deltaY, duration);
4364    } else {
4365        webviewController->ScrollBy(deltaX, deltaY);
4366    }
4367    return result;
4368}
4369
4370napi_value NapiWebviewController::SlideScroll(napi_env env, napi_callback_info info)
4371{
4372    napi_value thisVar = nullptr;
4373    napi_value result = nullptr;
4374    size_t argc = INTEGER_TWO;
4375    napi_value argv[INTEGER_TWO] = { 0 };
4376    float vx;
4377    float vy;
4378
4379    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4380    if (argc != INTEGER_TWO) {
4381        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4382            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "two"));
4383        return result;
4384    }
4385
4386    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], vx)) {
4387        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4388            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "vx", "number"));
4389        return result;
4390    }
4391
4392    if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], vy)) {
4393        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4394            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "vy", "number"));
4395        return result;
4396    }
4397
4398    WebviewController *webviewController = nullptr;
4399    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4400    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4401        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4402        return nullptr;
4403    }
4404    webviewController->SlideScroll(vx, vy);
4405    return result;
4406}
4407
4408napi_value NapiWebviewController::SetScrollable(napi_env env, napi_callback_info info)
4409{
4410    napi_value thisVar = nullptr;
4411    napi_value result = nullptr;
4412    size_t argc = INTEGER_TWO;
4413    size_t argcForOld = INTEGER_ONE;
4414    napi_value argv[INTEGER_TWO] = { 0 };
4415
4416    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4417    if (argc != INTEGER_TWO && argc != argcForOld) {
4418        NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
4419            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_TWO, "one", "two"));
4420        return result;
4421    }
4422    bool isEnableScroll;
4423    if (!NapiParseUtils::ParseBoolean(env, argv[0], isEnableScroll)) {
4424        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4425            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "enable", "boolean"));
4426        return result;
4427    }
4428
4429    int32_t scrollType = -1;
4430    if (argc == INTEGER_TWO) {
4431        if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ONE], scrollType) || scrollType < 0 ||
4432            scrollType >= INTEGER_ONE) {
4433            WVLOG_E("BusinessError: 401. The character of 'scrollType' must be int32.");
4434            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4435            return result;
4436        }
4437    }
4438
4439    WebviewController* webviewController = nullptr;
4440    napi_status status = napi_unwrap(env, thisVar, (void**)&webviewController);
4441    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4442        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4443        return nullptr;
4444    }
4445    webviewController->SetScrollable(isEnableScroll, scrollType);
4446    return result;
4447}
4448
4449napi_value NapiWebviewController::GetScrollable(napi_env env, napi_callback_info info)
4450{
4451    napi_value result = nullptr;
4452    WebviewController *webviewController = GetWebviewController(env, info);
4453    if (!webviewController) {
4454        return nullptr;
4455    }
4456
4457    bool isScrollable = webviewController->GetScrollable();
4458    NAPI_CALL(env, napi_get_boolean(env, isScrollable, &result));
4459    return result;
4460}
4461
4462napi_value NapiWebviewController::InnerGetCertificate(napi_env env, napi_callback_info info)
4463{
4464    napi_value thisVar = nullptr;
4465    napi_value result = nullptr;
4466    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
4467    napi_create_array(env, &result);
4468
4469    WebviewController *webviewController = nullptr;
4470    napi_unwrap(env, thisVar, (void **)&webviewController);
4471    if (!webviewController || !webviewController->IsInit()) {
4472        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4473        return result;
4474    }
4475
4476    std::vector<std::string> certChainDerData;
4477    bool ans = webviewController->GetCertChainDerData(certChainDerData);
4478    if (!ans) {
4479        WVLOG_E("get cert chain data failed");
4480        return result;
4481    }
4482
4483    for (uint8_t i = 0; i < certChainDerData.size(); i++) {
4484        if (i == UINT8_MAX) {
4485            WVLOG_E("error, cert chain data array reach max");
4486            break;
4487        }
4488        void *data = nullptr;
4489        napi_value buffer = nullptr;
4490        napi_value item = nullptr;
4491        NAPI_CALL(env, napi_create_arraybuffer(env, certChainDerData[i].size(), &data, &buffer));
4492        int retCode = memcpy_s(data, certChainDerData[i].size(),
4493                               certChainDerData[i].data(), certChainDerData[i].size());
4494        if (retCode != 0) {
4495            WVLOG_E("memcpy_s cert data failed, index = %{public}u,", i);
4496            continue;
4497        }
4498        NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, certChainDerData[i].size(), buffer, 0, &item));
4499        NAPI_CALL(env, napi_set_element(env, result, i, item));
4500    }
4501    return result;
4502}
4503
4504napi_value NapiWebviewController::SetAudioMuted(napi_env env, napi_callback_info info)
4505{
4506    WVLOG_D("SetAudioMuted invoked");
4507
4508    napi_value result = nullptr;
4509    NAPI_CALL(env, napi_get_undefined(env, &result));
4510
4511    napi_value thisVar = nullptr;
4512    size_t argc = INTEGER_ONE;
4513    napi_value argv[INTEGER_ONE] = { 0 };
4514    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4515    if (argc != INTEGER_ONE) {
4516        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4517            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4518        return result;
4519    }
4520
4521    bool muted = false;
4522    if (!NapiParseUtils::ParseBoolean(env, argv[0], muted)) {
4523        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4524            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "mute", "boolean"));
4525        return result;
4526    }
4527
4528    WebviewController* webviewController = nullptr;
4529    napi_status status = napi_unwrap(env, thisVar, (void**)&webviewController);
4530    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4531        WVLOG_E("SetAudioMuted failed due to no associated Web component");
4532        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4533        return result;
4534    }
4535
4536    ErrCode ret = webviewController->SetAudioMuted(muted);
4537    if (ret != NO_ERROR) {
4538        WVLOG_E("SetAudioMuted failed, error code: %{public}d", ret);
4539        BusinessError::ThrowErrorByErrcode(env, ret);
4540        return result;
4541    }
4542
4543    WVLOG_I("SetAudioMuted: %{public}s", (muted ? "true" : "false"));
4544    return result;
4545}
4546
4547napi_value NapiWebviewController::PrefetchPage(napi_env env, napi_callback_info info)
4548{
4549    napi_value thisVar = nullptr;
4550    napi_value result = nullptr;
4551    size_t argc = INTEGER_TWO;
4552    napi_value argv[INTEGER_TWO];
4553    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4554    WebviewController *webviewController = nullptr;
4555    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4556    if ((argc != INTEGER_ONE) && (argc != INTEGER_TWO)) {
4557        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4558        return nullptr;
4559    }
4560    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4561        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4562        return nullptr;
4563    }
4564    std::string url;
4565    if (!ParsePrepareUrl(env, argv[INTEGER_ZERO], url)) {
4566        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
4567        return nullptr;
4568    }
4569    std::map<std::string, std::string> additionalHttpHeaders;
4570    if (argc == INTEGER_ONE) {
4571        ErrCode ret = webviewController->PrefetchPage(url, additionalHttpHeaders);
4572        if (ret != NO_ERROR) {
4573            WVLOG_E("PrefetchPage failed, error code: %{public}d", ret);
4574            BusinessError::ThrowErrorByErrcode(env, ret);
4575            return nullptr;
4576        }
4577        NAPI_CALL(env, napi_get_undefined(env, &result));
4578        return result;
4579    }
4580    return PrefetchPageWithHttpHeaders(env, info, url, argv, webviewController);
4581}
4582
4583napi_value NapiWebviewController::PrefetchPageWithHttpHeaders(napi_env env, napi_callback_info info, std::string& url,
4584    const napi_value* argv, WebviewController* webviewController)
4585{
4586    napi_value result = nullptr;
4587    std::map<std::string, std::string> additionalHttpHeaders;
4588    napi_value array = argv[INTEGER_ONE];
4589    bool isArray = false;
4590    napi_is_array(env, array, &isArray);
4591    if (isArray) {
4592        uint32_t arrayLength = INTEGER_ZERO;
4593        napi_get_array_length(env, array, &arrayLength);
4594        for (uint32_t i = 0; i < arrayLength; ++i) {
4595            std::string key;
4596            std::string value;
4597            napi_value obj = nullptr;
4598            napi_value keyObj = nullptr;
4599            napi_value valueObj = nullptr;
4600            napi_get_element(env, array, i, &obj);
4601            if (napi_get_named_property(env, obj, "headerKey", &keyObj) != napi_ok) {
4602                continue;
4603            }
4604            if (napi_get_named_property(env, obj, "headerValue", &valueObj) != napi_ok) {
4605                continue;
4606            }
4607            NapiParseUtils::ParseString(env, keyObj, key);
4608            NapiParseUtils::ParseString(env, valueObj, value);
4609            additionalHttpHeaders[key] = value;
4610        }
4611    } else {
4612        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4613        return nullptr;
4614    }
4615
4616    ErrCode ret = webviewController->PrefetchPage(url, additionalHttpHeaders);
4617    if (ret != NO_ERROR) {
4618        WVLOG_E("PrefetchPage failed, error code: %{public}d", ret);
4619        BusinessError::ThrowErrorByErrcode(env, ret);
4620        return nullptr;
4621    }
4622    NAPI_CALL(env, napi_get_undefined(env, &result));
4623    return result;
4624}
4625
4626napi_value NapiWebviewController::GetLastJavascriptProxyCallingFrameUrl(napi_env env, napi_callback_info info)
4627{
4628    napi_value result = nullptr;
4629    WebviewController *webviewController = GetWebviewController(env, info);
4630    if (!webviewController) {
4631        return nullptr;
4632    }
4633
4634    std::string lastCallingFrameUrl = webviewController->GetLastJavascriptProxyCallingFrameUrl();
4635    napi_create_string_utf8(env, lastCallingFrameUrl.c_str(), lastCallingFrameUrl.length(), &result);
4636    return result;
4637}
4638
4639napi_value NapiWebviewController::PrepareForPageLoad(napi_env env, napi_callback_info info)
4640{
4641    napi_value thisVar = nullptr;
4642    napi_value result = nullptr;
4643    size_t argc = INTEGER_THREE;
4644    napi_value argv[INTEGER_THREE] = { 0 };
4645    napi_get_undefined(env, &result);
4646    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4647    if (argc != INTEGER_THREE) {
4648        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4649        return nullptr;
4650    }
4651
4652    std::string url;
4653    if (!ParsePrepareUrl(env, argv[INTEGER_ZERO], url)) {
4654        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
4655        return nullptr;
4656    }
4657
4658    bool preconnectable = false;
4659    if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_ONE], preconnectable)) {
4660        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4661        return nullptr;
4662    }
4663
4664    int32_t numSockets = 0;
4665    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_TWO], numSockets)) {
4666        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4667        return nullptr;
4668    }
4669    if (numSockets <= 0 || static_cast<uint32_t>(numSockets) > SOCKET_MAXIMUM) {
4670        BusinessError::ThrowErrorByErrcode(env, INVALID_SOCKET_NUMBER);
4671        return nullptr;
4672    }
4673
4674    NWebHelper::Instance().PrepareForPageLoad(url, preconnectable, numSockets);
4675    NAPI_CALL(env, napi_get_undefined(env, &result));
4676    return result;
4677}
4678
4679napi_value NapiWebviewController::PrefetchResource(napi_env env, napi_callback_info info)
4680{
4681    napi_value thisVar = nullptr;
4682    napi_value result = nullptr;
4683    size_t argc = INTEGER_FOUR;
4684    napi_value argv[INTEGER_FOUR] = { 0 };
4685    napi_get_undefined(env, &result);
4686    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4687    if (argc > INTEGER_FOUR || argc < INTEGER_ONE) {
4688        WVLOG_E("BusinessError: 401. Arg count must between 1 and 4.");
4689        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4690        return nullptr;
4691    }
4692
4693    std::shared_ptr<NWebEnginePrefetchArgs> prefetchArgs = ParsePrefetchArgs(env, argv[INTEGER_ZERO]);
4694    if (prefetchArgs == nullptr) {
4695        return nullptr;
4696    }
4697
4698    std::map<std::string, std::string> additionalHttpHeaders;
4699    if (argc >= INTEGER_TWO && !ParseHttpHeaders(env, argv[INTEGER_ONE], &additionalHttpHeaders)) {
4700        WVLOG_E("BusinessError: 401. The type of 'additionalHttpHeaders' must be Array of 'WebHeader'.");
4701        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4702        return nullptr;
4703    }
4704
4705    std::string cacheKey;
4706    if ((argc >= INTEGER_THREE) && !NapiParseUtils::ParseString(env, argv[INTEGER_TWO], cacheKey)) {
4707        WVLOG_E("BusinessError: 401.The type of 'cacheKey' must be string.");
4708        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4709        return nullptr;
4710    }
4711
4712    if (cacheKey.empty()) {
4713        cacheKey = prefetchArgs->GetUrl();
4714    } else {
4715        if (!CheckCacheKey(env, cacheKey)) {
4716            return nullptr;
4717        }
4718    }
4719
4720    int32_t cacheValidTime = 0;
4721    if (argc >= INTEGER_FOUR) {
4722        if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_THREE], cacheValidTime) || cacheValidTime <= 0 ||
4723            cacheValidTime > INT_MAX) {
4724            WVLOG_E("BusinessError: 401. The character of 'cacheValidTime' must be int32.");
4725            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4726            return nullptr;
4727        }
4728    }
4729
4730    NAPI_CALL(env, napi_get_undefined(env, &result));
4731    NWebHelper::Instance().PrefetchResource(prefetchArgs, additionalHttpHeaders, cacheKey, cacheValidTime);
4732    return result;
4733}
4734
4735napi_value NapiWebviewController::ClearPrefetchedResource(napi_env env, napi_callback_info info)
4736{
4737    napi_value thisVar = nullptr;
4738    napi_value result = nullptr;
4739    size_t argc = INTEGER_ONE;
4740    napi_value argv[INTEGER_ONE] = { 0 };
4741    napi_get_undefined(env, &result);
4742    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4743    if (argc != INTEGER_ONE) {
4744        WVLOG_E("BusinessError: 401. Arg count must be 1.");
4745        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4746        return nullptr;
4747    }
4748
4749    std::vector<std::string> cacheKeyList;
4750    if (!ParseCacheKeyList(env, argv[INTEGER_ZERO], &cacheKeyList)) {
4751        WVLOG_E("BusinessError: 401. The type of 'cacheKeyList' must be Array of string.");
4752        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4753        return nullptr;
4754    }
4755
4756    NAPI_CALL(env, napi_get_undefined(env, &result));
4757    NWebHelper::Instance().ClearPrefetchedResource(cacheKeyList);
4758    return result;
4759}
4760
4761napi_value NapiWebviewController::SetDownloadDelegate(napi_env env, napi_callback_info info)
4762{
4763    WVLOG_D("WebDownloader::JS_SetDownloadDelegate");
4764    NWebHelper::Instance().LoadNWebSDK();
4765    size_t argc = 1;
4766    napi_value argv[1] = {0};
4767    napi_value thisVar = nullptr;
4768    void* data = nullptr;
4769    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
4770
4771    WebDownloadDelegate* delegate = nullptr;
4772    napi_value obj = argv[0];
4773    napi_unwrap(env, obj, (void**)&delegate);
4774    if (!delegate) {
4775        WVLOG_E("[DOWNLOAD] WebDownloader::JS_SetDownloadDelegate delegate is null");
4776        (void)RemoveDownloadDelegateRef(env, thisVar);
4777        return nullptr;
4778    }
4779    napi_create_reference(env, obj, 1, &delegate->delegate_);
4780
4781    WebviewController *webviewController = nullptr;
4782    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
4783    if (webviewController == nullptr || !webviewController->IsInit()) {
4784        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4785        WVLOG_E("create message port failed, napi unwrap webviewController failed");
4786        return nullptr;
4787    }
4788    int32_t nwebId = webviewController->GetWebId();
4789    WebDownloadManager::AddDownloadDelegateForWeb(nwebId, delegate);
4790    return nullptr;
4791}
4792
4793napi_value NapiWebviewController::StartDownload(napi_env env, napi_callback_info info)
4794{
4795    WVLOG_D("[DOWNLOAD] NapiWebviewController::StartDownload");
4796    size_t argc = 1;
4797    napi_value argv[1] = {0};
4798    napi_value thisVar = nullptr;
4799    void* data = nullptr;
4800    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
4801
4802    WebviewController *webviewController = nullptr;
4803    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
4804    if (webviewController == nullptr || !webviewController->IsInit()) {
4805        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4806        WVLOG_E("create message port failed, napi unwrap webviewController failed");
4807        return nullptr;
4808    }
4809
4810    std::string url;
4811    if (!ParsePrepareUrl(env, argv[INTEGER_ZERO], url)) {
4812        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
4813        return nullptr;
4814    }
4815    int32_t nwebId = webviewController->GetWebId();
4816    NWebHelper::Instance().LoadNWebSDK();
4817    WebDownloader_StartDownload(nwebId, url.c_str());
4818    return nullptr;
4819}
4820
4821napi_value NapiWebviewController::CloseAllMediaPresentations(napi_env env, napi_callback_info info)
4822{
4823    napi_value result = nullptr;
4824    WebviewController* webviewController = GetWebviewController(env, info);
4825    if (!webviewController) {
4826        return result;
4827    }
4828
4829    webviewController->CloseAllMediaPresentations();
4830    NAPI_CALL(env, napi_get_undefined(env, &result));
4831    return result;
4832}
4833
4834napi_value NapiWebviewController::StopAllMedia(napi_env env, napi_callback_info info)
4835{
4836    napi_value result = nullptr;
4837    WebviewController* webviewController = GetWebviewController(env, info);
4838    if (!webviewController) {
4839        return result;
4840    }
4841
4842    webviewController->StopAllMedia();
4843    NAPI_CALL(env, napi_get_undefined(env, &result));
4844    return result;
4845}
4846
4847napi_value NapiWebviewController::ResumeAllMedia(napi_env env, napi_callback_info info)
4848{
4849    napi_value result = nullptr;
4850    WebviewController* webviewController = GetWebviewController(env, info);
4851    if (!webviewController) {
4852        return result;
4853    }
4854
4855    webviewController->ResumeAllMedia();
4856    NAPI_CALL(env, napi_get_undefined(env, &result));
4857    return result;
4858}
4859
4860napi_value NapiWebviewController::PauseAllMedia(napi_env env, napi_callback_info info)
4861{
4862    napi_value result = nullptr;
4863    WebviewController* webviewController = GetWebviewController(env, info);
4864    if (!webviewController) {
4865        return result;
4866    }
4867
4868    webviewController->PauseAllMedia();
4869    NAPI_CALL(env, napi_get_undefined(env, &result));
4870    return result;
4871}
4872
4873napi_value NapiWebviewController::GetMediaPlaybackState(napi_env env, napi_callback_info info)
4874{
4875    napi_value result = nullptr;
4876    WebviewController* webviewController = GetWebviewController(env, info);
4877    if (!webviewController) {
4878        return result;
4879    }
4880
4881    int32_t mediaPlaybackState = webviewController->GetMediaPlaybackState();
4882    napi_create_int32(env, mediaPlaybackState, &result);
4883    return result;
4884}
4885
4886napi_value NapiWebviewController::SetConnectionTimeout(napi_env env, napi_callback_info info)
4887{
4888    napi_value result = nullptr;
4889    size_t argc = INTEGER_ONE;
4890    napi_value argv[INTEGER_ONE] = { nullptr };
4891    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
4892    if (argc != INTEGER_ONE) {
4893        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4894                NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4895        return result;
4896    }
4897
4898    int32_t timeout = 0;
4899    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], timeout) || (timeout <= 0)) {
4900        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4901                "BusinessError: 401. Parameter error. The type of 'timeout' must be int and must be positive integer.");
4902        return result;
4903    }
4904
4905    NWebHelper::Instance().SetConnectionTimeout(timeout);
4906    NAPI_CALL(env, napi_get_undefined(env, &result));
4907    return result;
4908}
4909
4910napi_value NapiWebviewController::CreateWebPrintDocumentAdapter(napi_env env, napi_callback_info info)
4911{
4912    WVLOG_I("Create web print document adapter.");
4913    napi_value thisVar = nullptr;
4914    napi_value result = nullptr;
4915    size_t argc = INTEGER_ONE;
4916    napi_value argv[INTEGER_ONE];
4917    NAPI_CALL(env, napi_get_undefined(env, &result));
4918    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
4919    if (argc != INTEGER_ONE) {
4920        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4921            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
4922        return result;
4923    }
4924    std::string jobName;
4925    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], jobName)) {
4926        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
4927            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "jopName", "string"));
4928        return result;
4929    }
4930    WebviewController *webviewController = nullptr;
4931    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
4932    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
4933        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
4934        return result;
4935    }
4936    void* webPrintDocument = webviewController->CreateWebPrintDocumentAdapter(jobName);
4937    if (!webPrintDocument) {
4938        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4939        return result;
4940    }
4941    napi_handle_scope scope = nullptr;
4942    napi_open_handle_scope(env, &scope);
4943    if (scope == nullptr) {
4944        return result;
4945    }
4946    napi_value webPrintDoc = nullptr;
4947    NAPI_CALL(env, napi_get_reference_value(env, g_webPrintDocClassRef, &webPrintDoc));
4948    napi_value consParam[INTEGER_ONE] = {0};
4949    NAPI_CALL(env, napi_create_bigint_uint64(env, reinterpret_cast<uint64_t>(webPrintDocument),
4950                                             &consParam[INTEGER_ZERO]));
4951    napi_value proxy = nullptr;
4952    status = napi_new_instance(env, webPrintDoc, INTEGER_ONE, &consParam[INTEGER_ZERO], &proxy);
4953    if (status!= napi_ok) {
4954        napi_close_handle_scope(env, scope);
4955        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
4956        return result;
4957    }
4958    napi_close_handle_scope(env, scope);
4959    return proxy;
4960}
4961
4962napi_value NapiWebviewController::GetSecurityLevel(napi_env env, napi_callback_info info)
4963{
4964    napi_value result = nullptr;
4965    WebviewController *webviewController = GetWebviewController(env, info);
4966    if (!webviewController) {
4967        return result;
4968    }
4969
4970    int32_t securityLevel = webviewController->GetSecurityLevel();
4971    napi_create_int32(env, securityLevel, &result);
4972    return result;
4973}
4974
4975void ParsePrintRangeAdapter(napi_env env, napi_value pageRange, PrintAttributesAdapter& printAttr)
4976{
4977    if (!pageRange) {
4978        WVLOG_E("ParsePrintRangeAdapter failed.");
4979        return;
4980    }
4981    napi_value startPage = nullptr;
4982    napi_value endPage = nullptr;
4983    napi_value pages = nullptr;
4984    napi_get_named_property(env, pageRange, "startPage", &startPage);
4985    napi_get_named_property(env, pageRange, "endPage", &endPage);
4986    if (startPage) {
4987        NapiParseUtils::ParseUint32(env, startPage, printAttr.pageRange.startPage);
4988    }
4989    if (endPage) {
4990        NapiParseUtils::ParseUint32(env, endPage, printAttr.pageRange.endPage);
4991    }
4992    napi_get_named_property(env, pageRange, "pages", &pages);
4993    uint32_t pageArrayLength = 0;
4994    napi_get_array_length(env, pages, &pageArrayLength);
4995    for (uint32_t i = 0; i < pageArrayLength; ++i) {
4996        napi_value pagesNumObj = nullptr;
4997        napi_get_element(env, pages, i, &pagesNumObj);
4998        uint32_t pagesNum;
4999        NapiParseUtils::ParseUint32(env, pagesNumObj, pagesNum);
5000        printAttr.pageRange.pages.push_back(pagesNum);
5001    }
5002}
5003
5004void ParsePrintPageSizeAdapter(napi_env env, napi_value pageSize, PrintAttributesAdapter& printAttr)
5005{
5006    if (!pageSize) {
5007        WVLOG_E("ParsePrintPageSizeAdapter failed.");
5008        return;
5009    }
5010    napi_value id = nullptr;
5011    napi_value name = nullptr;
5012    napi_value width = nullptr;
5013    napi_value height = nullptr;
5014    napi_get_named_property(env, pageSize, "id", &id);
5015    napi_get_named_property(env, pageSize, "name", &name);
5016    napi_get_named_property(env, pageSize, "width", &width);
5017    napi_get_named_property(env, pageSize, "height", &height);
5018    if (width) {
5019        NapiParseUtils::ParseUint32(env, width, printAttr.pageSize.width);
5020    }
5021    if (height) {
5022        NapiParseUtils::ParseUint32(env, height, printAttr.pageSize.height);
5023    }
5024}
5025
5026void ParsePrintMarginAdapter(napi_env env, napi_value margin, PrintAttributesAdapter& printAttr)
5027{
5028    if (!margin) {
5029        WVLOG_E("ParsePrintMarginAdapter failed.");
5030        return;
5031    }
5032    napi_value top = nullptr;
5033    napi_value bottom = nullptr;
5034    napi_value left = nullptr;
5035    napi_value right = nullptr;
5036    napi_get_named_property(env, margin, "top", &top);
5037    napi_get_named_property(env, margin, "bottom", &bottom);
5038    napi_get_named_property(env, margin, "left", &left);
5039    napi_get_named_property(env, margin, "right", &right);
5040    if (top) {
5041        NapiParseUtils::ParseUint32(env, top, printAttr.margin.top);
5042    }
5043    if (bottom) {
5044        NapiParseUtils::ParseUint32(env, bottom, printAttr.margin.bottom);
5045    }
5046    if (left) {
5047        NapiParseUtils::ParseUint32(env, left, printAttr.margin.left);
5048    }
5049    if (right) {
5050        NapiParseUtils::ParseUint32(env, right, printAttr.margin.right);
5051    }
5052}
5053
5054WebPrintWriteResultCallback ParseWebPrintWriteResultCallback(napi_env env, napi_value argv)
5055{
5056    if (!argv) {
5057        WVLOG_E("ParseWebPrintWriteResultCallback failed.");
5058        return nullptr;
5059    }
5060    napi_ref jsCallback = nullptr;
5061    napi_create_reference(env, argv, 1, &jsCallback);
5062    if (jsCallback) {
5063        WebPrintWriteResultCallback callbackImpl =
5064            [env, jCallback = std::move(jsCallback)](std::string jobId, uint32_t state) {
5065            if (!env) {
5066                return;
5067            }
5068            napi_handle_scope scope = nullptr;
5069            napi_open_handle_scope(env, &scope);
5070            if (scope == nullptr) {
5071                return;
5072            }
5073            napi_value setResult[INTEGER_TWO] = {0};
5074            napi_create_string_utf8(env, jobId.c_str(), NAPI_AUTO_LENGTH, &setResult[INTEGER_ZERO]);
5075            napi_create_uint32(env, state, &setResult[INTEGER_ONE]);
5076            napi_value args[INTEGER_TWO] = {setResult[INTEGER_ZERO], setResult[INTEGER_ONE]};
5077            napi_value callback = nullptr;
5078            napi_get_reference_value(env, jCallback, &callback);
5079            napi_value callbackResult = nullptr;
5080            napi_call_function(env, nullptr, callback, INTEGER_TWO, args, &callbackResult);
5081            napi_delete_reference(env, jCallback);
5082            napi_close_handle_scope(env, scope);
5083        };
5084        return callbackImpl;
5085    }
5086    return nullptr;
5087}
5088
5089bool ParseWebPrintAttrParams(napi_env env, napi_value obj, PrintAttributesAdapter& printAttr)
5090{
5091    if (!obj) {
5092        WVLOG_E("ParseWebPrintAttrParams failed.");
5093        return false;
5094    }
5095    napi_value copyNumber = nullptr;
5096    napi_value pageRange = nullptr;
5097    napi_value isSequential = nullptr;
5098    napi_value pageSize = nullptr;
5099    napi_value isLandscape = nullptr;
5100    napi_value colorMode = nullptr;
5101    napi_value duplexMode = nullptr;
5102    napi_value margin = nullptr;
5103    napi_value option = nullptr;
5104    napi_get_named_property(env, obj, "copyNumber", &copyNumber);
5105    napi_get_named_property(env, obj, "pageRange", &pageRange);
5106    napi_get_named_property(env, obj, "isSequential", &isSequential);
5107    napi_get_named_property(env, obj, "pageSize", &pageSize);
5108    napi_get_named_property(env, obj, "isLandscape", &isLandscape);
5109    napi_get_named_property(env, obj, "colorMode", &colorMode);
5110    napi_get_named_property(env, obj, "duplexMode", &duplexMode);
5111    napi_get_named_property(env, obj, "margin", &margin);
5112    napi_get_named_property(env, obj, "option", &option);
5113    if (copyNumber) {
5114        NapiParseUtils::ParseUint32(env, copyNumber, printAttr.copyNumber);
5115    }
5116    if (isSequential) {
5117        NapiParseUtils::ParseBoolean(env, isSequential, printAttr.isSequential);
5118    }
5119    if (isLandscape) {
5120        NapiParseUtils::ParseBoolean(env, isLandscape,  printAttr.isLandscape);
5121    }
5122    if (colorMode) {
5123        NapiParseUtils::ParseUint32(env, colorMode, printAttr.colorMode);
5124    }
5125    if (duplexMode) {
5126        NapiParseUtils::ParseUint32(env, duplexMode, printAttr.duplexMode);
5127    }
5128    if (option) {
5129        NapiParseUtils::ParseString(env, option, printAttr.option);
5130    }
5131    ParsePrintRangeAdapter(env, pageRange, printAttr);
5132    ParsePrintPageSizeAdapter(env, pageSize, printAttr);
5133    ParsePrintMarginAdapter(env, margin, printAttr);
5134    return true;
5135}
5136
5137napi_value NapiWebPrintDocument::OnStartLayoutWrite(napi_env env, napi_callback_info info)
5138{
5139    WVLOG_I("On Start Layout Write.");
5140    napi_value thisVar = nullptr;
5141    napi_value result = nullptr;
5142    size_t argc = INTEGER_FIVE;
5143    napi_value argv[INTEGER_FIVE] = { 0 };
5144    WebPrintDocument *webPrintDocument = nullptr;
5145
5146    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
5147    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webPrintDocument));
5148    if (webPrintDocument == nullptr) {
5149        WVLOG_E("unwrap webPrintDocument failed.");
5150        return result;
5151    }
5152
5153    std::string jobId;
5154    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], jobId)) {
5155        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5156        return result;
5157    }
5158
5159    int32_t fd;
5160    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_THREE], fd)) {
5161        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5162        return result;
5163    }
5164    PrintAttributesAdapter oldPrintAttr;
5165    PrintAttributesAdapter newPrintAttr;
5166    bool ret = false;
5167    ret = ParseWebPrintAttrParams(env, argv[INTEGER_ONE], oldPrintAttr);
5168    if (!ret) {
5169        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5170        return result;
5171    }
5172    ret = ParseWebPrintAttrParams(env, argv[INTEGER_TWO], newPrintAttr);
5173    if (!ret) {
5174        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5175        return result;
5176    }
5177    WebPrintWriteResultCallback writeResultCallback = nullptr;
5178    writeResultCallback = ParseWebPrintWriteResultCallback(env, argv[INTEGER_FOUR]);
5179    webPrintDocument->OnStartLayoutWrite(jobId, oldPrintAttr, newPrintAttr, fd, writeResultCallback);
5180    return result;
5181}
5182
5183napi_value NapiWebPrintDocument::OnJobStateChanged(napi_env env, napi_callback_info info)
5184{
5185    WVLOG_I("On Job State Changed.");
5186    napi_value thisVar = nullptr;
5187    napi_value result = nullptr;
5188    size_t argc = INTEGER_TWO;
5189    napi_value argv[INTEGER_TWO];
5190    NAPI_CALL(env, napi_get_undefined(env, &result));
5191
5192    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5193    WebPrintDocument *webPrintDocument = nullptr;
5194    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webPrintDocument));
5195    if (webPrintDocument == nullptr) {
5196        WVLOG_E("unwrap webPrintDocument failed.");
5197        return result;
5198    }
5199    if (argc != INTEGER_TWO) {
5200        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5201        return result;
5202    }
5203
5204    std::string jobId;
5205    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], jobId)) {
5206        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5207        return result;
5208    }
5209
5210    int32_t state;
5211    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ONE], state)) {
5212        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5213        return result;
5214    }
5215    webPrintDocument->OnJobStateChanged(jobId, state);
5216    return result;
5217}
5218
5219napi_value NapiWebPrintDocument::JsConstructor(napi_env env, napi_callback_info info)
5220{
5221    napi_value thisVar = nullptr;
5222    size_t argc = INTEGER_ONE;
5223    napi_value argv[INTEGER_ONE];
5224    uint64_t addrWebPrintDoc = 0;
5225    bool loseLess = true;
5226    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5227
5228    if (!NapiParseUtils::ParseUint64(env, argv[INTEGER_ZERO], addrWebPrintDoc, &loseLess)) {
5229        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5230        return nullptr;
5231    }
5232    void *webPrintDocPtr = reinterpret_cast<void *>(addrWebPrintDoc);
5233    WebPrintDocument *webPrintDoc = new (std::nothrow) WebPrintDocument(webPrintDocPtr);
5234    if (webPrintDoc == nullptr) {
5235        WVLOG_E("new web print failed");
5236        return nullptr;
5237    }
5238    NAPI_CALL(env, napi_wrap(env, thisVar, webPrintDoc,
5239        [](napi_env env, void *data, void *hint) {
5240            WebPrintDocument *webPrintDocument = static_cast<WebPrintDocument *>(data);
5241            delete webPrintDocument;
5242        },
5243        nullptr, nullptr));
5244    return thisVar;
5245}
5246
5247napi_value NapiWebviewController::SetPrintBackground(napi_env env, napi_callback_info info)
5248{
5249    napi_value result = nullptr;
5250    napi_value thisVar = nullptr;
5251    size_t argc = INTEGER_ONE;
5252    napi_value argv[INTEGER_ONE] = { 0 };
5253
5254    NAPI_CALL(env, napi_get_undefined(env, &result));
5255    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5256    if (argc != INTEGER_ONE) {
5257        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5258            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
5259        return result;
5260    }
5261
5262    bool printBackgroundEnabled = false;
5263    if (!NapiParseUtils::ParseBoolean(env, argv[0], printBackgroundEnabled)) {
5264        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5265            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "enable", "boolean"));
5266        return result;
5267    }
5268
5269    WebviewController *webviewController = GetWebviewController(env, info);
5270    if (!webviewController) {
5271        return result;
5272    }
5273    webviewController->SetPrintBackground(printBackgroundEnabled);
5274    return result;
5275}
5276
5277napi_value NapiWebviewController::GetPrintBackground(napi_env env, napi_callback_info info)
5278{
5279    napi_value result = nullptr;
5280    WebviewController *webviewController = GetWebviewController(env, info);
5281
5282    if (!webviewController) {
5283        return result;
5284    }
5285
5286    bool printBackgroundEnabled = webviewController->GetPrintBackground();
5287    NAPI_CALL(env, napi_get_boolean(env, printBackgroundEnabled, &result));
5288    return result;
5289}
5290
5291napi_value NapiWebviewController::SetWebSchemeHandler(napi_env env, napi_callback_info info)
5292{
5293    size_t argc = 2;
5294    napi_value argv[2] = {0};
5295    napi_value thisVar = nullptr;
5296    void* data = nullptr;
5297    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
5298
5299    WebviewController *webviewController = nullptr;
5300    NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
5301    if (webviewController == nullptr || !webviewController->IsInit()) {
5302        BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
5303        WVLOG_E("create message port failed, napi unwrap webviewController failed");
5304        return nullptr;
5305    }
5306
5307    std::string scheme = "";
5308    if (!NapiParseUtils::ParseString(env, argv[0], scheme)) {
5309        WVLOG_E("NapiWebviewController::SetWebSchemeHandler parse scheme failed");
5310        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5311            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "scheme", "string"));
5312        return nullptr;
5313    }
5314
5315    WebSchemeHandler* handler = nullptr;
5316    napi_value obj = argv[1];
5317    napi_unwrap(env, obj, (void**)&handler);
5318    if (!handler) {
5319        WVLOG_E("NapiWebviewController::SetWebSchemeHandler handler is null");
5320        return nullptr;
5321    }
5322    napi_create_reference(env, obj, 1, &handler->delegate_);
5323
5324    if (!webviewController->SetWebSchemeHandler(scheme.c_str(), handler)) {
5325        WVLOG_E("NapiWebviewController::SetWebSchemeHandler failed");
5326    }
5327    return nullptr;
5328}
5329
5330napi_value NapiWebviewController::ClearWebSchemeHandler(napi_env env, napi_callback_info info)
5331{
5332    napi_value result = nullptr;
5333    WebviewController *webviewController = GetWebviewController(env, info);
5334    if (!webviewController) {
5335        return nullptr;
5336    }
5337
5338    int32_t ret = webviewController->ClearWebSchemeHandler();
5339    if (ret != 0) {
5340        WVLOG_E("NapiWebviewController::ClearWebSchemeHandler failed");
5341    }
5342    NAPI_CALL(env, napi_get_undefined(env, &result));
5343    return result;
5344}
5345
5346napi_value NapiWebviewController::SetServiceWorkerWebSchemeHandler(
5347    napi_env env, napi_callback_info info)
5348{
5349    size_t argc = 2;
5350    napi_value argv[2] = {0};
5351    napi_value thisVar = nullptr;
5352    void* data = nullptr;
5353    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
5354
5355    std::string scheme = "";
5356    if (!NapiParseUtils::ParseString(env, argv[0], scheme)) {
5357        WVLOG_E("NapiWebviewController::SetWebSchemeHandler parse scheme failed");
5358        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5359            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "scheme", "string"));
5360        return nullptr;
5361    }
5362
5363    WebSchemeHandler* handler = nullptr;
5364    napi_value obj = argv[1];
5365    napi_unwrap(env, obj, (void**)&handler);
5366    if (!handler) {
5367        WVLOG_E("NapiWebviewController::SetServiceWorkerWebSchemeHandler handler is null");
5368        return nullptr;
5369    }
5370    napi_create_reference(env, obj, 1, &handler->delegate_);
5371
5372    if (!WebviewController::SetWebServiveWorkerSchemeHandler(
5373        scheme.c_str(), handler)) {
5374        WVLOG_E("NapiWebviewController::SetWebSchemeHandler failed");
5375    }
5376    return nullptr;
5377}
5378
5379napi_value NapiWebviewController::ClearServiceWorkerWebSchemeHandler(
5380    napi_env env, napi_callback_info info)
5381{
5382    int32_t ret = WebviewController::ClearWebServiceWorkerSchemeHandler();
5383    if (ret != 0) {
5384        WVLOG_E("ClearServiceWorkerWebSchemeHandler ret=%{public}d", ret);
5385        return nullptr;
5386    }
5387    return nullptr;
5388}
5389
5390napi_value NapiWebviewController::EnableIntelligentTrackingPrevention(
5391    napi_env env, napi_callback_info info)
5392{
5393    WVLOG_I("enable/disable intelligent tracking prevention.");
5394    napi_value result = nullptr;
5395    napi_value thisVar = nullptr;
5396    size_t argc = INTEGER_ONE;
5397    napi_value argv[INTEGER_ONE] = { 0 };
5398
5399    NAPI_CALL(env, napi_get_undefined(env, &result));
5400    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5401    if (argc != INTEGER_ONE) {
5402        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5403            "BusinessError 401: Parameter error. The number of params must be one.");
5404        return result;
5405    }
5406
5407    bool enabled = false;
5408    if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_ZERO], enabled)) {
5409        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5410            "BusinessError 401: Parameter error. The type of 'enable' must be boolean.");
5411        return result;
5412    }
5413
5414    WebviewController *webviewController = GetWebviewController(env, info);
5415    if (!webviewController) {
5416        return result;
5417    }
5418    webviewController->EnableIntelligentTrackingPrevention(enabled);
5419    return result;
5420}
5421
5422napi_value NapiWebviewController::IsIntelligentTrackingPreventionEnabled(
5423    napi_env env, napi_callback_info info)
5424{
5425    WVLOG_I("get intelligent tracking prevention enabled value.");
5426    napi_value result = nullptr;
5427    WebviewController *webviewController = GetWebviewController(env, info);
5428
5429    if (!webviewController) {
5430        return result;
5431    }
5432
5433    bool enabled = webviewController->
5434        IsIntelligentTrackingPreventionEnabled();
5435    NAPI_CALL(env, napi_get_boolean(env, enabled, &result));
5436    return result;
5437}
5438
5439bool GetHostList(napi_env env, napi_value array, std::vector<std::string>& hosts)
5440{
5441    uint32_t arrayLen = 0;
5442    napi_get_array_length(env, array, &arrayLen);
5443    if (arrayLen == 0) {
5444        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5445            "BusinessError 401: Parameter error. The array length must be greater than 0.");
5446        return false;
5447    }
5448
5449    for (uint32_t i = 0; i < arrayLen; i++) {
5450        napi_value hostItem = nullptr;
5451        napi_get_element(env, array, i, &hostItem);
5452
5453        size_t hostLen = 0;
5454        napi_get_value_string_utf8(env, hostItem, nullptr, 0, &hostLen);
5455        if (hostLen == 0 || hostLen > UINT_MAX) {
5456            WVLOG_E("hostitem length is invalid");
5457            return false;
5458        }
5459
5460        char host[hostLen + 1];
5461        int retCode = memset_s(host, sizeof(host), 0, hostLen + 1);
5462        if (retCode < 0) {
5463            WVLOG_E("memset_s failed, retCode=%{public}d", retCode);
5464            return false;
5465        }
5466        napi_get_value_string_utf8(env, hostItem, host, sizeof(host), &hostLen);
5467        std::string hostStr(host);
5468        hosts.emplace_back(hostStr);
5469    }
5470    return true;
5471}
5472
5473napi_value NapiWebviewController::AddIntelligentTrackingPreventionBypassingList(
5474    napi_env env, napi_callback_info info)
5475{
5476    WVLOG_I("Add intelligent tracking prevention bypassing list.");
5477    napi_value result = nullptr;
5478    napi_value thisVar = nullptr;
5479    size_t argc = INTEGER_ONE;
5480    napi_value argv[INTEGER_ONE] = { 0 };
5481    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5482    if (argc != INTEGER_ONE) {
5483        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5484            "BusinessError 401: Parameter error. The number of params must be one.");
5485        return result;
5486    }
5487
5488    bool isArray = false;
5489    NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ZERO], &isArray));
5490    if (!isArray) {
5491        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5492            "BusinessError 401: Parameter error. The type of 'hostList' must be string array.");
5493        return result;
5494    }
5495
5496    std::vector<std::string> hosts;
5497    if (!GetHostList(env, argv[INTEGER_ZERO], hosts)) {
5498        WVLOG_E("get host list failed, GetHostList fail");
5499        return result;
5500    }
5501
5502    NWebHelper::Instance().AddIntelligentTrackingPreventionBypassingList(hosts);
5503    NAPI_CALL(env, napi_get_undefined(env, &result));
5504    return result;
5505}
5506
5507napi_value NapiWebviewController::RemoveIntelligentTrackingPreventionBypassingList(
5508    napi_env env, napi_callback_info info)
5509{
5510    WVLOG_I("Remove intelligent tracking prevention bypassing list.");
5511    napi_value result = nullptr;
5512    napi_value thisVar = nullptr;
5513    size_t argc = INTEGER_ONE;
5514    napi_value argv[INTEGER_ONE] = { 0 };
5515    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5516    if (argc != INTEGER_ONE) {
5517        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5518            "BusinessError 401: Parameter error. The number of params must be one.");
5519        return result;
5520    }
5521
5522    bool isArray = false;
5523    NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ZERO], &isArray));
5524    if (!isArray) {
5525        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5526            "BusinessError 401: Parameter error. The type of 'hostList' must be string array.");
5527        return result;
5528    }
5529
5530    std::vector<std::string> hosts;
5531    if (!GetHostList(env, argv[INTEGER_ZERO], hosts)) {
5532        WVLOG_E("get host list failed, GetHostList fail");
5533        return result;
5534    }
5535
5536    NWebHelper::Instance().RemoveIntelligentTrackingPreventionBypassingList(hosts);
5537    NAPI_CALL(env, napi_get_undefined(env, &result));
5538    return result;
5539}
5540
5541napi_value NapiWebviewController::ClearIntelligentTrackingPreventionBypassingList(
5542    napi_env env, napi_callback_info info)
5543{
5544    napi_value result = nullptr;
5545    WVLOG_I("Clear intelligent tracking prevention bypassing list.");
5546    NWebHelper::Instance().ClearIntelligentTrackingPreventionBypassingList();
5547    NAPI_CALL(env, napi_get_undefined(env, &result));
5548    return result;
5549}
5550
5551napi_value NapiWebviewController::GetDefaultUserAgent(napi_env env, napi_callback_info info)
5552{
5553    WVLOG_I("Get the default user agent.");
5554    napi_value result = nullptr;
5555
5556    std::string userAgent = NWebHelper::Instance().GetDefaultUserAgent();
5557    NAPI_CALL(env, napi_create_string_utf8(env, userAgent.c_str(), userAgent.length(), &result));
5558    return result;
5559}
5560
5561napi_value NapiWebviewController::PauseAllTimers(napi_env env, napi_callback_info info)
5562{
5563    napi_value result = nullptr;
5564    NWebHelper::Instance().PauseAllTimers();
5565    NAPI_CALL(env, napi_get_undefined(env, &result));
5566    return result;
5567}
5568
5569napi_value NapiWebviewController::ResumeAllTimers(napi_env env, napi_callback_info info)
5570{
5571    napi_value result = nullptr;
5572    NWebHelper::Instance().ResumeAllTimers();
5573    NAPI_CALL(env, napi_get_undefined(env, &result));
5574    return result;
5575}
5576
5577napi_value NapiWebviewController::StartCamera(napi_env env, napi_callback_info info)
5578{
5579    napi_value result = nullptr;
5580    NAPI_CALL(env, napi_get_undefined(env, &result));
5581    WebviewController* webviewController = GetWebviewController(env, info);
5582    if (!webviewController) {
5583        return result;
5584    }
5585    webviewController->StartCamera();
5586
5587    return result;
5588}
5589
5590napi_value NapiWebviewController::StopCamera(napi_env env, napi_callback_info info)
5591{
5592    napi_value result = nullptr;
5593    NAPI_CALL(env, napi_get_undefined(env, &result));
5594    WebviewController* webviewController = GetWebviewController(env, info);
5595    if (!webviewController) {
5596        return result;
5597    }
5598    webviewController->StopCamera();
5599
5600    return result;
5601}
5602
5603napi_value NapiWebviewController::CloseCamera(napi_env env, napi_callback_info info)
5604{
5605    napi_value result = nullptr;
5606    NAPI_CALL(env, napi_get_undefined(env, &result));
5607    WebviewController* webviewController = GetWebviewController(env, info);
5608    if (!webviewController) {
5609        return result;
5610    }
5611    webviewController->CloseCamera();
5612
5613    return result;
5614}
5615
5616napi_value NapiWebviewController::OnCreateNativeMediaPlayer(napi_env env, napi_callback_info info)
5617{
5618    WVLOG_D("put on_create_native_media_player callback");
5619
5620    size_t argc = INTEGER_ONE;
5621    napi_value value = nullptr;
5622    napi_value argv[INTEGER_ONE];
5623    napi_get_cb_info(env, info, &argc, argv, &value, nullptr);
5624    if (argc != INTEGER_ONE) {
5625        WVLOG_E("arg count %{public}zu is not equal to 1", argc);
5626        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5627        return nullptr;
5628    }
5629
5630    napi_valuetype valueType = napi_undefined;
5631    napi_typeof(env, argv[INTEGER_ZERO], &valueType);
5632    if (valueType != napi_function) {
5633        WVLOG_E("arg type is invalid");
5634        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5635        return nullptr;
5636    }
5637
5638    napi_ref callback = nullptr;
5639    napi_create_reference(env, argv[INTEGER_ZERO], INTEGER_ONE, &callback);
5640    if (!callback) {
5641        WVLOG_E("failed to create reference for callback");
5642        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5643        return nullptr;
5644    }
5645
5646    WebviewController* webviewController = GetWebviewController(env, info);
5647    if (!webviewController || !webviewController->IsInit()) {
5648        WVLOG_E("webview controller is null or not init");
5649        napi_delete_reference(env, callback);
5650        return nullptr;
5651    }
5652
5653    webviewController->OnCreateNativeMediaPlayer(env, std::move(callback));
5654    return nullptr;
5655}
5656
5657napi_value NapiWebviewController::SetRenderProcessMode(
5658    napi_env env, napi_callback_info info)
5659{
5660    WVLOG_I("set render process mode.");
5661    napi_value result = nullptr;
5662    napi_value thisVar = nullptr;
5663    size_t argc = INTEGER_ONE;
5664    napi_value argv[INTEGER_ONE] = { 0 };
5665
5666    NAPI_CALL(env, napi_get_undefined(env, &result));
5667    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5668    if (argc != INTEGER_ONE) {
5669        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5670            "BusinessError 401: Parameter error. The number of params must be one.");
5671        return result;
5672    }
5673
5674    int32_t mode = 0;
5675    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], mode)) {
5676        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5677            "BusinessError 401: Parameter error. The type of 'mode' must be int.");
5678        return result;
5679    }
5680
5681    NWebHelper::Instance().SetRenderProcessMode(
5682        static_cast<RenderProcessMode>(mode));
5683
5684    return result;
5685}
5686
5687napi_value NapiWebviewController::GetRenderProcessMode(
5688    napi_env env, napi_callback_info info)
5689{
5690    WVLOG_I("get render mode.");
5691    napi_value result = nullptr;
5692
5693    int32_t mode = static_cast<int32_t>(NWebHelper::Instance().GetRenderProcessMode());
5694    NAPI_CALL(env, napi_create_int32(env, mode, &result));
5695    return result;
5696}
5697
5698napi_value NapiWebviewController::PrecompileJavaScript(napi_env env, napi_callback_info info)
5699{
5700    napi_value thisVar = nullptr;
5701    napi_value result = nullptr;
5702    size_t argc = INTEGER_THREE;
5703    napi_value argv[INTEGER_THREE] = {0};
5704    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5705    if (argc != INTEGER_THREE) {
5706        WVLOG_E("BusinessError: 401. Args count of 'PrecompileJavaScript' must be 3.");
5707        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5708        return result;
5709    }
5710
5711    WebviewController* webviewController = GetWebviewController(env, info);
5712    if (!webviewController) {
5713        WVLOG_E("PrecompileJavaScript: init webview controller error.");
5714        return result;
5715    }
5716
5717    std::string url;
5718    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], url) || url.empty()) {
5719        WVLOG_E("BusinessError: 401. The type of 'url' must be string.");
5720        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5721        return result;
5722    }
5723
5724    std::string script;
5725    bool parseResult = webviewController->ParseScriptContent(env, argv[INTEGER_ONE], script);
5726    if (!parseResult) {
5727        WVLOG_E("BusinessError: 401. The type of 'script' must be string or Uint8Array.");
5728        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5729        return result;
5730    }
5731
5732    auto cacheOptions = webviewController->ParseCacheOptions(env, argv[INTEGER_TWO]);
5733
5734    napi_deferred deferred = nullptr;
5735    napi_value promise = nullptr;
5736    napi_create_promise(env, &deferred, &promise);
5737    if (promise && deferred) {
5738        webviewController->PrecompileJavaScriptPromise(env, deferred, url, script, cacheOptions);
5739        return promise;
5740    }
5741
5742    return promise;
5743}
5744
5745napi_value NapiWebviewController::EnableBackForwardCache(napi_env env, napi_callback_info info)
5746{
5747    napi_value thisVar = nullptr;
5748    napi_value result = nullptr;
5749    size_t argc = INTEGER_ONE;
5750    napi_value argv[INTEGER_ONE] = { 0 };
5751    napi_get_undefined(env, &result);
5752    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5753    if (argc != INTEGER_ONE) {
5754        WVLOG_E("EnalbeBackForwardCache: wrong number of params.");
5755        NWebHelper::Instance().EnableBackForwardCache(false, false);
5756        NAPI_CALL(env, napi_get_undefined(env, &result));
5757        return result;
5758    }
5759
5760    bool nativeEmbed = false;
5761    bool mediaTakeOver = false;
5762    napi_value embedObj = nullptr;
5763    napi_value mediaObj = nullptr;
5764    if (napi_get_named_property(env, argv[INTEGER_ZERO], "nativeEmbed", &embedObj) == napi_ok) {
5765        if (!NapiParseUtils::ParseBoolean(env, embedObj, nativeEmbed)) {
5766            nativeEmbed = false;
5767        }
5768    }
5769
5770    if (napi_get_named_property(env, argv[INTEGER_ZERO], "mediaTakeOver", &mediaObj) == napi_ok) {
5771        if (!NapiParseUtils::ParseBoolean(env, mediaObj, mediaTakeOver)) {
5772            mediaTakeOver = false;
5773        }
5774    }
5775
5776    NWebHelper::Instance().EnableBackForwardCache(nativeEmbed, mediaTakeOver);
5777    NAPI_CALL(env, napi_get_undefined(env, &result));
5778    return result;
5779}
5780
5781napi_value NapiWebviewController::SetBackForwardCacheOptions(napi_env env, napi_callback_info info)
5782{
5783    napi_value thisVar = nullptr;
5784    napi_value result = nullptr;
5785    size_t argc = INTEGER_ONE;
5786    napi_value argv[INTEGER_ONE] = { 0 };
5787    napi_get_undefined(env, &result);
5788    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5789    WebviewController* webviewController = GetWebviewController(env, info);
5790    if (!webviewController) {
5791        WVLOG_E("SetBackForwardCacheOptions: Init webview controller error.");
5792        return result;
5793    }
5794
5795    if (argc != INTEGER_ONE) {
5796        WVLOG_E("SetBackForwardCacheOptions: wrong number of params.");
5797        webviewController->SetBackForwardCacheOptions(
5798            BFCACHE_DEFAULT_SIZE, BFCACHE_DEFAULT_TIMETOLIVE);
5799        NAPI_CALL(env, napi_get_undefined(env, &result));
5800        return result;
5801    }
5802
5803    int32_t size = BFCACHE_DEFAULT_SIZE;
5804    int32_t timeToLive = BFCACHE_DEFAULT_TIMETOLIVE;
5805    napi_value sizeObj = nullptr;
5806    napi_value timeToLiveObj = nullptr;
5807    if (napi_get_named_property(env, argv[INTEGER_ZERO], "size", &sizeObj) == napi_ok) {
5808        if (!NapiParseUtils::ParseInt32(env, sizeObj, size)) {
5809            size = BFCACHE_DEFAULT_SIZE;
5810        }
5811    }
5812
5813    if (napi_get_named_property(env, argv[INTEGER_ZERO], "timeToLive", &timeToLiveObj) == napi_ok) {
5814        if (!NapiParseUtils::ParseInt32(env, timeToLiveObj, timeToLive)) {
5815            timeToLive = BFCACHE_DEFAULT_TIMETOLIVE;
5816        }
5817    }
5818
5819    webviewController->SetBackForwardCacheOptions(size, timeToLive);
5820    NAPI_CALL(env, napi_get_undefined(env, &result));
5821    return result;
5822}
5823
5824napi_value NapiWebviewController::WarmupServiceWorker(napi_env env, napi_callback_info info)
5825{
5826    napi_value thisVar = nullptr;
5827    napi_value result = nullptr;
5828    size_t argc = INTEGER_ONE;
5829    napi_value argv[INTEGER_ONE] = { 0 };
5830    napi_get_undefined(env, &result);
5831    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5832    if (argc != INTEGER_ONE) {
5833        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5834        return result;
5835    }
5836
5837    std::string url;
5838    if (!ParsePrepareUrl(env, argv[INTEGER_ZERO], url)) {
5839        BusinessError::ThrowErrorByErrcode(env, INVALID_URL);
5840        return result;
5841    }
5842
5843    NWebHelper::Instance().WarmupServiceWorker(url);
5844    return result;
5845}
5846
5847napi_value NapiWebviewController::InjectOfflineResources(napi_env env, napi_callback_info info)
5848{
5849    napi_value thisVar = nullptr;
5850    napi_value result = nullptr;
5851    size_t argc = INTEGER_ONE;
5852    napi_value argv[INTEGER_ONE] = {0};
5853    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5854    if (argc != INTEGER_ONE) {
5855        WVLOG_E("BusinessError: 401. Args count of 'InjectOfflineResource' must be 1.");
5856        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5857        return result;
5858    }
5859
5860    napi_value resourcesList = argv[INTEGER_ZERO];
5861    bool isArray = false;
5862    napi_is_array(env, resourcesList, &isArray);
5863    if (!isArray) {
5864        WVLOG_E("BusinessError: 401. The type of 'resourceMaps' must be Array");
5865        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5866        return result;
5867    }
5868
5869    AddResourcesToMemoryCache(env, info, resourcesList);
5870    return result;
5871}
5872
5873void NapiWebviewController::AddResourcesToMemoryCache(napi_env env,
5874                                                      napi_callback_info info,
5875                                                      napi_value& resourcesList)
5876{
5877    uint32_t resourcesCount = 0;
5878    napi_get_array_length(env, resourcesList, &resourcesCount);
5879
5880    if (resourcesCount > MAX_RESOURCES_COUNT || resourcesCount == 0) {
5881        WVLOG_E("BusinessError: 401. The size of 'resourceMaps' must less than %{public}zu and not 0",
5882            MAX_RESOURCES_COUNT);
5883        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5884        return;
5885    }
5886
5887    for (uint32_t i = 0 ; i < resourcesCount ; i++) {
5888        napi_value urlListObj = nullptr;
5889        napi_value resourceObj = nullptr;
5890        napi_value headersObj = nullptr;
5891        napi_value typeObj = nullptr;
5892        napi_value obj = nullptr;
5893
5894        napi_create_array(env, &headersObj);
5895        napi_create_array(env, &urlListObj);
5896
5897        napi_get_element(env, resourcesList, i, &obj);
5898        if ((napi_get_named_property(env, obj, "urlList", &urlListObj) != napi_ok) ||
5899            (napi_get_named_property(env, obj, "resource", &resourceObj) != napi_ok) ||
5900            (napi_get_named_property(env, obj, "responseHeaders", &headersObj) != napi_ok) ||
5901            (napi_get_named_property(env, obj, "type", &typeObj) != napi_ok)) {
5902            WVLOG_E("InjectOfflineResources: parse params from resource map failed.");
5903            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5904            continue;
5905        }
5906
5907        OfflineResourceValue resourceValue;
5908        resourceValue.urlList = urlListObj;
5909        resourceValue.resource = resourceObj;
5910        resourceValue.responseHeaders = headersObj;
5911        resourceValue.type = typeObj;
5912        AddResourceItemToMemoryCache(env, info, resourceValue);
5913    }
5914}
5915
5916void NapiWebviewController::AddResourceItemToMemoryCache(napi_env env,
5917                                                         napi_callback_info info,
5918                                                         OfflineResourceValue resourceValue)
5919{
5920    WebviewController* webviewController = GetWebviewController(env, info);
5921    if (!webviewController) {
5922        WVLOG_E("InjectOfflineResource: init webview controller error.");
5923        return;
5924    }
5925
5926    std::vector<std::string> urlList;
5927    ParseURLResult result = webviewController->ParseURLList(env, resourceValue.urlList, urlList);
5928    if (result != ParseURLResult::OK) {
5929        auto errCode = result == ParseURLResult::FAILED ? PARAM_CHECK_ERROR : INVALID_URL;
5930        if (errCode == PARAM_CHECK_ERROR) {
5931            WVLOG_E("BusinessError: 401. The type of 'urlList' must be Array of string.");
5932        }
5933        BusinessError::ThrowErrorByErrcode(env, errCode);
5934        return;
5935    }
5936
5937    std::vector<uint8_t> resource = webviewController->ParseUint8Array(env, resourceValue.resource);
5938    if (resource.empty() || resource.size() > MAX_RESOURCE_SIZE) {
5939        WVLOG_E("BusinessError: 401. The type of 'resource' must be Uint8Array. "
5940            "'resource' size must less than %{public}zu and must not be empty.", MAX_RESOURCE_SIZE);
5941        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5942        return;
5943    }
5944
5945    std::map<std::string, std::string> responseHeaders;
5946    if (!webviewController->ParseResponseHeaders(env, resourceValue.responseHeaders, responseHeaders)) {
5947        WVLOG_E("BusinessError: 401. The type of 'responseHeaders' must be Array of 'WebHeader'.");
5948        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5949        return;
5950    }
5951
5952    uint32_t type = 0;
5953    if (!NapiParseUtils::ParseUint32(env, resourceValue.type, type)) {
5954        WVLOG_E("BusinessError: 401. The type of 'type' must be one kind of 'OfflineResourceType'.");
5955        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
5956        return;
5957    }
5958
5959    webviewController->InjectOfflineResource(urlList, resource, responseHeaders, type);
5960}
5961
5962napi_value NapiWebviewController::SetHostIP(napi_env env, napi_callback_info info)
5963{
5964    napi_value thisVar = nullptr;
5965    napi_value result = nullptr;
5966    size_t argc = INTEGER_THREE;
5967    napi_value argv[INTEGER_THREE] = { 0 };
5968    std::string hostName;
5969    std::string address;
5970    int32_t aliveTime = INTEGER_ZERO;
5971
5972    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
5973    if (argc != INTEGER_THREE) {
5974        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5975            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "three"));
5976        return result;
5977    }
5978
5979    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], hostName) ||
5980        !NapiParseUtils::ParseString(env, argv[INTEGER_ONE], address) ||
5981        !NapiParseUtils::ParseInt32(env, argv[INTEGER_TWO], aliveTime) ||
5982        aliveTime <= 0) {
5983        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR, ParamCheckErrorMsgTemplate::PARAM_TYEPS_ERROR);
5984        return result;
5985    }
5986
5987    if (!ParseIP(env, argv[INTEGER_ONE], address)) {
5988        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
5989            "BusinessError 401: IP address error.");
5990        return result;
5991    }
5992
5993    NWebHelper::Instance().SetHostIP(hostName, address, aliveTime);
5994    NAPI_CALL(env, napi_get_undefined(env, &result));
5995
5996    return result;
5997}
5998
5999napi_value NapiWebviewController::ClearHostIP(napi_env env, napi_callback_info info)
6000{
6001    napi_value thisVar = nullptr;
6002    napi_value result = nullptr;
6003    size_t argc = INTEGER_ONE;
6004    napi_value argv[INTEGER_ONE] = { 0 };
6005    std::string hostName;
6006
6007    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6008    if (argc != INTEGER_ONE) {
6009        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6010            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
6011        return result;
6012    }
6013
6014    if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], hostName)) {
6015        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6016            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "hostName", "string"));
6017        return result;
6018    }
6019
6020    NWebHelper::Instance().ClearHostIP(hostName);
6021    NAPI_CALL(env, napi_get_undefined(env, &result));
6022    return result;
6023}
6024
6025napi_value NapiWebviewController::EnableWholeWebPageDrawing(
6026    napi_env env, napi_callback_info info)
6027{
6028    napi_value result = nullptr;
6029    NWebHelper::Instance().EnableWholeWebPageDrawing();
6030    NAPI_CALL(env, napi_get_undefined(env, &result));
6031    return result;
6032}
6033
6034napi_value NapiWebviewController::EnableAdsBlock(
6035    napi_env env, napi_callback_info info)
6036{
6037    napi_value result = nullptr;
6038    napi_value thisVar = nullptr;
6039    size_t argc = INTEGER_ONE;
6040    napi_value argv[INTEGER_ONE] = { 0 };
6041
6042    NAPI_CALL(env, napi_get_undefined(env, &result));
6043    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6044    if (argc != INTEGER_ONE) {
6045        WVLOG_E("EnableAdsBlock: args count is not allowed.");
6046        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6047            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
6048        return result;
6049    }
6050
6051    bool enabled = false;
6052    if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_ZERO], enabled)) {
6053        WVLOG_E("EnableAdsBlock: the given enabled is not allowed.");
6054        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6055            "BusinessError 401: Parameter error. The type of 'enable' must be boolean.");
6056        return result;
6057    }
6058
6059    WebviewController *webviewController = GetWebviewController(env, info);
6060    if (!webviewController) {
6061        WVLOG_E("EnableAdsBlock: init webview controller error.");
6062        return result;
6063    }
6064
6065    WVLOG_I("EnableAdsBlock: %{public}s", (enabled ? "true" : "false"));
6066    webviewController->EnableAdsBlock(enabled);
6067    return result;
6068}
6069
6070napi_value NapiWebviewController::IsAdsBlockEnabled(napi_env env, napi_callback_info info)
6071{
6072    napi_value result = nullptr;
6073    WebviewController *webviewController = GetWebviewController(env, info);
6074    if (!webviewController) {
6075        return nullptr;
6076    }
6077
6078    bool isAdsBlockEnabled = webviewController->IsAdsBlockEnabled();
6079    NAPI_CALL(env, napi_get_boolean(env, isAdsBlockEnabled, &result));
6080    return result;
6081}
6082
6083napi_value NapiWebviewController::IsAdsBlockEnabledForCurPage(napi_env env, napi_callback_info info)
6084{
6085    napi_value result = nullptr;
6086    WebviewController *webviewController = GetWebviewController(env, info);
6087    if (!webviewController) {
6088        return nullptr;
6089    }
6090
6091    bool isAdsBlockEnabledForCurPage = webviewController->IsAdsBlockEnabledForCurPage();
6092    NAPI_CALL(env, napi_get_boolean(env, isAdsBlockEnabledForCurPage, &result));
6093    return result;
6094}
6095
6096napi_value NapiWebviewController::GetSurfaceId(napi_env env, napi_callback_info info)
6097{
6098    napi_value result = nullptr;
6099    WebviewController *webviewController = GetWebviewController(env, info);
6100    if (!webviewController) {
6101        return nullptr;
6102    }
6103
6104    std::string surfaceId = webviewController->GetSurfaceId();
6105    napi_create_string_utf8(env, surfaceId.c_str(), surfaceId.length(), &result);
6106    return result;
6107}
6108
6109napi_value NapiWebviewController::UpdateInstanceId(napi_env env, napi_callback_info info)
6110{
6111    WVLOG_D("Instance changed");
6112    napi_value result = nullptr;
6113    napi_value thisVar = nullptr;
6114    size_t argc = INTEGER_ONE;
6115    napi_value argv[INTEGER_ONE] = { 0 };
6116
6117    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6118    if (argc != INTEGER_ONE) {
6119        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
6120        return result;
6121    }
6122
6123    int32_t newId = 0;
6124    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], newId)) {
6125        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
6126        return result;
6127    }
6128
6129    WebviewController *webviewController = nullptr;
6130    napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
6131    if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
6132        return result;
6133    }
6134
6135    webviewController->UpdateInstanceId(newId);
6136
6137    NAPI_CALL(env, napi_get_undefined(env, &result));
6138    return result;
6139}
6140
6141napi_value NapiWebviewController::SetUrlTrustList(napi_env env, napi_callback_info info)
6142{
6143    WVLOG_D("SetUrlTrustList invoked");
6144
6145    napi_value result = nullptr;
6146    NAPI_CALL(env, napi_get_undefined(env, &result));
6147
6148    napi_value thisVar = nullptr;
6149    size_t argc = INTEGER_ONE;
6150    napi_value argv[INTEGER_ONE] = { 0 };
6151    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6152    if (argc != INTEGER_ONE) {
6153        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6154            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
6155        return result;
6156    }
6157
6158    std::string urlTrustList;
6159    if (!NapiParseUtils::ParseString(env, argv[0], urlTrustList)) {
6160        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6161            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "urlTrustList", "string"));
6162        return result;
6163    }
6164    if (urlTrustList.size() > MAX_URL_TRUST_LIST_STR_LEN) {
6165        WVLOG_E("EnableAdsBlock: url trust list len is too large.");
6166        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
6167        return result;
6168    }
6169
6170    WebviewController* webviewController = GetWebviewController(env, info);
6171    if (!webviewController) {
6172        WVLOG_E("webview controller is null or not init");
6173        return result;
6174    }
6175
6176    std::string detailMsg;
6177    ErrCode ret = webviewController->SetUrlTrustList(urlTrustList, detailMsg);
6178    if (ret != NO_ERROR) {
6179        WVLOG_E("SetUrlTrustList failed, error code: %{public}d", ret);
6180        BusinessError::ThrowErrorByErrcode(env, ret,
6181            NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_DETAIL_ERROR_MSG, detailMsg.c_str()));
6182        return result;
6183    }
6184    return result;
6185}
6186
6187WebSnapshotCallback CreateWebPageSnapshotResultCallback(
6188    napi_env env, napi_ref jsCallback, bool check, int32_t inputWidth, int32_t inputHeight)
6189{
6190    return
6191        [env, jCallback = std::move(jsCallback), check, inputWidth, inputHeight](
6192            const char *returnId, bool returnStatus, float radio, void *returnData,
6193            int returnWidth, int returnHeight) {
6194            WVLOG_I("WebPageSnapshot return napi callback");
6195            napi_value jsResult = nullptr;
6196            napi_create_object(env, &jsResult);
6197
6198            napi_value jsPixelMap = nullptr;
6199            Media::InitializationOptions opt;
6200            opt.size.width = static_cast<int32_t>(returnWidth);
6201            opt.size.height = static_cast<int32_t>(returnHeight);
6202            opt.pixelFormat = Media::PixelFormat::RGBA_8888;
6203            opt.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
6204            opt.editable = true;
6205            auto pixelMap = Media::PixelMap::Create(opt);
6206            if (pixelMap != nullptr) {
6207                uint64_t stride = static_cast<uint64_t>(returnWidth) << 2;
6208                uint64_t bufferSize = stride * static_cast<uint64_t>(returnHeight);
6209                pixelMap->WritePixels(static_cast<const uint8_t *>(returnData), bufferSize);
6210                std::shared_ptr<Media::PixelMap> pixelMapToJs(pixelMap.release());
6211                jsPixelMap = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMapToJs);
6212            } else {
6213                WVLOG_E("WebPageSnapshot create pixel map error");
6214            }
6215            napi_set_named_property(env, jsResult, "imagePixelMap", jsPixelMap);
6216
6217            int returnJsWidth = 0;
6218            int returnJsHeight = 0;
6219            if (radio > 0) {
6220                returnJsWidth = returnWidth / radio;
6221                returnJsHeight = returnHeight / radio;
6222            }
6223            if (check) {
6224                if (std::abs(returnJsWidth - inputWidth) < INTEGER_THREE) {
6225                    returnJsWidth = inputWidth;
6226                }
6227
6228                if (std::abs(returnJsHeight - inputHeight) < INTEGER_THREE) {
6229                    returnJsHeight = inputHeight;
6230                }
6231            }
6232            napi_value jsSizeObj = nullptr;
6233            napi_create_object(env, &jsSizeObj);
6234            napi_value jsSize[2] = {0};
6235            napi_create_int32(env, returnJsWidth, &jsSize[0]);
6236            napi_create_int32(env, returnJsHeight, &jsSize[1]);
6237            napi_set_named_property(env, jsSizeObj, "width", jsSize[0]);
6238            napi_set_named_property(env, jsSizeObj, "height", jsSize[1]);
6239            napi_set_named_property(env, jsResult, "size", jsSizeObj);
6240
6241            napi_value jsId = nullptr;
6242            napi_create_string_utf8(env, returnId, strlen(returnId), &jsId);
6243            napi_set_named_property(env, jsResult, "id", jsId);
6244
6245            napi_value jsStatus = nullptr;
6246            napi_get_boolean(env, returnStatus, &jsStatus);
6247            napi_set_named_property(env, jsResult, "status", jsStatus);
6248
6249            napi_value jsError = nullptr;
6250            napi_get_undefined(env, &jsError);
6251            napi_value args[INTEGER_TWO] = {jsError, jsResult};
6252
6253            napi_value callback = nullptr;
6254            napi_value callbackResult = nullptr;
6255            napi_get_reference_value(env, jCallback, &callback);
6256
6257            napi_call_function(env, nullptr, callback, INTEGER_TWO, args, &callbackResult);
6258            napi_delete_reference(env, jCallback);
6259            g_inWebPageSnapshot = false;
6260        };
6261}
6262
6263napi_value NapiWebviewController::WebPageSnapshot(napi_env env, napi_callback_info info)
6264{
6265    napi_value thisVar = nullptr;
6266    napi_value result = nullptr;
6267    size_t argc = INTEGER_TWO;
6268    napi_value argv[INTEGER_TWO] = {0};
6269
6270    napi_get_undefined(env, &result);
6271    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6272
6273    if (argc != INTEGER_TWO) {
6274        WVLOG_E("WebPageSnapshot: args count is not allowed.");
6275        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
6276        return result;
6277    }
6278
6279    napi_ref callback = nullptr;
6280    napi_create_reference(env, argv[INTEGER_ONE], INTEGER_ONE, &callback);
6281    if (!callback) {
6282        WVLOG_E("WebPageSnapshot failed to create reference for callback");
6283        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
6284        return result;
6285    }
6286
6287    WebviewController *webviewController = GetWebviewController(env, info);
6288    if (!webviewController) {
6289        WVLOG_E("WebPageSnapshot init webview controller error.");
6290        napi_delete_reference(env, callback);
6291        return result;
6292    }
6293
6294    if (g_inWebPageSnapshot) {
6295        JsErrorCallback(env, std::move(callback), FUNCTION_NOT_ENABLE);
6296        napi_delete_reference(env, callback);
6297        return result;
6298    }
6299    g_inWebPageSnapshot = true;
6300
6301    napi_value snapshotId = nullptr;
6302    napi_value snapshotSize = nullptr;
6303    napi_value snapshotSizeWidth = nullptr;
6304    napi_value snapshotSizeHeight = nullptr;
6305
6306    std::string nativeSnapshotId = "";
6307    int32_t nativeSnapshotSizeWidth = 0;
6308    int32_t nativeSnapshotSizeHeight = 0;
6309    PixelUnit nativeSnapshotSizeWidthType = PixelUnit::NONE;
6310    PixelUnit nativeSnapshotSizeHeightType = PixelUnit::NONE;
6311    PixelUnit nativeSnapshotSizeType = PixelUnit::NONE;
6312
6313    if (napi_get_named_property(env, argv[INTEGER_ZERO], "id", &snapshotId) == napi_ok) {
6314        NapiParseUtils::ParseString(env, snapshotId, nativeSnapshotId);
6315    }
6316
6317    if (napi_get_named_property(env, argv[INTEGER_ZERO], "size", &snapshotSize) == napi_ok) {
6318        if (napi_get_named_property(env, snapshotSize, "width", &snapshotSizeWidth) == napi_ok) {
6319            if (!webviewController->ParseJsLengthToInt(env, snapshotSizeWidth,
6320                                                       nativeSnapshotSizeWidthType,
6321                                                       nativeSnapshotSizeWidth)) {
6322                JsErrorCallback(env, std::move(callback), PARAM_CHECK_ERROR);
6323                g_inWebPageSnapshot = false;
6324                napi_delete_reference(env, callback);
6325                return result;
6326            }
6327        }
6328        if (napi_get_named_property(env, snapshotSize, "height", &snapshotSizeHeight) == napi_ok) {
6329            if (!webviewController->ParseJsLengthToInt(env, snapshotSizeHeight,
6330                                                       nativeSnapshotSizeHeightType,
6331                                                       nativeSnapshotSizeHeight)) {
6332                JsErrorCallback(env, std::move(callback), PARAM_CHECK_ERROR);
6333                g_inWebPageSnapshot = false;
6334                napi_delete_reference(env, callback);
6335                return result;
6336            }
6337        }
6338    }
6339
6340    if (nativeSnapshotSizeWidthType != PixelUnit::NONE && nativeSnapshotSizeHeightType != PixelUnit::NONE &&
6341        nativeSnapshotSizeWidthType != nativeSnapshotSizeHeightType) {
6342        WVLOG_E("WebPageSnapshot input different pixel unit");
6343        JsErrorCallback(env, std::move(callback), PARAM_CHECK_ERROR);
6344        g_inWebPageSnapshot = false;
6345        napi_delete_reference(env, callback);
6346        return result;
6347    }
6348
6349    if (nativeSnapshotSizeWidthType != PixelUnit::NONE) {
6350        nativeSnapshotSizeType = nativeSnapshotSizeWidthType;
6351    }
6352    if (nativeSnapshotSizeHeightType != PixelUnit::NONE) {
6353        nativeSnapshotSizeType = nativeSnapshotSizeHeightType;
6354    }
6355    if (nativeSnapshotSizeWidth < 0 || nativeSnapshotSizeHeight < 0) {
6356        WVLOG_E("WebPageSnapshot input pixel length less than 0");
6357        JsErrorCallback(env, std::move(callback), PARAM_CHECK_ERROR);
6358        g_inWebPageSnapshot = false;
6359        napi_delete_reference(env, callback);
6360        return result;
6361    }
6362    bool pixelCheck = false;
6363    if (nativeSnapshotSizeType == PixelUnit::VP) {
6364        pixelCheck = true;
6365    }
6366    WVLOG_I("WebPageSnapshot pixel type :%{public}d", static_cast<int>(nativeSnapshotSizeType));
6367
6368    auto resultCallback = CreateWebPageSnapshotResultCallback(
6369        env, std::move(callback), pixelCheck, nativeSnapshotSizeWidth, nativeSnapshotSizeHeight);
6370
6371    ErrCode ret = webviewController->WebPageSnapshot(nativeSnapshotId.c_str(),
6372        nativeSnapshotSizeType,
6373        nativeSnapshotSizeWidth,
6374        nativeSnapshotSizeHeight,
6375        std::move(resultCallback));
6376    if (ret != NO_ERROR) {
6377        g_inWebPageSnapshot = false;
6378        BusinessError::ThrowErrorByErrcode(env, ret);
6379    }
6380    return result;
6381}
6382
6383napi_value NapiWebviewController::SetPathAllowingUniversalAccess(
6384    napi_env env, napi_callback_info info)
6385{
6386    napi_value result = nullptr;
6387    napi_value thisVar = nullptr;
6388    size_t argc = INTEGER_ONE;
6389    napi_value argv[INTEGER_ONE] = { 0 };
6390    NAPI_CALL(env, napi_get_undefined(env, &result));
6391    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6392    WebviewController *webviewController = GetWebviewController(env, info);
6393    if (!webviewController) {
6394        WVLOG_E("SetPathAllowingUniversalAccess init webview controller error.");
6395        return result;
6396    }
6397    bool isArray = false;
6398    NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ZERO], &isArray));
6399    if (!isArray) {
6400        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6401            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "pathList", "Array<string>"));
6402        return result;
6403    }
6404    std::vector<std::string> pathList;
6405    uint32_t pathCount = 0;
6406    NAPI_CALL(env, napi_get_array_length(env, argv[INTEGER_ZERO], &pathCount));
6407    for (uint32_t i = 0 ; i < pathCount ; i++) {
6408        napi_value pathItem = nullptr;
6409        napi_get_element(env, argv[INTEGER_ZERO], i, &pathItem);
6410        std::string path;
6411        if (!NapiParseUtils::ParseString(env, pathItem, path)) {
6412            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6413                NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "pathList", "Array<string>"));
6414            return result;
6415        }
6416        if (path.empty()) {
6417            BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6418                NWebError::FormatString("BusinessError 401: Parameter error. Path: '%s' is invalid", path.c_str()));
6419            return result;
6420        }
6421        pathList.emplace_back(path);
6422    }
6423    std::string errorPath;
6424    webviewController->SetPathAllowingUniversalAccess(pathList, errorPath);
6425    if (!errorPath.empty()) {
6426        WVLOG_E("%{public}s is invalid.", errorPath.c_str());
6427        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6428            NWebError::FormatString("BusinessError 401: Parameter error. Path: '%s' is invalid", errorPath.c_str()));
6429    }
6430    return result;
6431}
6432
6433napi_value NapiWebviewController::TrimMemoryByPressureLevel(napi_env env,
6434    napi_callback_info info)
6435{
6436    napi_value thisVar = nullptr;
6437    napi_value result = nullptr;
6438    size_t argc = INTEGER_ONE;
6439    napi_value argv[INTEGER_ONE] = { 0 };
6440    int32_t memoryLevel;
6441    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6442    if (argc != INTEGER_ONE) {
6443        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6444            NWebError::FormatString(
6445                ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "one"));
6446        return result;
6447    }
6448
6449    if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], memoryLevel)) {
6450        BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6451            NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR,
6452                                    "PressureLevel", "number"));
6453        return result;
6454    }
6455
6456    memoryLevel = memoryLevel == 1 ? 0 : memoryLevel;
6457    NWebHelper::Instance().TrimMemoryByPressureLevel(memoryLevel);
6458    NAPI_CALL(env, napi_get_undefined(env, &result));
6459    return result;
6460}
6461
6462napi_value NapiWebviewController::GetScrollOffset(napi_env env,
6463    napi_callback_info info)
6464{
6465    napi_value result = nullptr;
6466    napi_value horizontal;
6467    napi_value vertical;
6468    float offsetX = 0;
6469    float offsetY = 0;
6470
6471    WebviewController* webviewController = GetWebviewController(env, info);
6472    if (!webviewController) {
6473        return nullptr;
6474    }
6475
6476    webviewController->GetScrollOffset(&offsetX, &offsetY);
6477
6478    napi_create_object(env, &result);
6479    napi_create_double(env, static_cast<double>(offsetX), &horizontal);
6480    napi_create_double(env, static_cast<double>(offsetY), &vertical);
6481    napi_set_named_property(env, result, "x", horizontal);
6482    napi_set_named_property(env, result, "y", vertical);
6483    return result;
6484}
6485
6486napi_value NapiWebviewController::ScrollByWithResult(napi_env env, napi_callback_info info)
6487{
6488   napi_value thisVar = nullptr;
6489   napi_value result = nullptr;
6490   size_t argc = INTEGER_TWO;
6491   napi_value argv[INTEGER_TWO] = { 0 };
6492   float deltaX;
6493   float deltaY;
6494
6495   napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
6496   if (argc != INTEGER_TWO) {
6497       BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6498           NWebError::FormatString(ParamCheckErrorMsgTemplate::PARAM_NUMBERS_ERROR_ONE, "two"));
6499       return result;
6500   }
6501
6502   if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], deltaX)) {
6503       BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6504           NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "deltaX", "number"));
6505       return result;
6506   }
6507
6508   if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], deltaY)) {
6509       BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
6510           NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "deltaY", "number"));
6511       return result;
6512   }
6513
6514   WebviewController *webviewController = GetWebviewController(env, info);
6515   if (!webviewController) {
6516       return nullptr;
6517   }
6518
6519   bool scrollByWithResult = webviewController->ScrollByWithResult(deltaX, deltaY);
6520   NAPI_CALL(env, napi_get_boolean(env, scrollByWithResult, &result));
6521   return result;
6522}
6523} // namespace NWeb
6524} // namespace OHOS
6525