* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NWEB_WEBVIEW_CONTROLLER_H
#define NWEB_WEBVIEW_CONTROLLER_H
#include <filesystem>
#include <memory>
#include <string>
#include <unordered_map>
#include "auto_napi_ref.h"
#include "napi/native_api.h"
#include "napi/native_common.h"
#include "napi/native_node_api.h"
#include "nweb.h"
#include "nweb_helper.h"
#include "nweb_snapshot_callback.h"
#include "nweb_web_message.h"
#include "web_errors.h"
#include "webview_javascript_result_callback.h"
#include "webview_controller_print_structs.h"
#include "web_scheme_handler.h"
#include "webview_value.h"
namespace OHOS {
namespace NWeb {
enum class WebHitTestType : int {
EDIT = 0,
EMAIL,
HTTP,
HTTP_IMG,
IMG,
MAP,
PHONE,
UNKNOWN
};
enum class SecureDnsModeType : int {
OFF = 0,
AUTO,
SECURE_ONLY
};
enum class ResourceType : uint32_t {
COLOR = 10001,
FLOAT,
STRING,
PLURAL,
BOOLEAN,
INTARRAY,
INTEGER,
PATTERN,
STRARRAY,
MEDIA = 20000,
RAWFILE = 30000
};
enum class WebMessageType : int {
NOTSUPPORT = 0,
STRING,
NUMBER,
BOOLEAN,
ARRAYBUFFER,
ARRAY,
ERROR
};
enum class MediaPlaybackState : int {
NONE = 0,
PLAYING,
PAUSED,
STOP
};
enum class SecurityLevel : int {
NONE = 0,
SECURE,
WARNING,
DANGEROUS
};
enum class CoreSecurityLevel : int {
NONE = 0,
SECURE = 3,
WARNING = 6,
DANGEROUS = 5
};
enum class OfflineResourceType : int {
IMAGE = 0,
CSS,
CLASSIC_JS,
MODULE_JS
};
enum class ParseURLResult : int {
OK = 0,
FAILED,
INVALID_URL
};
enum class UrlListSetResult : int {
INIT_ERROR = -2,
PARAM_ERROR = -1,
SET_OK = 0,
};
enum class ScrollType : int {
EVENT = 0,
};
enum class PressureLevel : int {
MEMORY_PRESSURE_LEVEL_MODERATE = 1,
MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
};
enum class AttachState : int {
NOT_ATTACHED = 0,
ATTACHED = 1
};
enum class BlanklessErrorCode : int {
SUCCESS = 0,
ERR_UNKNOWN = -1,
ERR_INVALID_PARAM = -2,
ERR_CONTROLLER_NOT_INITED = -3,
ERR_KEY_NOT_MATCH = -4,
ERR_SIGNIFICANT_CHANGE = -5,
ERR_DURATION_OUT_OF_RANGE = -6,
ERR_EXPIRATION_TIME_OUT_OF_RANGE = -7
};
enum class BlanklessFrameInterpolationState : int {
FRAME_INTERPOLATION_SUCCEEDED = 0,
FRAME_INTERPOLATION_FAILED = 1,
FRAME_INTERPOLATION_REMOVED = 2
};
struct BlanklessLoadingParamValue {
bool enable = false;
int32_t duration = 0;
int64_t expirationTime = 0;
napi_ref callback = nullptr;
};
class WebRegObj {
public:
WebRegObj() : m_regEnv(0), m_regHanderRef(nullptr) {
}
explicit WebRegObj(const napi_env& env, const napi_ref& ref)
{
m_regEnv = env;
m_regHanderRef = ref;
m_isMarked = false;
}
~WebRegObj() {
}
napi_env m_regEnv;
napi_ref m_regHanderRef;
bool m_isMarked;
};
class WebPrintDocument;
class WebviewController {
public:
explicit WebviewController() = default;
explicit WebviewController(int32_t nwebId);
explicit WebviewController(const std::string& webTag);
~WebviewController();
bool IsInit() const;
void SetWebId(int32_t nwebId);
WebviewController* FromID(int32_t nwebId);
bool AccessForward() const;
bool AccessBackward() const;
bool AccessStep(int32_t step) const;
void ClearHistory();
void Forward();
void Backward();
void OnActive();
void OnInactive();
void Refresh();
void ReloadIgnoreCache();
ErrCode ZoomIn();
ErrCode ZoomOut();
int32_t GetWebId() const;
std::string GetUserAgent();
std::string GetCustomUserAgent() const;
ErrCode SetCustomUserAgent(const std::string& userAgent);
std::string GetTitle();
int32_t GetProgress();
int32_t GetPageHeight();
ErrCode BackOrForward(int32_t step);
void StoreWebArchiveCallback(const std::string &baseName, bool autoName, napi_env env, napi_ref jsCallback);
void StoreWebArchivePromise(const std::string &baseName, bool autoName, napi_env env, napi_deferred deferred);
std::vector<std::string> CreateWebMessagePorts();
ErrCode PostWebMessage(std::string& message, std::vector<std::string>& ports, std::string& targetUrl);
std::shared_ptr<HitTestResult> GetHitTestValue();
void RequestFocus();
bool ParseUrl(napi_env env, napi_value urlObj, std::string& result) const;
ErrCode LoadUrl(std::string url);
ErrCode LoadUrl(std::string url, std::map<std::string, std::string> httpHeaders);
ErrCode LoadData(std::string data, std::string mimeType, std::string encoding,
std::string baseUrl, std::string historyUrl);
int GetHitTest();
void ClearMatches();
void SearchNext(bool forward);
void SearchAllAsync(const std::string& searchString);
void ClearSslCache();
void ClearClientAuthenticationCache();
void Stop();
ErrCode Zoom(float factor);
void InnerCompleteWindowNew(int32_t parentNwebId);
void SetNWebJavaScriptResultCallBack();
void RegisterJavaScriptProxy(RegisterJavaScriptProxyParam& param);
ErrCode DeleteJavaScriptRegister(const std::string& objName,
const std::vector<std::string>& methodList);
void RunJavaScriptCallback(const std::string &script, napi_env env, napi_ref jsCallback, bool extention);
void RunJavaScriptPromise(const std::string &script, napi_env env, napi_deferred deferred, bool extention);
void ExecuteAIPageCommand(const std::string& command, napi_env env, napi_deferred deferred);
void RunJavaScriptCallbackExt(
const int fd, const size_t scriptLength, napi_env env, napi_ref jsCallback, bool extention);
void RunJavaScriptPromiseExt(
const int fd, const size_t scriptLength, napi_env env, napi_deferred deferred, bool extention);
std::string GetUrl();
std::string GetOriginalUrl();
bool TerminateRenderProcess() const;
void PutNetworkAvailable(bool available);
bool HasImage(std::shared_ptr<NWebBoolValueCallback> callback);
ErrCode HasImagesCallback(napi_env env, napi_ref jsCallback);
ErrCode HasImagesPromise(napi_env env, napi_deferred deferred);
void RemoveCache(bool includeDiskFiles);
std::shared_ptr<NWebHistoryList> GetHistoryList();
bool GetFavicon(
const void **data, size_t &width, size_t &height, ImageColorType &colorType, ImageAlphaType &alphaType) const;
std::vector<uint8_t> SerializeWebState();
bool RestoreWebState(const std::vector<uint8_t> &state) const;
void ScrollPageDown(bool bottom);
void ScrollPageUp(bool top);
void ScrollTo(float x, float y);
void ScrollBy(float deltaX, float deltaY);
void SlideScroll(float vx, float vy);
void SetScrollable(bool enable);
void SetScrollable(bool enable, int32_t scrollType);
bool GetScrollable() const;
void InnerSetHapPath(const std::string &hapPath);
void InnerSetFavicon(napi_env env, napi_value favicon);
napi_value InnerGetFavicon(napi_env env);
bool GetCertChainDerData(std::vector<std::string> &certChainDerData) const;
ErrCode SetAudioMuted(bool muted);
ErrCode PrefetchPage(std::string& url, std::map<std::string, std::string> additionalHttpHeaders);
ErrCode PrefetchPage(std::string& url, std::map<std::string, std::string> additionalHttpHeaders,
std::shared_ptr<NWebPrefetchOptions> prefetchOptions);
void* CreateWebPrintDocumentAdapter(const std::string &jobName);
ErrCode PostUrl(std::string& url, std::vector<char>& postData);
void EnableSafeBrowsing(bool enable);
bool IsSafeBrowsingEnabled() const;
int GetSecurityLevel();
bool IsIncognitoMode() const;
void SetPrintBackground(bool enable);
bool GetPrintBackground() const;
static std::string GenerateWebTag();
bool SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) const;
int32_t ClearWebSchemeHandler();
static bool SetWebServiveWorkerSchemeHandler(
const char* scheme, WebSchemeHandler* handler);
static int32_t ClearWebServiceWorkerSchemeHandler();
std::string GetLastJavascriptProxyCallingFrameUrl();
void EnableIntelligentTrackingPrevention(bool enable);
bool IsIntelligentTrackingPreventionEnabled() const;
ErrCode StartCamera();
ErrCode StopCamera();
ErrCode CloseCamera();
ErrCode ResumeMicrophone();
ErrCode StopMicrophone();
ErrCode PauseMicrophone();
void CloseAllMediaPresentations();
void StopAllMedia();
void ResumeAllMedia();
void PauseAllMedia();
int GetMediaPlaybackState();
void OnCreateNativeMediaPlayer(napi_env env, napi_ref callback);
bool ParseScriptContent(napi_env env, napi_value value, std::string &script);
std::shared_ptr<CacheOptions> ParseCacheOptions(napi_env env, napi_value value);
void PrecompileJavaScriptPromise(napi_env env,
napi_deferred deferred,
const std::string &url, const std::string &script,
std::shared_ptr<CacheOptions> cacheOptions);
bool ParseResponseHeaders(napi_env env,
napi_value value,
std::map<std::string, std::string> &responseHeaders) const;
ParseURLResult ParseURLList(napi_env env, napi_value value, std::vector<std::string>& urlList);
bool CheckURL(std::string& url) const;
std::vector<uint8_t> ParseUint8Array(napi_env env, napi_value value);
void InjectOfflineResource(const std::vector<std::string>& urlList,
const std::vector<uint8_t>& resource,
const std::map<std::string, std::string>& response_headers,
const uint32_t type);
ErrCode SetUrlTrustList(const std::string& urlTrustList, std::string& detailErrMsg);
ErrCode SetUrlTrustList(const std::string& urlTrustList,
bool allowOpaqueOrigin, bool supportWildcard, std::string& detailErrMsg);
std::string GetSurfaceId();
void EnableAdsBlock(bool enable);
bool IsAdsBlockEnabled() const;
bool IsAdsBlockEnabledForCurPage() const;
bool ParseJsLengthToInt(napi_env env,
napi_value jsLength,
PixelUnit& type,
int32_t& result) const;
ErrCode WebPageSnapshot(const char* id,
PixelUnit type,
int32_t width,
int32_t height,
const WebSnapshotCallback callback);
void UpdateInstanceId(int32_t newId);
void SetBackForwardCacheOptions(int32_t size, int32_t timeToLive);
void SetPathAllowingUniversalAccess(const std::vector<std::string>& pathList,
std::string& errorPath);
bool ScrollByWithResult(float deltaX, float deltaY) const;
void ScrollToWithAnime(float x, float y, int32_t duration) ;
void ScrollByWithAnime(float deltaX, float deltaY, int32_t duration) ;
void GetScrollOffset(float* offset_x, float* offset_y);
void GetPageOffset(float* offset_x, float* offset_y);
void CreatePDFCallbackExt(
napi_env env, std::shared_ptr<NWebPDFConfigArgs> pdfConfig, napi_ref pdfCallback);
void CreatePDFPromiseExt(
napi_env env, std::shared_ptr<NWebPDFConfigArgs> pdfConfig, napi_deferred deferred);
std::shared_ptr<HitTestResult> GetLastHitTest();
void SaveWebSchemeHandler(const char* scheme, WebSchemeHandler* handler);
static void SaveWebServiceWorkerSchemeHandler(const char* scheme, WebSchemeHandler* handler);
int GetAttachState();
void RegisterStateChangeCallback(
const napi_env& env, const std::string& type, napi_value handler);
void TriggerStateChangeCallback(const std::string& type);
void DeleteRegisterObj(
const napi_env& env, std::vector<WebRegObj>& vecRegObjs, napi_value& handler);
void DeleteAllRegisterObj(const napi_env& env, std::vector<WebRegObj>& vecRegObjs);
void UnregisterStateChangeCallback(
const napi_env& env, const std::string& type, napi_value handler);
static void WaitForAttached(napi_env env, void* data);
static void TriggerWaitforAttachedPromise(napi_env env, napi_status status, void *data);
napi_value WaitForAttachedPromise(napi_env env, int32_t timeout, napi_deferred deferred);
int32_t GetBlanklessInfoWithKey(const std::string& key, double* similarity, int32_t* loadingTime);
int32_t SetBlanklessLoadingWithKey(const std::string& key, bool isStart);
int32_t SetBlanklessLoadingParams(napi_env env, const std::string& key, BlanklessLoadingParamValue& paramsValue);
void SetWebDetach(int32_t nwebId);
void SetSoftKeyboardBehaviorMode(WebSoftKeyboardBehaviorMode mode);
ErrCode AvoidVisibleViewportBottom(int32_t avoidHeight);
ErrCode SetErrorPageEnabled(bool enable);
bool GetErrorPageEnabled();
void SetUserAgentMetadata(const std::string& userAgent, std::shared_ptr<NWebUserAgentMetadata> metaData);
std::shared_ptr<NWebUserAgentMetadata> GetUserAgentMetadata(const std::string& userAgent);
std::string GetLastPostMessageURL();
private:
int ConverToWebHitTestType(int hitType);
bool GetRawFileUrl(const std::string &fileName,
const std::string& bundleName, const std::string& moduleName, std::string &result) const;
bool ParseRawFileUrl(napi_env env, napi_value urlObj, std::string& result) const;
bool GetResourceUrl(napi_env env, napi_value urlObj, std::string& result) const;
bool ParseJsLengthResourceToInt(napi_env env,
napi_value jsLength,
PixelUnit& type,
int32_t& result) const;
bool GetHapModuleInfo();
void DeleteWebSchemeHandler();
static void DeleteWebServiceWorkerSchemeHandler();
public:
static std::string customeSchemeCmdLine_;
static bool existNweb_;
static bool webDebuggingAccess_;
static int32_t webDebuggingPort_;
static std::set<std::string> webTagSet_;
static int32_t webTagStrId_;
private:
std::mutex webMtx_;
int32_t nwebId_ = -1;
std::shared_ptr<WebviewJavaScriptResultCallBack> javaScriptResultCb_ = nullptr;
std::string hapPath_ = "";
std::string webTag_ = "";
AutoNapiRef favicon_;
std::vector<std::string> moduleName_;
std::map<std::string, WebSchemeHandler*> webSchemeHandlerMap_;
static std::map<std::string, WebSchemeHandler*> webServiceWorkerSchemeHandlerMap_;
AttachState attachState_ = AttachState::NOT_ATTACHED;
std::unordered_map<std::string, std::vector<WebRegObj>> attachEventRegisterInfo_;
std::condition_variable attachCond_;
std::mutex attachMtx_;
};
class WebMessageExt {
public:
explicit WebMessageExt(std::shared_ptr<NWebMessage> data,
std::shared_ptr<NWebRomValue> value = nullptr)
: data_(data), value_(value) {}
~WebMessageExt() = default;
void SetType(int type);
int ConvertNwebType2JsType(NWebValue::Type type);
int GetType()
{
if (data_) {
return ConvertNwebType2JsType(data_->GetType());
}
return static_cast<int>(WebMessageType::NOTSUPPORT);
}
void SetString(std::string value)
{
if (data_) {
data_->SetType(NWebValue::Type::STRING);
data_->SetString(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::STRING);
value_->SetString(value);
}
}
void SetNumber(double value)
{
if (data_) {
data_->SetType(NWebValue::Type::DOUBLE);
data_->SetDouble(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::DOUBLE);
value_->SetDouble(value);
}
}
void SetBoolean(bool value)
{
if (data_) {
data_->SetType(NWebValue::Type::BOOLEAN);
data_->SetBoolean(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::BOOLEAN);
value_->SetBool(value);
}
}
void SetArrayBuffer(std::vector<uint8_t>& value)
{
if (data_) {
data_->SetType(NWebValue::Type::BINARY);
data_->SetBinary(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::BINARY);
value_->SetBinary(value);
}
}
void SetStringArray(std::vector<std::string> value)
{
if (data_) {
data_->SetType(NWebValue::Type::STRINGARRAY);
data_->SetStringArray(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::STRINGARRAY);
value_->SetStringArray(value);
}
}
void SetDoubleArray(std::vector<double> value)
{
if (data_) {
data_->SetType(NWebValue::Type::DOUBLEARRAY);
data_->SetDoubleArray(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::DOUBLEARRAY);
value_->SetDoubleArray(value);
}
}
void SetInt64Array(std::vector<int64_t> value)
{
if (data_) {
data_->SetType(NWebValue::Type::INT64ARRAY);
data_->SetInt64Array(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::INT64ARRAY);
value_->SetInt64Array(value);
}
}
void SetBooleanArray(std::vector<bool> value)
{
if (data_) {
data_->SetType(NWebValue::Type::BOOLEANARRAY);
data_->SetBooleanArray(value);
}
if (value_) {
value_->SetType(NWebRomValue::Type::BOOLEANARRAY);
value_->SetBoolArray(value);
}
}
void SetError(std::string name, std::string message)
{
if (data_) {
data_->SetType(NWebValue::Type::ERROR);
data_->SetErrName(name);
data_->SetErrMsg(message);
}
if (value_) {
value_->SetType(NWebRomValue::Type::ERROR);
value_->SetErrName(name);
value_->SetErrMsg(message);
}
}
std::shared_ptr<NWebMessage> GetData() const
{
return data_;
}
std::shared_ptr<NWebRomValue> GetValue() const
{
return value_;
}
private:
int type_ = 0;
std::shared_ptr<NWebMessage> data_;
std::shared_ptr<NWebRomValue> value_;
};
}
}
#endif