1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <cstdint>
17#include "webview_controller_impl.h"
18#include "webview_javascript_execute_callback.h"
19#include "webview_javascript_result_callback.h"
20#include "webview_hasimage_callback.h"
21#include "native_arkweb_utils.h"
22#include "native_interface_arkweb.h"
23#include "cj_common_ffi.h"
24#include "application_context.h"
25#include "webview_log.h"
26#include "webview_utils.h"
27#include "nweb_store_web_archive_callback.h"
28#include <nweb_helper.h>
29#include "web_errors.h"
30#include "ffi_remote_data.h"
31#include "arkweb_scheme_handler.h"
32
33namespace OHOS::Webview {
34    constexpr int MAX_CUSTOM_SCHEME_SIZE = 10;
35    constexpr int MAX_CUSTOM_SCHEME_NAME_LENGTH = 32;
36    std::unordered_map<int32_t, WebviewControllerImpl*> g_webview_controller_map;
37    std::string WebviewControllerImpl::customeSchemeCmdLine_ = "";
38    bool WebviewControllerImpl::existNweb_ = false;
39    bool WebviewControllerImpl::webDebuggingAccess_ = false;
40
41    // WebMessagePortImpl
42    WebMessagePortImpl::WebMessagePortImpl(int32_t nwebId, std::string port, bool isExtentionType)
43        : nwebId_(nwebId), portHandle_(port), isExtentionType_(isExtentionType)
44    {}
45
46    ErrCode WebMessagePortImpl::ClosePort()
47    {
48        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
49        if (!nweb_ptr) {
50            return NWebError::INIT_ERROR;
51        }
52
53        nweb_ptr->ClosePort(portHandle_);
54        portHandle_.clear();
55        return NWebError::NO_ERROR;
56    }
57
58    ErrCode WebMessagePortImpl::PostPortMessage(std::shared_ptr<NWeb::NWebMessage> data)
59    {
60        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
61        if (!nweb_ptr) {
62            return NWebError::INIT_ERROR;
63        }
64
65        if (portHandle_.empty()) {
66            WEBVIEWLOGE("can't post message, message port already closed");
67            return NWebError::CAN_NOT_POST_MESSAGE;
68        }
69        nweb_ptr->PostPortMessage(portHandle_, data);
70        return NWebError::NO_ERROR;
71    }
72
73    ErrCode WebMessagePortImpl::SetPortMessageCallback(
74        std::shared_ptr<NWeb::NWebMessageValueCallback> callback)
75    {
76        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
77        if (!nweb_ptr) {
78            return NWebError::INIT_ERROR;
79        }
80
81        if (portHandle_.empty()) {
82            WEBVIEWLOGE("can't register message port callback event, message port already closed");
83            return NWebError::CAN_NOT_REGISTER_MESSAGE_EVENT;
84        }
85        nweb_ptr->SetPortMessageCallback(portHandle_, callback);
86        return NWebError::NO_ERROR;
87    }
88
89    std::string WebMessagePortImpl::GetPortHandle() const
90    {
91        return portHandle_;
92    }
93
94    void NWebMessageCallbackImpl::OnReceiveValue(std::shared_ptr<NWeb::NWebMessage> result)
95    {
96        WEBVIEWLOGD("message port received msg");
97        if (result == nullptr) {
98            return;
99        }
100        NWeb::NWebValue::Type type = result->GetType();
101        if (type == NWeb::NWebValue::Type::STRING) {
102            std::string msgStr = result->GetString();
103            char* message = MallocCString(msgStr);
104            RetWebMessage ret = {.messageStr = message, .messageArr = {.head = nullptr, .size = 0}};
105            callback_(ret);
106            free(message);
107        } else if (type == NWeb::NWebValue::Type::BINARY) {
108            std::vector<uint8_t> msgArr = result->GetBinary();
109            uint8_t* result = VectorToCArrUI8(msgArr);
110            if (result == nullptr) {
111                return;
112            }
113            RetWebMessage ret = {.messageStr = nullptr, .messageArr = CArrUI8{result, msgArr.size()}};
114            callback_(ret);
115            free(result);
116        }
117    }
118
119    void NWebWebMessageExtCallbackImpl::OnReceiveValue(std::shared_ptr<NWeb::NWebMessage> result)
120    {
121        WEBVIEWLOGD("message port received msg");
122        WebMessageExtImpl *webMessageExt = OHOS::FFI::FFIData::Create<WebMessageExtImpl>(result);
123        if (webMessageExt == nullptr) {
124            WEBVIEWLOGE("new WebMessageExt failed.");
125            return;
126        }
127        callback_(webMessageExt->GetID());
128    }
129
130    WebviewControllerImpl::WebviewControllerImpl(int32_t nwebId) : nwebId_(nwebId)
131    {
132        if (IsInit()) {
133            std::unique_lock<std::mutex> lk(webMtx_);
134            g_webview_controller_map.emplace(nwebId, this);
135        }
136    }
137
138    bool WebviewControllerImpl::IsInit()
139    {
140        return NWeb::NWebHelper::Instance().GetNWeb(nwebId_) ? true : false;
141    }
142
143    void WebviewControllerImpl::SetWebId(int32_t nwebId)
144    {
145        nwebId_ = nwebId;
146        std::unique_lock<std::mutex> lk(webMtx_);
147        g_webview_controller_map.emplace(nwebId, this);
148
149        if (webTag_.empty()) {
150            WEBVIEWLOGI("native webtag is empty, don't care because it's not a native instance");
151            return;
152        }
153
154        auto nweb_ptr = OHOS::NWeb::NWebHelper::Instance().GetNWeb(nwebId);
155        if (nweb_ptr) {
156            OH_NativeArkWeb_BindWebTagToWebInstance(webTag_.c_str(), nweb_ptr);
157            NWeb::NWebHelper::Instance().SetWebTag(nwebId_, webTag_.c_str());
158        }
159    }
160
161    void WebviewControllerImpl::InnerSetHapPath(const std::string &hapPath)
162    {
163        hapPath_ = hapPath;
164    }
165
166    int32_t WebviewControllerImpl::GetWebId() const
167    {
168        int32_t webId = -1;
169        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
170        if (nweb_ptr) {
171            webId = static_cast<int32_t>(nweb_ptr->GetWebId());
172        }
173        return webId;
174    }
175
176    int32_t WebviewControllerImpl::LoadUrl(std::string url)
177    {
178        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
179        if (!nweb_ptr) {
180            return NWebError::INIT_ERROR;
181        }
182        return nweb_ptr->Load(url);
183    }
184
185    int32_t WebviewControllerImpl::LoadUrl(std::string url, std::map<std::string, std::string> httpHeaders)
186    {
187        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
188        if (!nweb_ptr) {
189            return NWebError::INIT_ERROR;
190        }
191        return nweb_ptr->Load(url, httpHeaders);
192    }
193
194    ErrCode WebviewControllerImpl::LoadData(std::string data, std::string mimeType, std::string encoding,
195        std::string baseUrl, std::string historyUrl)
196    {
197        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
198        if (!nweb_ptr) {
199            return NWebError::INIT_ERROR;
200        }
201        if (baseUrl.empty() && historyUrl.empty()) {
202            return nweb_ptr->LoadWithData(data, mimeType, encoding);
203        }
204        return nweb_ptr->LoadWithDataAndBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
205    }
206
207    int32_t WebviewControllerImpl::PreFetchPage(std::string url)
208    {
209        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
210        if (!nweb_ptr) {
211            return NWebError::INIT_ERROR;
212        }
213        std::map<std::string, std::string> httpHeaders;
214        nweb_ptr->PrefetchPage(url, httpHeaders);
215        return NWebError::NO_ERROR;
216    }
217
218    int32_t WebviewControllerImpl::PreFetchPage(std::string url, std::map<std::string, std::string> httpHeaders)
219    {
220        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
221        if (!nweb_ptr) {
222            return NWebError::INIT_ERROR;
223        }
224        nweb_ptr->PrefetchPage(url, httpHeaders);
225        return NWebError::NO_ERROR;
226    }
227
228    void WebviewControllerImpl::Refresh()
229    {
230        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
231        if (nweb_ptr) {
232            nweb_ptr->Reload();
233        }
234    }
235
236    int32_t WebviewControllerImpl::SetAudioMuted(bool mute)
237    {
238        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
239        if (!nweb_ptr) {
240            return NWebError::INIT_ERROR;
241        }
242        nweb_ptr->SetAudioMuted(mute);
243        return NWebError::NO_ERROR;
244    }
245
246    std::string WebviewControllerImpl::GetUserAgent()
247    {
248        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
249        if (!nweb_ptr) {
250            return "";
251        }
252        std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
253        if (!setting) {
254            return "";
255        }
256        return setting->DefaultUserAgent();
257    }
258
259    bool WebviewControllerImpl::AccessForward()
260    {
261        bool access = false;
262        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
263        if (nweb_ptr) {
264            access = nweb_ptr->IsNavigateForwardAllowed();
265        }
266        return access;
267    }
268
269    bool WebviewControllerImpl::AccessBackward()
270    {
271        bool access = false;
272        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
273        if (nweb_ptr) {
274            access = nweb_ptr->IsNavigatebackwardAllowed();
275        }
276        return access;
277    }
278
279    int32_t WebviewControllerImpl::SetCustomUserAgent(const std::string& userAgent)
280    {
281        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
282        if (!nweb_ptr) {
283            return NWebError::INIT_ERROR;
284        }
285        std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
286        if (!setting) {
287            return NWebError::INIT_ERROR;
288        }
289        setting->PutUserAgent(userAgent);
290        return NWebError::NO_ERROR;
291    }
292
293    std::string WebviewControllerImpl::GetCustomUserAgent() const
294    {
295        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
296        if (!nweb_ptr) {
297            return "";
298        }
299        std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
300        if (!setting) {
301            return "";
302        }
303        return setting->UserAgent();
304    }
305
306    void WebviewControllerImpl::RunJavaScript(std::string script,
307        const std::function<void(RetDataCString)>& callbackRef)
308    {
309        RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
310        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
311        if (!nweb_ptr) {
312            callbackRef(ret);
313            return;
314        }
315        auto callbackImpl = std::make_shared<WebviewJavaScriptExecuteCallback>(callbackRef);
316        nweb_ptr->ExecuteJavaScript(script, callbackImpl, false);
317    }
318
319    void WebviewControllerImpl::RunJavaScriptExt(std::string script,
320        const std::function<void(RetDataI64)>& callbackRef)
321    {
322        RetDataI64 ret = { .code = NWebError::INIT_ERROR, .data = 0 };
323        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
324        if (!nweb_ptr) {
325            callbackRef(ret);
326            return;
327        }
328        auto callbackImpl = std::make_shared<WebviewJavaScriptExtExecuteCallback>(callbackRef);
329        nweb_ptr->ExecuteJavaScript(script, callbackImpl, true);
330    }
331
332    std::string WebviewControllerImpl::GetUrl()
333    {
334        std::string url = "";
335        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
336        if (nweb_ptr) {
337            url = nweb_ptr->GetUrl();
338        }
339        return url;
340    }
341
342    std::string WebviewControllerImpl::GetOriginalUrl()
343    {
344        std::string url = "";
345        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
346        if (nweb_ptr) {
347            url = nweb_ptr->GetOriginalUrl();
348        }
349        return url;
350    }
351
352    void WebviewControllerImpl::ScrollPageUp(bool top)
353    {
354        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
355        if (nweb_ptr) {
356            nweb_ptr->PageUp(top);
357        }
358        return;
359    }
360
361    void WebviewControllerImpl::ScrollPageDown(bool bottom)
362    {
363        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
364        if (nweb_ptr) {
365            nweb_ptr->PageDown(bottom);
366        }
367        return;
368    }
369
370    void WebviewControllerImpl::ScrollTo(float x, float y)
371    {
372        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
373        if (nweb_ptr) {
374            nweb_ptr->ScrollTo(x, y);
375        }
376        return;
377    }
378
379    void WebviewControllerImpl::ScrollBy(float deltaX, float deltaY)
380    {
381        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
382        if (nweb_ptr) {
383            nweb_ptr->ScrollBy(deltaX, deltaY);
384        }
385        return;
386    }
387
388    void WebviewControllerImpl::ScrollToWithAnime(float x, float y, int32_t duration)
389    {
390        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
391        if (nweb_ptr) {
392            nweb_ptr->ScrollToWithAnime(x, y, duration);
393        }
394        return;
395    }
396
397    void WebviewControllerImpl::ScrollByWithAnime(float deltaX, float deltaY, int32_t duration)
398    {
399        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
400        if (nweb_ptr) {
401            nweb_ptr->ScrollByWithAnime(deltaX, deltaY, duration);
402        }
403        return;
404    }
405
406    void WebviewControllerImpl::Forward()
407    {
408        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
409        if (nweb_ptr) {
410            nweb_ptr->NavigateForward();
411        }
412        return;
413    }
414
415    void WebviewControllerImpl::Backward()
416    {
417        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
418        if (nweb_ptr) {
419            nweb_ptr->NavigateBack();
420        }
421        return;
422    }
423
424    int32_t WebviewControllerImpl::BackOrForward(int32_t step)
425    {
426        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
427        if (!nweb_ptr) {
428            return NWebError::INIT_ERROR;
429        }
430        nweb_ptr->NavigateBackOrForward(step);
431        return NWebError::NO_ERROR;
432    }
433
434    int32_t WebviewControllerImpl::GetPageHeight()
435    {
436        int32_t pageHeight = 0;
437        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
438        if (nweb_ptr) {
439            pageHeight = nweb_ptr->ContentHeight();
440        }
441        return pageHeight;
442    }
443
444    std::string WebviewControllerImpl::GetTitle()
445    {
446        std::string title = "";
447        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
448        if (nweb_ptr) {
449            title = nweb_ptr->Title();
450        }
451        return title;
452    }
453
454    int32_t WebviewControllerImpl::Zoom(float factor)
455    {
456        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
457        if (!nweb_ptr) {
458            return NWebError::INIT_ERROR;
459        }
460        ErrCode result = NWebError::NO_ERROR;
461        result = nweb_ptr->Zoom(factor);
462
463        return result;
464    }
465
466    int32_t WebviewControllerImpl::ZoomIn()
467    {
468        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
469        if (!nweb_ptr) {
470            return NWebError::INIT_ERROR;
471        }
472        ErrCode result = NWebError::NO_ERROR;
473        result = nweb_ptr->ZoomIn();
474
475        return result;
476    }
477
478    int32_t WebviewControllerImpl::ZoomOut()
479    {
480        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
481        if (!nweb_ptr) {
482            return NWebError::INIT_ERROR;
483        }
484        ErrCode result = NWebError::NO_ERROR;
485        result = nweb_ptr->ZoomOut();
486
487        return result;
488    }
489
490    int32_t WebviewControllerImpl::RequestFocus()
491    {
492        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
493        if (!nweb_ptr) {
494            return NWebError::INIT_ERROR;
495        }
496        nweb_ptr->OnFocus();
497        ErrCode result = NWebError::NO_ERROR;
498        return result;
499    }
500
501    void WebviewControllerImpl::ClearHistory()
502    {
503        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
504        if (nweb_ptr) {
505            nweb_ptr->DeleteNavigateHistory();
506        }
507    }
508
509    bool WebviewControllerImpl::AccessStep(int32_t step)
510    {
511        bool access = false;
512        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
513        if (nweb_ptr) {
514            access = nweb_ptr->CanNavigateBackOrForward(step);
515        }
516        return access;
517    }
518
519    void WebviewControllerImpl::OnActive()
520    {
521        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
522        if (nweb_ptr) {
523            WEBVIEWLOGD("WebviewControllerImpl::OnActive start")
524            nweb_ptr->OnContinue();
525        }
526    }
527
528    void WebviewControllerImpl::OnInactive()
529    {
530        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
531        if (nweb_ptr) {
532            WEBVIEWLOGD("WebviewControllerImpl::OnInactive start")
533            nweb_ptr->OnPause();
534        }
535    }
536
537    int WebviewControllerImpl::GetHitTest()
538    {
539        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
540        if (nweb_ptr) {
541            return ConverToWebHitTestType(nweb_ptr->GetHitTestResult()->GetType());
542        }
543        return static_cast<int>(WebHitTestType::UNKNOWN);
544    }
545
546    std::shared_ptr<NWeb::HitTestResult> WebviewControllerImpl::GetHitTestValue()
547    {
548        std::shared_ptr<NWeb::HitTestResult> nwebResult;
549        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
550        if (nweb_ptr) {
551            nwebResult = nweb_ptr->GetHitTestResult();
552            if (nwebResult) {
553                nwebResult->SetType(ConverToWebHitTestType(nwebResult->GetType()));
554            }
555        }
556        return nwebResult;
557    }
558
559    int WebviewControllerImpl::ConverToWebHitTestType(int hitType)
560    {
561        WebHitTestType webHitType;
562        switch (hitType) {
563            case NWeb::HitTestResult::UNKNOWN_TYPE:
564                webHitType = WebHitTestType::UNKNOWN;
565                break;
566            case NWeb::HitTestResult::ANCHOR_TYPE:
567                webHitType = WebHitTestType::HTTP;
568                break;
569            case NWeb::HitTestResult::PHONE_TYPE:
570                webHitType = WebHitTestType::PHONE;
571                break;
572            case NWeb::HitTestResult::GEO_TYPE:
573                webHitType = WebHitTestType::MAP;
574                break;
575            case NWeb::HitTestResult::EMAIL_TYPE:
576                webHitType = WebHitTestType::EMAIL;
577                break;
578            case NWeb::HitTestResult::IMAGE_TYPE:
579                webHitType = WebHitTestType::IMG;
580                break;
581            case NWeb::HitTestResult::IMAGE_ANCHOR_TYPE:
582                webHitType = WebHitTestType::HTTP_IMG;
583                break;
584            case NWeb::HitTestResult::SRC_ANCHOR_TYPE:
585                webHitType = WebHitTestType::HTTP;
586                break;
587            case NWeb::HitTestResult::SRC_IMAGE_ANCHOR_TYPE:
588                webHitType = WebHitTestType::HTTP_IMG;
589                break;
590            case NWeb::HitTestResult::EDIT_TEXT_TYPE:
591                webHitType = WebHitTestType::EDIT;
592                break;
593            default:
594                webHitType = WebHitTestType::UNKNOWN;
595                break;
596        }
597        return static_cast<int>(webHitType);
598    }
599
600    void WebviewControllerImpl::StoreWebArchiveCallback(std::string baseName, bool autoName,
601        const std::function<void(RetDataCString)>& callbackRef)
602    {
603        RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
604        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
605        if (!nweb_ptr) {
606            callbackRef(ret);
607            return;
608        }
609        auto callbackImpl = std::make_shared<NWeb::NWebStoreWebArchiveCallback>();
610        callbackImpl->SetCallBack([cjCallback = callbackRef](std::string result) {
611            RetDataCString ret = { .code = NWebError::INVALID_RESOURCE, .data = nullptr };
612            if (result.empty()) {
613                cjCallback(ret);
614                return;
615            }
616            ret.code = NWebError::NO_ERROR;
617            ret.data = MallocCString(result);
618            if (ret.data == nullptr) {
619                ret.code = NWebError::NEW_OOM;
620            }
621            cjCallback(ret);
622        });
623        nweb_ptr->StoreWebArchive(baseName, autoName, callbackImpl);
624        return;
625    }
626
627    void WebviewControllerImpl::EnableSafeBrowsing(bool enable)
628    {
629        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
630        if (nweb_ptr) {
631            nweb_ptr->EnableSafeBrowsing(enable);
632        }
633        return;
634    }
635
636    bool WebviewControllerImpl::IsSafeBrowsingEnabled()
637    {
638        bool is_safe_browsing_enabled = false;
639        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
640        if (nweb_ptr) {
641            is_safe_browsing_enabled = nweb_ptr->IsSafeBrowsingEnabled();
642        }
643        return is_safe_browsing_enabled;
644    }
645
646    int WebviewControllerImpl::GetSecurityLevel()
647    {
648        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
649        if (!nweb_ptr) {
650            return static_cast<int>(SecurityLevel::NONE);
651        }
652
653        int nwebSecurityLevel = nweb_ptr->GetSecurityLevel();
654        SecurityLevel securityLevel;
655        switch (nwebSecurityLevel) {
656            case static_cast<int>(CoreSecurityLevel::NONE):
657                securityLevel = SecurityLevel::NONE;
658                break;
659            case static_cast<int>(CoreSecurityLevel::SECURE):
660                securityLevel = SecurityLevel::SECURE;
661                break;
662            case static_cast<int>(CoreSecurityLevel::WARNING):
663                securityLevel = SecurityLevel::WARNING;
664                break;
665            case static_cast<int>(CoreSecurityLevel::DANGEROUS):
666                securityLevel = SecurityLevel::DANGEROUS;
667                break;
668            default:
669                securityLevel = SecurityLevel::NONE;
670                break;
671        }
672
673        return static_cast<int>(securityLevel);
674    }
675
676    bool WebviewControllerImpl::IsIncognitoMode()
677    {
678        bool incognitoMode = false;
679        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
680        if (nweb_ptr) {
681            incognitoMode = nweb_ptr->IsIncognitoMode();
682        }
683        return incognitoMode;
684    }
685
686    void WebviewControllerImpl::RemoveCache(bool includeDiskFiles)
687    {
688        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
689        if (nweb_ptr) {
690            WEBVIEWLOGD("WebviewControllerImpl::RemoveCache start")
691            nweb_ptr->RemoveCache(includeDiskFiles);
692        }
693    }
694
695    std::shared_ptr<OHOS::NWeb::NWebHistoryList> WebviewControllerImpl::GetHistoryList()
696    {
697        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
698        if (!nweb_ptr) {
699            return nullptr;
700        }
701        return nweb_ptr->GetHistoryList();
702    }
703
704    bool WebviewControllerImpl::GetFavicon(const void **data, size_t &width, size_t &height,
705        NWeb::ImageColorType &colorType, NWeb::ImageAlphaType &alphaType) const
706    {
707        bool isGetFavicon = false;
708        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
709        if (nweb_ptr) {
710            isGetFavicon = nweb_ptr->GetFavicon(data, width, height, colorType, alphaType);
711        }
712        return isGetFavicon;
713    }
714
715    int32_t WebHistoryListImpl::GetListSize()
716    {
717        int32_t listSize = 0;
718
719        if (!sptrHistoryList_) {
720            return listSize;
721        }
722        listSize = sptrHistoryList_->GetListSize();
723        return listSize;
724    }
725
726    int32_t WebHistoryListImpl::GetCurrentIndex()
727    {
728        int32_t currentIndex = 0;
729
730        if (!sptrHistoryList_) {
731            return currentIndex;
732        }
733        currentIndex = sptrHistoryList_->GetCurrentIndex();
734        return currentIndex;
735    }
736
737    std::shared_ptr<OHOS::NWeb::NWebHistoryItem> WebHistoryListImpl::GetItem(int32_t index)
738    {
739        if (!sptrHistoryList_) {
740            return nullptr;
741        }
742        return sptrHistoryList_->GetItem(index);
743    }
744
745    void WebviewControllerImpl::SetNWebJavaScriptResultCallBack()
746    {
747        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
748        if (!nweb_ptr) {
749            return;
750        }
751        if (javaScriptResultCb_ && (javaScriptResultCb_->GetNWebId() == nwebId_)) {
752            return;
753        }
754
755        javaScriptResultCb_ = std::make_shared<WebviewJavaScriptResultCallBackImpl>(nwebId_);
756        nweb_ptr->SetNWebJavaScriptResultCallBack(javaScriptResultCb_);
757    }
758
759    void WebviewControllerImpl::RegisterJavaScriptProxy(const std::vector<std::function<char*(const char*)>>& cjFuncs,
760        const std::string& objName, const std::vector<std::string>& methodList)
761    {
762        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
763        if (!nweb_ptr) {
764            WEBVIEWLOGE("WebviewControllerImpl::RegisterJavaScriptProxy nweb_ptr is null");
765            return;
766        }
767        JavaScriptOb::ObjectID objId =
768            static_cast<JavaScriptOb::ObjectID>(JavaScriptOb::JavaScriptObjIdErrorCode::WEBCONTROLLERERROR);
769
770        if (!javaScriptResultCb_) {
771            WEBVIEWLOGE("WebviewControllerImpl::RegisterJavaScriptProxy javaScriptResultCb_ is null");
772            return;
773        }
774
775        if (methodList.empty()) {
776            WEBVIEWLOGE("WebviewControllerImpl::RegisterJavaScriptProxy methodList is empty");
777            return;
778        }
779
780        objId = javaScriptResultCb_->RegisterJavaScriptProxy(cjFuncs, objName, methodList);
781
782        nweb_ptr->RegisterArkJSfunction(objName, methodList, objId);
783    }
784
785    void WebviewControllerImpl::Stop()
786    {
787        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
788        if (nweb_ptr) {
789            return nweb_ptr->Stop();
790        }
791        return;
792    }
793
794    void WebviewControllerImpl::SetBackForwardCacheOptions(int32_t size, int32_t timeToLive)
795    {
796        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
797        if (!nweb_ptr) {
798            WEBVIEWLOGE("WebviewControllerImpl::void SetBackForwardCacheOptions nweb_ptr is null");
799            return;
800        }
801        nweb_ptr->SetBackForwardCacheOptions(size, timeToLive);
802    }
803
804    void WebviewControllerImpl::SlideScroll(float vx, float vy)
805    {
806        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
807        if (nweb_ptr) {
808            return nweb_ptr->SlideScroll(vx, vy);
809        }
810        return;
811    }
812
813    void WebviewControllerImpl::PutNetworkAvailable(bool enable)
814    {
815        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
816        if (nweb_ptr) {
817            return nweb_ptr->PutNetworkAvailable(enable);
818        }
819        return;
820    }
821
822    void WebviewControllerImpl::ClearClientAuthenticationCache()
823    {
824        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
825        if (nweb_ptr) {
826            return nweb_ptr->ClearClientAuthenticationCache();
827        }
828        return;
829    }
830
831    void WebviewControllerImpl::ClearSslCache()
832    {
833        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
834        if (nweb_ptr) {
835            return nweb_ptr->ClearSslCache();
836        }
837        return;
838    }
839
840    void WebviewControllerImpl::SearchNext(bool forward)
841    {
842        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
843        if (nweb_ptr) {
844            return nweb_ptr->FindNext(forward);
845        }
846        return;
847    }
848
849    void WebviewControllerImpl::ClearMatches()
850    {
851        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
852        if (nweb_ptr) {
853            return nweb_ptr->ClearMatches();
854        }
855        return;
856    }
857
858    void WebviewControllerImpl::SearchAllAsync(std::string str)
859    {
860        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
861        if (nweb_ptr) {
862            return nweb_ptr->FindAllAsync(str);
863        }
864        return;
865    }
866
867    ErrCode WebviewControllerImpl::DeleteJavaScriptRegister(const std::string& objName,
868        const std::vector<std::string>& methodList)
869    {
870        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
871        if (nweb_ptr) {
872            nweb_ptr->UnregisterArkJSfunction(objName, methodList);
873        }
874        if (javaScriptResultCb_) {
875            bool ret = javaScriptResultCb_->DeleteJavaScriptRegister(objName);
876            if (!ret) {
877                return NWebError::CANNOT_DEL_JAVA_SCRIPT_PROXY;
878            }
879        }
880        return NWebError::NO_ERROR;
881    }
882
883    int32_t WebviewControllerImpl::PostUrl(std::string& url, std::vector<char>& postData)
884    {
885        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
886        if (!nweb_ptr) {
887            return NWebError::INIT_ERROR;
888        }
889        return nweb_ptr->PostUrl(url, postData);
890    }
891
892    std::vector<std::string> WebviewControllerImpl::CreateWebMessagePorts()
893    {
894        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
895        if (!nweb_ptr) {
896            std::vector<std::string> empty;
897            return empty;
898        }
899        return nweb_ptr->CreateWebMessagePorts();
900    }
901
902    ErrCode WebviewControllerImpl::PostWebMessage(std::string& message,
903        std::vector<std::string>& ports, std::string& targetUrl)
904    {
905        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
906        if (!nweb_ptr) {
907            return NWebError::INIT_ERROR;
908        }
909
910        nweb_ptr->PostWebMessage(message, ports, targetUrl);
911        return NWebError::NO_ERROR;
912    }
913
914    std::vector<uint8_t> WebviewControllerImpl::SerializeWebState()
915    {
916        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
917        if (nweb_ptr) {
918            return nweb_ptr->SerializeWebState();
919        }
920        std::vector<uint8_t> empty;
921        return empty;
922    }
923
924    bool WebviewControllerImpl::RestoreWebState(const std::vector<uint8_t> &state) const
925    {
926        bool isRestored = false;
927        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
928        if (nweb_ptr) {
929            isRestored = nweb_ptr->RestoreWebState(state);
930        }
931        return isRestored;
932    }
933
934    bool WebviewControllerImpl::GetCertChainDerData(std::vector<std::string> &certChainDerData) const
935    {
936        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
937        if (!nweb_ptr) {
938            WEBVIEWLOGE("GetCertChainDerData failed, nweb ptr is null");
939            return false;
940        }
941
942        return nweb_ptr->GetCertChainDerData(certChainDerData, true);
943    }
944
945    ErrCode WebviewControllerImpl::HasImagesCallback(const std::function<void(RetDataBool)>& callbackRef)
946    {
947        auto nweb_ptr = NWeb::NWebHelper::Instance().GetNWeb(nwebId_);
948        if (!nweb_ptr) {
949            return NWebError::INIT_ERROR;
950        }
951        if (callbackRef == nullptr) {
952            return NWebError::PARAM_CHECK_ERROR;
953        }
954        auto callbackImpl = std::make_shared<WebviewHasImageCallback>(callbackRef);
955        nweb_ptr->HasImages(callbackImpl);
956        return NWebError::NO_ERROR;
957    }
958
959    bool CheckSchemeName(const std::string& schemeName)
960    {
961        if (schemeName.empty() || schemeName.size() > MAX_CUSTOM_SCHEME_NAME_LENGTH) {
962            WEBVIEWLOGE("Invalid scheme name length");
963            return false;
964        }
965        for (auto it = schemeName.begin(); it != schemeName.end(); it++) {
966            char chr = *it;
967            if (!((chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9') ||
968                (chr == '.') || (chr == '+') || (chr == '-'))) {
969                WEBVIEWLOGE("invalid character %{public}c", chr);
970                return false;
971            }
972        }
973        return true;
974    }
975
976    void SetCustomizeSchemeOption(Scheme& scheme)
977    {
978        std::map<int, std::function<bool(const Scheme&)>> schemeProperties = {
979            {0, [](const Scheme& scheme) { return scheme.isStandard; }},
980            {1, [](const Scheme& scheme) { return scheme.isLocal; }},
981            {2, [](const Scheme& scheme) { return scheme.isDisplayIsolated; }},
982            {3, [](const Scheme& scheme) { return scheme.isSecure; }},
983            {4, [](const Scheme& scheme) { return scheme.isSupportCORS; }},
984            {5, [](const Scheme& scheme) { return scheme.isCspBypassing; }},
985            {6, [](const Scheme& scheme) { return scheme.isSupportFetch; }},
986            {7, [](const Scheme& scheme) { return scheme.isCodeCacheSupported; }}
987        };
988
989        for (const auto& property : schemeProperties) {
990            if (property.second(scheme)) {
991                scheme.option += 1 << property.first;
992            }
993        }
994    }
995
996    bool SetCustomizeScheme(CScheme cscheme, Scheme& scheme)
997    {
998        scheme.isSupportCORS = cscheme.isSupportCORS;
999        scheme.isSupportFetch = cscheme.isSupportFetch;
1000        scheme.isStandard = cscheme.isStandard;
1001        scheme.isLocal = cscheme.isLocal;
1002        scheme.isDisplayIsolated = cscheme.isDisplayIsolated;
1003        scheme.isSecure = cscheme.isSecure;
1004        scheme.isCspBypassing = cscheme.isCspBypassing;
1005        scheme.isCodeCacheSupported = cscheme.isCodeCacheSupported;
1006        scheme.name = std::string(cscheme.name);
1007        if (!CheckSchemeName(scheme.name)) {
1008            return false;
1009        }
1010        SetCustomizeSchemeOption(scheme);
1011        return true;
1012    }
1013
1014    int32_t WebviewControllerImpl::CustomizeSchemesArrayDataHandler(CArrScheme schemes)
1015    {
1016        int64_t arrayLength = schemes.size;
1017        if (arrayLength > MAX_CUSTOM_SCHEME_SIZE) {
1018            return NWebError::PARAM_CHECK_ERROR;
1019        }
1020        std::vector<Scheme> schemeVector;
1021        for (int64_t i = 0; i < arrayLength; ++i) {
1022            Scheme scheme;
1023            bool result = SetCustomizeScheme(schemes.cScheme[i], scheme);
1024            if (!result) {
1025                return NWebError::PARAM_CHECK_ERROR;
1026            }
1027            schemeVector.push_back(scheme);
1028        }
1029        int32_t registerResult;
1030        for (auto it = schemeVector.begin(); it != schemeVector.end(); ++it) {
1031            registerResult = OH_ArkWeb_RegisterCustomSchemes(it->name.c_str(), it->option);
1032            if (registerResult != NO_ERROR) {
1033                return registerResult;
1034            }
1035        }
1036        return NWebError::NO_ERROR;
1037    }
1038}
1039