* Copyright (c) 2022 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.
*/
#include "webview_controller.h"
#include <memory>
#include <unordered_map>
#include <securec.h>
#include <regex>
#include "application_context.h"
#include "ani_business_error.h"
#include "business_error.h"
#include "napi_parse_utils.h"
#include "ohos_resource_adapter_impl.h"
#include "native_arkweb_utils.h"
#include "native_interface_arkweb.h"
#include "nweb_log.h"
#include "nweb_store_web_archive_callback.h"
#include "web_errors.h"
#include "webview_hasimage_callback.h"
#include "webview_javascript_result_callback.h"
#include "native_media_player_impl.h"
#include "nweb_precompile_callback.h"
#include "nweb_cache_options_impl.h"
#include "bundle_mgr_proxy.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "parameters.h"
#include "system_ability_definition.h"
#include "nweb_snapshot_callback_impl.h"
#include "../../../../../../ohos_interface/ohos_glue/base/include/ark_web_errno.h"
namespace {
constexpr int32_t PARAMZERO = 0;
constexpr int32_t PARAMONE = 1;
constexpr int32_t RESULT_COUNT = 2;
const std::string BUNDLE_NAME_PREFIX = "bundleName:";
const std::string MODULE_NAME_PREFIX = "moduleName:";
}
namespace OHOS {
namespace NWeb {
namespace {
constexpr uint32_t URL_MAXIMUM = 2 * 1024 * 1024;
struct WaitForAttachParam {
arkts::concurrency_helpers::AsyncWork* asyncWork;
ani_resolver resolver;
int32_t timeout;
WebviewController* webviewController;
int32_t state;
ani_vm* vm;
};
bool GetAppBundleNameAndModuleName(std::string& bundleName, std::string& moduleName)
{
static std::string applicationBundleName;
static std::string applicationModuleName;
if (!applicationBundleName.empty() && !applicationModuleName.empty()) {
bundleName = applicationBundleName;
moduleName = applicationModuleName;
return true;
}
std::shared_ptr<AbilityRuntime::ApplicationContext> context =
AbilityRuntime::ApplicationContext::GetApplicationContext();
if (!context) {
WVLOG_E("Failed to get application context.");
return false;
}
auto resourceManager = context->GetResourceManager();
if (!resourceManager) {
WVLOG_E("Failed to get resource manager.");
return false;
}
applicationBundleName = resourceManager->bundleInfo.first;
applicationModuleName = resourceManager->bundleInfo.second;
bundleName = applicationBundleName;
moduleName = applicationModuleName;
WVLOG_D("application bundleName: %{public}s, moduleName: %{public}s", bundleName.c_str(), moduleName.c_str());
return true;
}
}
using namespace NWebError;
std::mutex g_objectMtx;
std::unordered_map<int32_t, WebviewController*> g_webview_controller_map;
std::string WebviewController::customeSchemeCmdLine_ = "";
bool WebviewController::existNweb_ = false;
bool WebviewController::webDebuggingAccess_ = OHOS::system::GetBoolParameter("web.debug.devtools", false);
int32_t WebviewController::webDebuggingPort_ = 0;
std::set<std::string> WebviewController::webTagSet_;
int32_t WebviewController::webTagStrId_ = 0;
WebviewController::WebviewController(int32_t nwebId) : nwebId_(nwebId)
{
if (IsInit()) {
std::unique_lock<std::mutex> lk(g_objectMtx);
g_webview_controller_map.emplace(nwebId, this);
}
}
WebviewController::WebviewController(const std::string& webTag) : webTag_(webTag)
{
NWebHelper::Instance().SetWebTag(-1, webTag_.c_str());
}
WebviewController::~WebviewController()
{
std::unique_lock<std::mutex> lk(g_objectMtx);
g_webview_controller_map.erase(nwebId_);
{
std::unique_lock<std::mutex> attachLock(attachMtx_);
attachState_ = AttachState::ATTACHED;
attachCond_.notify_all();
}
for (auto& [eventName, regObjs] : attachEventRegisterInfo_) {
for (auto& regObj : regObjs) {
if (regObj.m_regHandlerRef) {
regObj.m_regEnv->GlobalReference_Delete(regObj.m_regHandlerRef);
regObj.m_regHandlerRef = nullptr;
}
}
regObjs.clear();
}
attachEventRegisterInfo_.clear();
}
void WebviewController::TriggerStateChangeCallback(const std::string& type)
{
auto iter = attachEventRegisterInfo_.find(type);
if (iter == attachEventRegisterInfo_.end()) {
WVLOG_D("TriggerStateChangeCallback event %{public}s not found", type.c_str());
return;
}
const std::vector<WebRegObj>& regObjs = iter->second;
for (const auto& regObj : regObjs) {
if (!regObj.m_isMarked) {
if (!regObj.m_regHandlerRef) {
WVLOG_E("Handler for event %{public}s is null", type.c_str());
continue;
}
ani_enum_item stateRst = nullptr;
ani_enum enumType;
if (regObj.m_regEnv->FindEnum("@ohos.web.webview.webview.ControllerAttachState", &enumType) != ANI_OK) {
WVLOG_E("Find enum ControllerAttachState failed");
continue;
}
if (regObj.m_regEnv->Enum_GetEnumItemByIndex(enumType, static_cast<ani_int>(attachState_), &stateRst) !=
ANI_OK) {
WVLOG_E("Convert attachState(%{public}d) failed", attachState_);
continue;
}
std::vector<ani_ref> vec;
vec.push_back(stateRst);
ani_ref callbackResult = nullptr;
if (regObj.m_regEnv->FunctionalObject_Call(
reinterpret_cast<ani_fn_object>(regObj.m_regHandlerRef), vec.size(),
vec.data(), &callbackResult) != ANI_OK) {
WVLOG_E("FunctionalObject_Call failed");
}
}
}
for (auto it = iter->second.begin(); it != iter->second.end();) {
if (it->m_isMarked) {
it->m_regEnv->GlobalReference_Delete(it->m_regHandlerRef);
it = iter->second.erase(it);
} else {
++it;
}
}
}
void WebviewController::SetWebId(int32_t nwebId)
{
nwebId_ = nwebId;
std::unique_lock<std::mutex> lk(g_objectMtx);
g_webview_controller_map.emplace(nwebId, this);
if (webTag_.empty()) {
WVLOG_I("native webtag is empty, don't care because it's not a native instance");
return;
}
AttachState prevState = attachState_;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
OH_NativeArkWeb_BindWebTagToWebInstance(webTag_.c_str(), nweb_ptr);
NWebHelper::Instance().SetWebTag(nwebId_, webTag_.c_str());
{
std::unique_lock<std::mutex> attachLock(attachMtx_);
attachState_ = AttachState::ATTACHED;
attachCond_.notify_all();
}
if (prevState != attachState_) {
TriggerStateChangeCallback(CONTROLLER_ATTACH_STATE_CHANGE);
}
}
SetNWebJavaScriptResultCallBack();
NativeArkWeb_OnValidCallback validCallback = OH_NativeArkWeb_GetJavaScriptProxyValidCallback(webTag_.c_str());
if (validCallback) {
WVLOG_I("native validCallback start to call");
(*validCallback)(webTag_.c_str());
} else {
WVLOG_W("native validCallback is null, callback nothing");
}
}
void WebviewController::SetWebDetach(int32_t nwebId)
{
if (nwebId != nwebId_) {
WVLOG_W("Web detach nwebId(%{public}d) is not equal to current nwebId(%{public}d)", nwebId, nwebId_);
return;
}
if (attachState_ != AttachState::NOT_ATTACHED) {
std::unique_lock<std::mutex> attachLock(attachMtx_);
attachState_ = AttachState::NOT_ATTACHED;
TriggerStateChangeCallback(CONTROLLER_ATTACH_STATE_CHANGE);
}
}
WebviewController* WebviewController::FromID(int32_t nwebId)
{
std::unique_lock<std::mutex> lk(g_objectMtx);
if (auto it = g_webview_controller_map.find(nwebId); it != g_webview_controller_map.end()) {
auto control = it->second;
return control;
}
return nullptr;
}
void WebviewController::InnerCompleteWindowNew(int32_t parentNwebId)
{
WVLOG_D("WebviewController::InnerCompleteWindowNew parentNwebId == "
"%{public}d ",
parentNwebId);
if (parentNwebId < 0) {
WVLOG_E("WebviewController::InnerCompleteWindowNew parentNwebId == %{public}d "
"error",
parentNwebId);
return;
}
auto parentControl = FromID(parentNwebId);
if (!parentControl || !(parentControl->javaScriptResultCb_)) {
WVLOG_E("WebviewController::InnerCompleteWindowNew parentControl or "
"javaScriptResultCb_ is null");
return;
}
auto parNamedObjs = parentControl->javaScriptResultCb_->GetNamedObjects();
auto currentControl = FromID(nwebId_);
if (!currentControl || !(currentControl->javaScriptResultCb_)) {
WVLOG_E("WebviewController::InnerCompleteWindowNew currentControl or "
"javaScriptResultCb_ is null");
return;
}
std::unique_lock<std::mutex> lock(webMtx_);
{
auto curNamedObjs = currentControl->javaScriptResultCb_->GetNamedObjects();
SetNWebJavaScriptResultCallBack();
for (auto it = parNamedObjs.begin(); it != parNamedObjs.end(); it++) {
if (curNamedObjs.find(it->first) != curNamedObjs.end()) {
continue;
}
if (it->second && IsInit()) {
RegisterJavaScriptProxyParam param;
param.env = it->second->GetEnv();
param.obj = it->second->GetValue();
param.objName = it->first;
param.syncMethodList = it->second->GetSyncMethodNames();
param.asyncMethodList = it->second->GetAsyncMethodNames();
param.permission = it->second->GetPermission();
RegisterJavaScriptProxy(param);
}
}
}
}
bool WebviewController::IsInit() const
{
return NWebHelper::Instance().GetNWeb(nwebId_) ? true : false;
}
bool WebviewController::AccessForward() const
{
bool access = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
access = nweb_ptr->IsNavigateForwardAllowed();
} else {
WVLOG_E("WebviewController::AccessForward nweb_ptr is null");
}
return access;
}
bool WebviewController::AccessBackward() const
{
bool access = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
access = nweb_ptr->IsNavigatebackwardAllowed();
}
return access;
}
bool WebviewController::AccessStep(int32_t step) const
{
bool access = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
access = nweb_ptr->CanNavigateBackOrForward(step);
}
return access;
}
void WebviewController::ClearHistory()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->DeleteNavigateHistory();
}
}
void WebviewController::Forward()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->NavigateForward();
}
}
void WebviewController::Backward()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->NavigateBack();
}
}
void WebviewController::OnActive()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->OnContinue();
}
}
void WebviewController::OnInactive()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->OnPause();
}
}
void WebviewController::Refresh()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->Reload();
}
}
void WebviewController::ReloadIgnoreCache()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ReloadIgnoreCache();
}
}
ErrCode WebviewController::ZoomIn()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
ErrCode result = NWebError::NO_ERROR;
result = nweb_ptr->ZoomIn();
return result;
}
ErrCode WebviewController::ZoomOut()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
ErrCode result = NWebError::NO_ERROR;
result = nweb_ptr->ZoomOut();
return result;
}
int32_t WebviewController::GetWebId() const
{
int32_t webId = -1;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
webId = static_cast<int32_t>(nweb_ptr->GetWebId());
}
return webId;
}
std::string WebviewController::GetUserAgent()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return "";
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return "";
}
return setting->DefaultUserAgent();
}
std::string WebviewController::GetCustomUserAgent() const
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return "";
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return "";
}
return setting->UserAgent();
}
ErrCode WebviewController::SetCustomUserAgent(const std::string& userAgent)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return NWebError::INIT_ERROR;
}
setting->PutUserAgent(userAgent);
return NWebError::NO_ERROR;
}
std::string WebviewController::GetTitle()
{
std::string title = "";
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
title = nweb_ptr->Title();
}
return title;
}
int32_t WebviewController::GetProgress()
{
int32_t progress = 0;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
progress = nweb_ptr->PageLoadProgress();
}
return progress;
}
int32_t WebviewController::GetPageHeight()
{
int32_t pageHeight = 0;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
pageHeight = nweb_ptr->ContentHeight();
}
return pageHeight;
}
ErrCode WebviewController::BackOrForward(int32_t step)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
nweb_ptr->NavigateBackOrForward(step);
return NWebError::NO_ERROR;
}
void WebviewController::StoreWebArchiveCallback(const std::string &baseName, bool autoName, napi_env env,
napi_ref jsCallback)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
napi_value setResult[RESULT_COUNT] = {0};
setResult[PARAMZERO] = BusinessError::CreateError(env, NWebError::INIT_ERROR);
napi_get_null(env, &setResult[PARAMONE]);
napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
napi_value callback = nullptr;
napi_get_reference_value(env, jsCallback, &callback);
napi_value callbackResult = nullptr;
napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &callbackResult);
napi_delete_reference(env, jsCallback);
return;
}
if (jsCallback == nullptr) {
return;
}
auto callbackImpl = std::make_shared<OHOS::NWeb::NWebStoreWebArchiveCallback>();
callbackImpl->SetCallBack([env, jCallback = std::move(jsCallback)](std::string result) {
if (!env) {
return;
}
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env, &scope);
if (scope == nullptr) {
return;
}
napi_value setResult[RESULT_COUNT] = {0};
if (result.empty()) {
setResult[PARAMZERO] = BusinessError::CreateError(env, NWebError::INVALID_RESOURCE);
napi_get_null(env, &setResult[PARAMONE]);
} else {
napi_get_undefined(env, &setResult[PARAMZERO]);
napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &setResult[PARAMONE]);
}
napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
napi_value callback = nullptr;
napi_get_reference_value(env, jCallback, &callback);
napi_value callbackResult = nullptr;
napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &callbackResult);
napi_delete_reference(env, jCallback);
napi_close_handle_scope(env, scope);
});
nweb_ptr->StoreWebArchive(baseName, autoName, callbackImpl);
return;
}
void WebviewController::StoreWebArchivePromise(const std::string &baseName, bool autoName, napi_env env,
napi_deferred deferred)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
napi_value jsResult = nullptr;
jsResult = NWebError::BusinessError::CreateError(env, NWebError::INIT_ERROR);
napi_reject_deferred(env, deferred, jsResult);
return;
}
if (deferred == nullptr) {
return;
}
auto callbackImpl = std::make_shared<OHOS::NWeb::NWebStoreWebArchiveCallback>();
callbackImpl->SetCallBack([env, deferred](std::string result) {
if (!env) {
return;
}
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env, &scope);
if (scope == nullptr) {
return;
}
napi_value setResult[RESULT_COUNT] = {0};
setResult[PARAMZERO] = NWebError::BusinessError::CreateError(env, NWebError::INVALID_RESOURCE);
napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &setResult[PARAMONE]);
napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]};
if (!result.empty()) {
napi_resolve_deferred(env, deferred, args[PARAMONE]);
} else {
napi_reject_deferred(env, deferred, args[PARAMZERO]);
}
napi_close_handle_scope(env, scope);
});
nweb_ptr->StoreWebArchive(baseName, autoName, callbackImpl);
return;
}
std::vector<std::string> WebviewController::CreateWebMessagePorts()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
std::vector<std::string> empty;
return empty;
}
return nweb_ptr->CreateWebMessagePorts();
}
ErrCode WebviewController::PostWebMessage(std::string& message, std::vector<std::string>& ports, std::string& targetUrl)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
nweb_ptr->PostWebMessage(message, ports, targetUrl);
return NWebError::NO_ERROR;
}
std::shared_ptr<HitTestResult> WebviewController::GetHitTestValue()
{
std::shared_ptr<HitTestResult> nwebResult;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nwebResult = nweb_ptr->GetHitTestResult();
if (nwebResult) {
nwebResult->SetType(ConverToWebHitTestType(nwebResult->GetType()));
}
}
return nwebResult;
}
void WebviewController::RequestFocus()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->OnFocus();
}
}
std::string WebviewController::GenerateWebTag()
{
std::string webTag = "arkweb:" + std::to_string(WebviewController::webTagStrId_);
while (WebviewController::webTagSet_.find(webTag) != WebviewController::webTagSet_.end()) {
WebviewController::webTagStrId_++;
webTag = "arkweb:" + std::to_string(WebviewController::webTagStrId_);
}
return webTag;
}
bool WebviewController::GetRawFileUrl(const std::string &fileName,
const std::string& bundleName, const std::string& moduleName, std::string &result) const
{
if (fileName.empty()) {
WVLOG_E("File name is empty.");
return false;
}
if (hapPath_.empty()) {
std::shared_ptr<AbilityRuntime::ApplicationContext> context =
AbilityRuntime::ApplicationContext::GetApplicationContext();
std::string packagePath = "file:///" + context->GetBundleCodeDir() + "/";
std::string contextBundleName = context->GetBundleName() + "/";
std::shared_ptr<AppExecFwk::ApplicationInfo> appInfo = context->GetApplicationInfo();
std::string entryDir = appInfo->entryDir;
bool isStage = entryDir.find("entry") == std::string::npos ? false : true;
result = isStage ? packagePath + "entry/resources/rawfile/" + fileName :
packagePath + contextBundleName + "assets/entry/resources/rawfile/" + fileName;
} else {
std::string appBundleName;
std::string appModuleName;
result = "resource://RAWFILE/";
if (!bundleName.empty() && !moduleName.empty() &&
GetAppBundleNameAndModuleName(appBundleName, appModuleName)) {
if (appBundleName != bundleName || appModuleName != moduleName) {
result += BUNDLE_NAME_PREFIX + bundleName + "/" + MODULE_NAME_PREFIX + moduleName + "/";
}
}
result += fileName;
}
WVLOG_D("The parsed url is: ***");
return true;
}
bool WebviewController::ParseUrl(napi_env env, napi_value urlObj, std::string& result) const
{
napi_valuetype valueType = napi_null;
napi_typeof(env, urlObj, &valueType);
if ((valueType != napi_object) && (valueType != napi_string)) {
WVLOG_E("Unable to parse url object.");
return false;
}
if (valueType == napi_string) {
NapiParseUtils::ParseString(env, urlObj, result);
WVLOG_D("The parsed url is: ***");
return true;
}
napi_value type = nullptr;
napi_valuetype typeVlueType = napi_null;
napi_get_named_property(env, urlObj, "type", &type);
napi_typeof(env, type, &typeVlueType);
if (typeVlueType == napi_number) {
int32_t typeInteger;
NapiParseUtils::ParseInt32(env, type, typeInteger);
if (typeInteger == static_cast<int>(ResourceType::RAWFILE)) {
return ParseRawFileUrl(env, urlObj, result);
} else if (typeInteger == static_cast<int>(ResourceType::STRING)) {
if (!GetResourceUrl(env, urlObj, result)) {
WVLOG_E("Unable to parse string from url object.");
return false;
}
return true;
}
WVLOG_E("The type parsed from url object is not RAWFILE.");
return false;
}
WVLOG_E("Unable to parse type from url object.");
return false;
}
bool WebviewController::ParseRawFileUrl(napi_env env, napi_value urlObj, std::string& result) const
{
napi_value paraArray = nullptr;
napi_get_named_property(env, urlObj, "params", ¶Array);
bool isArray = false;
napi_is_array(env, paraArray, &isArray);
if (!isArray) {
WVLOG_E("Unable to parse parameter array from url object.");
return false;
}
napi_value fileNameObj;
napi_value bundleNameObj;
napi_value moduleNameObj;
std::string fileName;
std::string bundleName;
std::string moduleName;
napi_get_element(env, paraArray, 0, &fileNameObj);
napi_get_named_property(env, urlObj, "bundleName", &bundleNameObj);
napi_get_named_property(env, urlObj, "moduleName", &moduleNameObj);
NapiParseUtils::ParseString(env, fileNameObj, fileName);
NapiParseUtils::ParseString(env, bundleNameObj, bundleName);
NapiParseUtils::ParseString(env, moduleNameObj, moduleName);
return GetRawFileUrl(fileName, bundleName, moduleName, result);
}
bool WebviewController::GetResourceUrl(napi_env env, napi_value urlObj, std::string& result) const
{
napi_value resIdObj = nullptr;
napi_value bundleNameObj = nullptr;
napi_value moduleNameObj = nullptr;
int32_t resId;
std::string bundleName;
std::string moduleName;
if ((napi_get_named_property(env, urlObj, "id", &resIdObj) != napi_ok) ||
(napi_get_named_property(env, urlObj, "bundleName", &bundleNameObj) != napi_ok) ||
(napi_get_named_property(env, urlObj, "moduleName", &moduleNameObj) != napi_ok)) {
return false;
}
if (!NapiParseUtils::ParseInt32(env, resIdObj, resId) ||
!NapiParseUtils::ParseString(env, bundleNameObj, bundleName) ||
!NapiParseUtils::ParseString(env, moduleNameObj, moduleName)) {
return false;
}
if (OhosResourceAdapterImpl::GetResourceString(bundleName, moduleName, resId, result)) {
return true;
}
return false;
}
ErrCode WebviewController::PostUrl(std::string& url, std::vector<char>& postData)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
return nweb_ptr->PostUrl(url, postData);
}
ErrCode WebviewController::LoadUrl(std::string url)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
return nweb_ptr->Load(url);
}
ErrCode WebviewController::LoadUrl(std::string url, std::map<std::string, std::string> httpHeaders)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
return nweb_ptr->Load(url, httpHeaders);
}
ErrCode WebviewController::LoadData(std::string data, std::string mimeType, std::string encoding,
std::string baseUrl, std::string historyUrl)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
if (baseUrl.empty() && historyUrl.empty()) {
return nweb_ptr->LoadWithData(data, mimeType, encoding);
}
return nweb_ptr->LoadWithDataAndBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
}
int WebviewController::ConverToWebHitTestType(int hitType)
{
WebHitTestType webHitType;
switch (hitType) {
case HitTestResult::UNKNOWN_TYPE:
webHitType = WebHitTestType::UNKNOWN;
break;
case HitTestResult::ANCHOR_TYPE:
webHitType = WebHitTestType::HTTP;
break;
case HitTestResult::PHONE_TYPE:
webHitType = WebHitTestType::PHONE;
break;
case HitTestResult::GEO_TYPE:
webHitType = WebHitTestType::MAP;
break;
case HitTestResult::EMAIL_TYPE:
webHitType = WebHitTestType::EMAIL;
break;
case HitTestResult::IMAGE_TYPE:
webHitType = WebHitTestType::IMG;
break;
case HitTestResult::IMAGE_ANCHOR_TYPE:
webHitType = WebHitTestType::HTTP_IMG;
break;
case HitTestResult::SRC_ANCHOR_TYPE:
webHitType = WebHitTestType::HTTP;
break;
case HitTestResult::SRC_IMAGE_ANCHOR_TYPE:
webHitType = WebHitTestType::HTTP_IMG;
break;
case HitTestResult::EDIT_TEXT_TYPE:
webHitType = WebHitTestType::EDIT;
break;
default:
webHitType = WebHitTestType::UNKNOWN;
break;
}
return static_cast<int>(webHitType);
}
int WebviewController::GetHitTest()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
std::shared_ptr<HitTestResult> nwebResult = nweb_ptr->GetHitTestResult();
if (nwebResult) {
return ConverToWebHitTestType(nwebResult->GetType());
} else {
return ConverToWebHitTestType(HitTestResult::UNKNOWN_TYPE);
}
}
return static_cast<int>(WebHitTestType::UNKNOWN);
}
void WebviewController::ClearMatches()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ClearMatches();
}
}
void WebviewController::SearchNext(bool forward)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->FindNext(forward);
}
}
void WebviewController::EnableSafeBrowsing(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->EnableSafeBrowsing(enable);
}
}
bool WebviewController::IsSafeBrowsingEnabled() const
{
bool isSafeBrowsingEnabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
isSafeBrowsingEnabled = nweb_ptr->IsSafeBrowsingEnabled();
}
return isSafeBrowsingEnabled;
}
void WebviewController::SearchAllAsync(const std::string& searchString)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->FindAllAsync(searchString);
}
}
void WebviewController::ClearSslCache()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ClearSslCache();
}
}
void WebviewController::ClearClientAuthenticationCache()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ClearClientAuthenticationCache();
}
}
void WebviewController::Stop()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->Stop();
}
}
ErrCode WebviewController::Zoom(float factor)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
ErrCode result = NWebError::NO_ERROR;
result = nweb_ptr->Zoom(factor);
return result;
}
ErrCode WebviewController::DeleteJavaScriptRegister(const std::string& objName,
const std::vector<std::string>& methodList)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->UnregisterArkJSfunction(objName, methodList);
}
if (javaScriptResultCb_) {
bool ret = javaScriptResultCb_->DeleteJavaScriptRegister(objName);
if (!ret) {
return CANNOT_DEL_JAVA_SCRIPT_PROXY;
}
}
return NWebError::NO_ERROR;
}
void WebviewController::SetNWebJavaScriptResultCallBack()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
if (javaScriptResultCb_ && (javaScriptResultCb_->GetNWebId() == nwebId_)) {
return;
}
javaScriptResultCb_ = std::make_shared<WebviewJavaScriptResultCallBack>(nwebId_);
nweb_ptr->SetNWebJavaScriptResultCallBack(javaScriptResultCb_);
}
void WebviewController::RegisterJavaScriptProxy(RegisterJavaScriptProxyParam& param)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy nweb_ptr is null");
return;
}
JavaScriptOb::ObjectID objId =
static_cast<JavaScriptOb::ObjectID>(JavaScriptOb::JavaScriptObjIdErrorCode::WEBCONTROLLERERROR);
if (!javaScriptResultCb_) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy javaScriptResultCb_ is "
"null");
return;
}
if (param.syncMethodList.empty() && param.asyncMethodList.empty()) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy all methodList are "
"empty");
return;
}
std::vector<std::string> allMethodList;
std::merge(param.syncMethodList.begin(), param.syncMethodList.end(),
param.asyncMethodList.begin(), param.asyncMethodList.end(),
std::back_inserter(allMethodList));
RegisterJavaScriptProxyParam param_tmp;
param_tmp.env = param.env;
param_tmp.obj = param.obj;
param_tmp.objName = param.objName;
param_tmp.syncMethodList = allMethodList;
param_tmp.asyncMethodList = param.asyncMethodList;
param_tmp.permission = param.permission;
objId = javaScriptResultCb_->RegisterJavaScriptProxy(param_tmp);
nweb_ptr->RegisterArkJSfunctionV2(param_tmp.objName, param_tmp.syncMethodList,
std::vector<std::string>(), objId, param_tmp.permission);
}
void WebviewController::RegisterJavaScriptProxy(AniRegisterJavaScriptProxyParam& param)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy nweb_ptr is null");
return;
}
JavaScriptOb::ObjectID objId =
static_cast<JavaScriptOb::ObjectID>(JavaScriptOb::JavaScriptObjIdErrorCode::WEBCONTROLLERERROR);
if (!javaScriptResultCb_) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy javaScriptResultCb_ is null");
return;
}
if (param.syncMethodList.empty() && param.asyncMethodList.empty()) {
WVLOG_E("WebviewController::RegisterJavaScriptProxy all methodList are empty");
return;
}
std::vector<std::string> allMethodList;
std::merge(param.syncMethodList.begin(), param.syncMethodList.end(), param.asyncMethodList.begin(),
param.asyncMethodList.end(), std::back_inserter(allMethodList));
AniRegisterJavaScriptProxyParam tmp;
tmp.env = param.env;
tmp.obj = param.obj;
tmp.objName = param.objName;
tmp.syncMethodList = allMethodList;
tmp.asyncMethodList = param.asyncMethodList;
tmp.permission = param.permission;
tmp.webviewObj = param.webviewObj;
objId = javaScriptResultCb_->RegisterJavaScriptProxy(tmp);
nweb_ptr->RegisterArkJSfunctionV2(tmp.objName, tmp.syncMethodList, std::vector<std::string>(),
objId, tmp.permission);
}
void WebviewController::CreatePDFExt(
std::shared_ptr<NWebPDFConfigArgs> pdfConfig, std::shared_ptr<NWebArrayBufferValueCallback> callbackImpl)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("nweb_ptr is nullptr");
return;
}
if (callbackImpl == nullptr) {
WVLOG_E("callbackImpl is nullptr");
return;
}
nweb_ptr->ExecuteCreatePDFExt(pdfConfig, callbackImpl);
}
std::string WebviewController::GetUrl()
{
std::string url = "";
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
url = nweb_ptr->GetUrl();
}
return url;
}
std::string WebviewController::GetOriginalUrl()
{
std::string url = "";
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
url = nweb_ptr->GetOriginalUrl();
}
return url;
}
bool WebviewController::TerminateRenderProcess() const
{
bool ret = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
ret = nweb_ptr->TerminateRenderProcess();
}
return ret;
}
void WebviewController::PutNetworkAvailable(bool available)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->PutNetworkAvailable(available);
}
}
ErrCode WebviewController::HasImagesCallback(ani_vm *vm, ani_ref jsCallback)
{
if (vm == nullptr) {
return NWebError::INIT_ERROR;
}
ani_env* env = nullptr;
if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) {
return NWebError::INIT_ERROR;
}
if (env == nullptr) {
WVLOG_E("env is nullptr");
return NWebError::INIT_ERROR;
}
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
std::vector<ani_ref> vec;
ani_ref errorValue = AniBusinessErrorError::CreateError(env, NWebError::INIT_ERROR);
ani_ref dataValue = nullptr;
auto status = env->GetUndefined(&dataValue);
if (status != ANI_OK) {
WVLOG_E("get null failed, status is : %{public}d", status);
return NWebError::INIT_ERROR;
}
if (errorValue == nullptr || dataValue == nullptr) {
WVLOG_E("errorValue or dataValue is nullptr");
return NWebError::INIT_ERROR;
}
vec.push_back(errorValue);
vec.push_back(dataValue);
ani_ref callbackResult = nullptr;
auto stat = env->FunctionalObject_Call(
reinterpret_cast<ani_fn_object>(jsCallback), vec.size(), vec.data(), &callbackResult);
if (stat != ANI_OK) {
WVLOG_E("FunctionalObject_Call failed, status is : %{public}d", stat);
return NWebError::INIT_ERROR;
}
if (env->GlobalReference_Delete(jsCallback) != ANI_OK) {
WVLOG_E("delete globalReference failed");
}
return NWebError::INIT_ERROR;
}
if (jsCallback == nullptr) {
return NWebError::PARAM_CHECK_ERROR;
}
auto callbackImpl = std::make_shared<WebviewHasImageCallback>(vm, jsCallback, nullptr);
if (callbackImpl) {
nweb_ptr->HasImages(callbackImpl);
return NWebError::NO_ERROR;
}
return NWebError::PARAM_CHECK_ERROR;
}
ErrCode WebviewController::HasImagesPromise(ani_vm *vm, ani_resolver deferred)
{
if (vm == nullptr) {
WVLOG_E("vm is nullptr");
return NWebError::INIT_ERROR;
}
ani_env* env = nullptr;
if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) {
return NWebError::INIT_ERROR;
}
if (env == nullptr) {
WVLOG_E("env is nullptr");
return NWebError::INIT_ERROR;
}
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
ani_ref jsResult = nullptr;
jsResult = AniBusinessErrorError::CreateError(env, NWebError::INIT_ERROR);
if (jsResult == nullptr) {
return NWebError::INIT_ERROR;
}
auto status = env->PromiseResolver_Reject(deferred, static_cast<ani_error>(jsResult));
if (status != ANI_OK) {
WVLOG_E("PromiseResolver_Reject failed, status is : %{public}d", status);
return NWebError::INIT_ERROR;
}
return NWebError::INIT_ERROR;
}
if (deferred == nullptr) {
return NWebError::PARAM_CHECK_ERROR;
}
auto callbackImpl = std::make_shared<WebviewHasImageCallback>(vm, nullptr, deferred);
if (callbackImpl) {
nweb_ptr->HasImages(callbackImpl);
return NWebError::NO_ERROR;
}
return NWebError::PARAM_CHECK_ERROR;
}
void WebviewController::RemoveCache(bool includeDiskFiles)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->RemoveCache(includeDiskFiles);
}
}
std::shared_ptr<NWebHistoryList> WebviewController::GetHistoryList()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return nullptr;
}
return nweb_ptr->GetHistoryList();
}
bool WebviewController::GetFavicon(
const void **data, size_t &width, size_t &height, ImageColorType &colorType, ImageAlphaType &alphaType) const
{
bool isGetFavicon = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
isGetFavicon = nweb_ptr->GetFavicon(data, width, height, colorType, alphaType);
}
return isGetFavicon;
}
std::vector<uint8_t> WebviewController::SerializeWebState()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
return nweb_ptr->SerializeWebState();
}
std::vector<uint8_t> empty;
return empty;
}
bool WebviewController::RestoreWebState(const std::vector<uint8_t> &state) const
{
bool isRestored = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
isRestored = nweb_ptr->RestoreWebState(state);
}
return isRestored;
}
void WebviewController::ScrollPageDown(bool bottom)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->PageDown(bottom);
}
return;
}
void WebviewController::ScrollPageUp(bool top)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->PageUp(top);
}
return;
}
void WebviewController::ScrollTo(float x, float y)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ScrollTo(x, y);
}
return;
}
void WebviewController::ScrollBy(float deltaX, float deltaY)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ScrollBy(deltaX, deltaY);
}
return;
}
void WebviewController::SlideScroll(float vx, float vy)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->SlideScroll(vx, vy);
}
return;
}
void WebviewController::SetScrollable(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return;
}
return setting->SetScrollable(enable);
}
bool WebviewController::GetScrollable() const
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return true;
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return true;
}
return setting->GetScrollable();
}
void WebviewController::InnerSetHapPath(const std::string &hapPath)
{
hapPath_ = hapPath;
}
bool WebviewController::GetCertChainDerData(std::vector<std::string> &certChainDerData) const
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("GetCertChainDerData failed, nweb ptr is null");
return false;
}
return nweb_ptr->GetCertChainDerData(certChainDerData, true);
}
ErrCode WebviewController::SetAudioMuted(bool muted)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->SetAudioMuted(muted);
return NWebError::NO_ERROR;
}
ErrCode WebviewController::PrefetchPage(std::string& url, std::map<std::string, std::string> additionalHttpHeaders)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->PrefetchPage(url, additionalHttpHeaders);
return NWebError::NO_ERROR;
}
ErrCode WebviewController::PrefetchPage(std::string& url, std::map<std::string, std::string> additionalHttpHeaders,
std::shared_ptr<NWebPrefetchOptions> prefetchOptions)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->PrefetchPageV2(url, additionalHttpHeaders,
prefetchOptions->GetminTimeBetweenPrefetchesMs(), prefetchOptions->GetignoreCacheControlNoStore());
return NWebError::NO_ERROR;
}
void WebPrintDocument::OnStartLayoutWrite(const std::string& jobId, const PrintAttributesAdapter& oldAttrs,
const PrintAttributesAdapter& newAttrs, uint32_t fd, std::function<void(std::string, uint32_t)> writeResultCallback)
{
if (printDocAdapter_) {
std::shared_ptr<PrintWriteResultCallbackAdapter> callback =
std::make_shared<WebPrintWriteResultCallbackAdapter>(writeResultCallback);
printDocAdapter_->OnStartLayoutWrite(jobId, oldAttrs, newAttrs, fd, callback);
}
}
void WebPrintDocument::OnJobStateChanged(const std::string& jobId, uint32_t state)
{
if (printDocAdapter_) {
printDocAdapter_->OnJobStateChanged(jobId, state);
}
}
void* WebviewController::CreateWebPrintDocumentAdapter(const std::string& jobName)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return nullptr;
}
return nweb_ptr->CreateWebPrintDocumentAdapter(jobName);
}
void WebviewController::CloseAllMediaPresentations()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->CloseAllMediaPresentations();
}
}
void WebviewController::StopAllMedia()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->StopAllMedia();
}
}
void WebviewController::ResumeAllMedia()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ResumeAllMedia();
}
}
void WebviewController::PauseAllMedia()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->PauseAllMedia();
}
}
int WebviewController::GetMediaPlaybackState()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return static_cast<int>(MediaPlaybackState::NONE);
}
return nweb_ptr->GetMediaPlaybackState();
}
ErrCode WebviewController::AvoidVisibleViewportBottom(int32_t avoidHeight)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
nweb_ptr->AvoidVisibleViewportBottom(avoidHeight);
return NWebError::NO_ERROR;
}
int WebviewController::GetSecurityLevel(ani_env* env)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR);
return static_cast<int>(SecurityLevel::NONE);
}
int nwebSecurityLevel = nweb_ptr->GetSecurityLevel();
SecurityLevel securityLevel;
switch (nwebSecurityLevel) {
case static_cast<int>(CoreSecurityLevel::NONE):
securityLevel = SecurityLevel::NONE;
break;
case static_cast<int>(CoreSecurityLevel::SECURE):
securityLevel = SecurityLevel::SECURE;
break;
case static_cast<int>(CoreSecurityLevel::WARNING):
securityLevel = SecurityLevel::WARNING;
break;
case static_cast<int>(CoreSecurityLevel::DANGEROUS):
securityLevel = SecurityLevel::DANGEROUS;
break;
default:
securityLevel = SecurityLevel::NONE;
break;
}
return static_cast<int>(securityLevel);
}
bool WebviewController::IsIncognitoMode() const
{
bool incognitoMode = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
incognitoMode = nweb_ptr->IsIncognitoMode();
}
return incognitoMode;
}
void WebviewController::SetPrintBackground(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->SetPrintBackground(enable);
}
}
bool WebviewController::GetPrintBackground() const
{
bool printBackgroundEnabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
printBackgroundEnabled = nweb_ptr->GetPrintBackground();
}
return printBackgroundEnabled;
}
void WebviewController::EnableIntelligentTrackingPrevention(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->EnableIntelligentTrackingPrevention(enable);
}
}
bool WebviewController::IsIntelligentTrackingPreventionEnabled() const
{
bool enabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
enabled = nweb_ptr->IsIntelligentTrackingPreventionEnabled();
}
return enabled;
}
void WebPrintWriteResultCallbackAdapter::WriteResultCallback(std::string jobId, uint32_t code)
{
cb_(jobId, code);
}
bool WebviewController::SetWebSchemeHandler(const char* scheme, WebSchemeHandler* handler) const
{
if (!handler || !scheme) {
WVLOG_E("WebviewController::SetWebSchemeHandler handler or scheme is nullptr");
return false;
}
auto schemeHandler_ptr = WebSchemeHandler::GetArkWebSchemeHandler(handler);
if (!schemeHandler_ptr) {
WVLOG_E("WebviewController::SetWebSchemeHandler ArkWebSchemeHandler is nullptr");
return false;
}
ArkWeb_SchemeHandler* schemeHandler = const_cast<ArkWeb_SchemeHandler*>(schemeHandler_ptr);
return OH_ArkWeb_SetSchemeHandler(scheme, webTag_.c_str(), schemeHandler);
}
bool WebviewController::SetWebServiveWorkerSchemeHandler(const char* scheme, WebSchemeHandler* handler)
{
auto schemeHandler_ptr = WebSchemeHandler::GetArkWebSchemeHandler(handler);
if (!schemeHandler_ptr) {
WVLOG_E("WebviewController::SetWebServiveWorkerSchemeHandler ArkWebSchemeHandler is nullptr");
return false;
}
ArkWeb_SchemeHandler* schemeHandler = const_cast<ArkWeb_SchemeHandler*>(schemeHandler_ptr);
return OH_ArkWebServiceWorker_SetSchemeHandler(scheme, schemeHandler);
}
int32_t WebviewController::ClearWebSchemeHandler()
{
return OH_ArkWeb_ClearSchemeHandlers(webTag_.c_str());
}
int32_t WebviewController::ClearWebServiceWorkerSchemeHandler()
{
return OH_ArkWebServiceWorker_ClearSchemeHandlers();
}
ErrCode WebviewController::StartCamera()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->StartCamera();
return NWebError::NO_ERROR;
}
ErrCode WebviewController::StopCamera()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->StopCamera();
return NWebError::NO_ERROR;
}
ErrCode WebviewController::CloseCamera()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->CloseCamera();
return NWebError::NO_ERROR;
}
ErrCode WebviewController::ResumeMicrophone()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->ResumeMicrophone();
return NWebError::NO_ERROR;
}
ErrCode WebviewController::StopMicrophone()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->StopMicrophone();
return NWebError::NO_ERROR;
}
ErrCode WebviewController::PauseMicrophone()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
nweb_ptr->PauseMicrophone();
return NWebError::NO_ERROR;
}
std::string WebviewController::GetLastJavascriptProxyCallingFrameUrl()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return "";
}
return nweb_ptr->GetLastJavascriptProxyCallingFrameUrl();
}
bool WebviewController::ParseScriptContent(napi_env env, napi_value value, std::string &script)
{
napi_valuetype valueType;
napi_typeof(env, value, &valueType);
if (valueType == napi_string) {
std::string str;
if (!NapiParseUtils::ParseString(env, value, str)) {
WVLOG_E("PrecompileJavaScript: parse script text to string failed.");
return false;
}
script = str;
return true;
}
std::vector<uint8_t> vec = ParseUint8Array(env, value);
if (!vec.size()) {
WVLOG_E("PrecompileJavaScript: parse script text to Uint8Array failed.");
return false;
}
std::string str(vec.begin(), vec.end());
script = str;
return true;
}
std::shared_ptr<CacheOptions> WebviewController::ParseCacheOptions(napi_env env, napi_value value)
{
std::map<std::string, std::string> responseHeaders;
auto defaultCacheOptions = std::make_shared<NWebCacheOptionsImpl>(responseHeaders);
napi_value responseHeadersValue = nullptr;
if (napi_get_named_property(env, value, "responseHeaders", &responseHeadersValue) != napi_ok) {
WVLOG_D("PrecompileJavaScript: cannot get 'responseHeaders' of CacheOptions.");
return defaultCacheOptions;
}
if (!ParseResponseHeaders(env, responseHeadersValue, responseHeaders)) {
WVLOG_D("PrecompileJavaScript: parse 'responseHeaders' of CacheOptions failed. use default options");
return defaultCacheOptions;
}
return std::make_shared<NWebCacheOptionsImpl>(responseHeaders);
}
void WebviewController::PrecompileJavaScriptPromise(
napi_env env, napi_deferred deferred,
const std::string &url, const std::string &script, std::shared_ptr<CacheOptions> cacheOptions)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr || !deferred) {
return;
}
auto callbackImpl = std::make_shared<OHOS::NWeb::NWebPrecompileCallback>();
callbackImpl->SetCallback([env, deferred](int64_t result) {
if (!env) {
return;
}
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env, &scope);
if (scope == nullptr) {
return;
}
napi_value setResult[RESULT_COUNT] = {0};
napi_create_int64(env, result, &setResult[PARAMZERO]);
napi_value args[RESULT_COUNT] = {setResult[PARAMZERO]};
if (result == static_cast<int64_t>(PrecompileError::OK)) {
napi_resolve_deferred(env, deferred, args[PARAMZERO]);
} else {
napi_reject_deferred(env, deferred, args[PARAMZERO]);
}
napi_close_handle_scope(env, scope);
});
nweb_ptr->PrecompileJavaScript(url, script, cacheOptions, callbackImpl);
}
int32_t WebviewController::PrecompileJavaScript(const std::string& url, const std::string& script,
std::shared_ptr<OHOS::NWeb::CacheOptions> cacheOptions,
std::shared_ptr<OHOS::NWeb::NWebMessageValueCallback> callbackImpl)
{
WVLOG_D("PrecompDleJavaScript begin");
if (url.empty() || script.empty()) {
WVLOG_E("url or script is empty");
return NWebError::PARAM_CHECK_ERROR;
}
if (!callbackImpl) {
WVLOG_E("PrecompileJavaScript !callbackImpl");
return NWebError::PARAM_CHECK_ERROR;
}
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("nweb_ptr is null");
return NWebError::INIT_ERROR;
}
nweb_ptr->PrecompileJavaScript(url, script, cacheOptions, callbackImpl);
return NWebError::NO_ERROR;
}
bool WebviewController::ParseResponseHeaders(napi_env env,
napi_value value,
std::map<std::string, std::string> &responseHeaders) const
{
bool isArray = false;
napi_is_array(env, value, &isArray);
if (!isArray) {
WVLOG_E("Response headers is not array.");
return false;
}
uint32_t length = INTEGER_ZERO;
napi_get_array_length(env, value, &length);
for (uint32_t i = 0; i < length; i++) {
std::string keyString;
std::string valueString;
napi_value header = nullptr;
napi_value keyObj = nullptr;
napi_value valueObj = nullptr;
napi_get_element(env, value, i, &header);
if (napi_get_named_property(env, header, "headerKey", &keyObj) != napi_ok ||
!NapiParseUtils::ParseString(env, keyObj, keyString)) {
continue;
}
if (napi_get_named_property(env, header, "headerValue", &valueObj) != napi_ok ||
!NapiParseUtils::ParseString(env, valueObj, valueString)) {
continue;
}
responseHeaders[keyString] = valueString;
}
return true;
}
ParseURLResult WebviewController::ParseURLList(napi_env env, napi_value value, std::vector<std::string>& urlList)
{
if (!NapiParseUtils::ParseStringArray(env, value, urlList)) {
return ParseURLResult::FAILED;
}
for (auto url : urlList) {
if (!CheckURL(url)) {
return ParseURLResult::INVALID_URL;
}
}
return ParseURLResult::OK;
}
bool WebviewController::CheckURL(std::string& url) const
{
if (url.size() > URL_MAXIMUM) {
WVLOG_E("The URL exceeds the maximum length of %{public}d. URL: %{private}s", URL_MAXIMUM, url.c_str());
return false;
}
if (!regex_match(url, std::regex("^http(s)?:\\/\\/.+", std::regex_constants::icase))) {
WVLOG_E("The Parse URL error. URL: %{private}s", url.c_str());
return false;
}
return true;
}
std::vector<uint8_t> WebviewController::ParseUint8Array(napi_env env, napi_value value)
{
napi_typedarray_type typedArrayType;
size_t length = 0;
napi_value buffer = nullptr;
size_t offset = 0;
napi_get_typedarray_info(env, value, &typedArrayType, &length, nullptr, &buffer, &offset);
if (typedArrayType != napi_uint8_array) {
WVLOG_E("Param is not Unit8Array.");
return std::vector<uint8_t>();
}
uint8_t *data = nullptr;
size_t total = 0;
napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total);
length = std::min<size_t>(length, total - offset);
std::vector<uint8_t> vec(length);
int retCode = memcpy_s(vec.data(), vec.size(), &data[offset], length);
if (retCode != 0) {
WVLOG_E("Parse Uint8Array failed.");
return std::vector<uint8_t>();
}
return vec;
}
void WebviewController::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)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
if (urlList.empty()) {
WVLOG_E("urlList is empty");
return;
}
std::string originUrl = urlList[0];
if (urlList.size() == 1) {
nweb_ptr->InjectOfflineResource(originUrl, originUrl, resource, response_headers, type);
return;
}
for (size_t i = 1 ; i < urlList.size() ; i++) {
nweb_ptr->InjectOfflineResource(urlList[i], originUrl, resource, response_headers, type);
}
}
void WebviewController::EnableAdsBlock(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->EnableAdsBlock(enable);
}
}
bool WebviewController::IsAdsBlockEnabled() const
{
bool enabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
enabled = nweb_ptr->IsAdsBlockEnabled();
}
return enabled;
}
bool WebviewController::IsAdsBlockEnabledForCurPage() const
{
bool enabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
enabled = nweb_ptr->IsAdsBlockEnabledForCurPage();
}
return enabled;
}
std::string WebviewController::GetSurfaceId()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return "";
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return "";
}
return setting->GetSurfaceId();
}
void WebviewController::UpdateInstanceId(int32_t newId)
{
if (javaScriptResultCb_) {
javaScriptResultCb_->UpdateInstanceId(newId);
}
}
ErrCode WebviewController::SetUrlTrustList(const std::string& urlTrustList, std::string& detailErrMsg)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return NWebError::INIT_ERROR;
}
int ret = NWebError::NO_ERROR;
switch (nweb_ptr->SetUrlTrustListWithErrMsg(urlTrustList, detailErrMsg)) {
case static_cast<int>(UrlListSetResult::INIT_ERROR):
ret = NWebError::INIT_ERROR;
break;
case static_cast<int>(UrlListSetResult::PARAM_ERROR):
ret = NWebError::PARAM_CHECK_ERROR;
break;
case static_cast<int>(UrlListSetResult::SET_OK):
ret = NWebError::NO_ERROR;
break;
default:
ret = NWebError::PARAM_CHECK_ERROR;
break;
}
return ret;
}
ErrCode WebviewController::SetUrlTrustList(const std::string& urlTrustList,
bool allowOpaqueOrigin, bool supportWildcard, std::string& detailErrMsg)
{
auto nwebPtr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nwebPtr) {
return NWebError::INIT_ERROR;
}
int ret = NWebError::NO_ERROR;
int setUrlTrustListRet = nwebPtr->SetUrlTrustListWithErrMsg(urlTrustList,
allowOpaqueOrigin, supportWildcard, detailErrMsg);
switch (setUrlTrustListRet) {
case static_cast<int>(UrlListSetResult::INIT_ERROR):
ret = NWebError::INIT_ERROR;
break;
case static_cast<int>(UrlListSetResult::PARAM_ERROR):
ret = NWebError::PARAM_CHECK_ERROR;
break;
case static_cast<int>(UrlListSetResult::SET_OK):
ret = NWebError::NO_ERROR;
break;
default:
ret = NWebError::PARAM_CHECK_ERROR;
break;
}
return ret;
}
bool WebviewController::ParseJsLengthResourceToInt(
napi_env env, napi_value jsLength, PixelUnit &type, int32_t &result) const
{
napi_value resIdObj = nullptr;
int32_t resId;
if ((napi_get_named_property(env, jsLength, "id", &resIdObj) != napi_ok)) {
return false;
}
if (!NapiParseUtils::ParseInt32(env, resIdObj, resId)) {
return false;
}
std::shared_ptr<AbilityRuntime::ApplicationContext> context =
AbilityRuntime::ApplicationContext::GetApplicationContext();
if (!context) {
WVLOG_E("WebPageSnapshot Failed to get application context.");
return false;
}
auto resourceManager = context->GetResourceManager();
if (!resourceManager) {
WVLOG_E("WebPageSnapshot Failed to get resource manager.");
return false;
}
napi_value jsResourceType = nullptr;
napi_valuetype resourceType = napi_null;
napi_get_named_property(env, jsLength, "type", &jsResourceType);
napi_typeof(env, jsResourceType, &resourceType);
if (resourceType == napi_number) {
int32_t resourceTypeNum;
NapiParseUtils::ParseInt32(env, jsResourceType, resourceTypeNum);
std::string resourceString;
switch (resourceTypeNum) {
case static_cast<int>(ResourceType::INTEGER):
if (resourceManager->GetIntegerById(resId, result) == Global::Resource::SUCCESS) {
type = PixelUnit::VP;
return true;
}
break;
case static_cast<int>(ResourceType::STRING):
if (resourceManager->GetStringById(resId, resourceString) == Global::Resource::SUCCESS) {
return NapiParseUtils::ParseJsLengthStringToInt(resourceString, type, result);
}
break;
default:
break;
}
WVLOG_E("WebPageSnapshot resource type not support");
return false;
}
WVLOG_E("WebPageSnapshot resource type error");
return false;
}
bool WebviewController::ParseJsLengthToInt(
napi_env env, napi_value jsLength, PixelUnit &type, int32_t &result) const
{
napi_valuetype jsType = napi_null;
napi_typeof(env, jsLength, &jsType);
if ((jsType != napi_object) && (jsType != napi_string) && (jsType != napi_number)) {
WVLOG_E("WebPageSnapshot Unable to parse js length object.");
return false;
}
if (jsType == napi_number) {
NapiParseUtils::ParseInt32(env, jsLength, result);
type = PixelUnit::VP;
return true;
}
if (jsType == napi_string) {
std::string nativeString;
NapiParseUtils::ParseString(env, jsLength, nativeString);
if (!NapiParseUtils::ParseJsLengthStringToInt(nativeString, type, result)) {
return false;
}
return true;
}
if (jsType == napi_object) {
return ParseJsLengthResourceToInt(env, jsLength, type, result);
}
return false;
}
ErrCode WebviewController::WebPageSnapshot(
const char *id, PixelUnit type, int32_t width, int32_t height, const WebSnapshotCallback callback)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
auto snapshotCallback = std::make_shared<NWebSnapshotCallbackImpl>(std::move(callback));
bool init = nweb_ptr->WebPageSnapshotV2(id, type, width, height, snapshotCallback);
if (ArkWebGetErrno() != RESULT_OK) {
WVLOG_I("WebPageSnapshotV2 isn't existing, using old");
init = nweb_ptr->WebPageSnapshot(
id, type, width, height, snapshotCallback->extract());
snapshotCallback.reset();
}
if (!init) {
return INIT_ERROR;
}
return NWebError::NO_ERROR;
}
bool WebviewController::GetHapModuleInfo()
{
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
WVLOG_E("get SystemAbilityManager failed");
return false;
}
sptr<IRemoteObject> remoteObject =
systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (remoteObject == nullptr) {
WVLOG_E("get Bundle Manager failed");
return false;
}
auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
if (bundleMgr == nullptr) {
WVLOG_E("get Bundle Manager failed");
return false;
}
AppExecFwk::BundleInfo bundleInfo;
if (bundleMgr->GetBundleInfoForSelf(
static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE),
bundleInfo) != 0) {
WVLOG_E("get bundle info failed");
return false;
}
moduleName_ = bundleInfo.moduleNames;
return true;
}
void WebviewController::SetPathAllowingUniversalAccess(
const std::vector<std::string>& pathList, std::string& errorPath)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
if (moduleName_.empty()) {
WVLOG_I("need to get module name for path");
if (!GetHapModuleInfo()) {
WVLOG_E("GetHapModuleInfo failed");
moduleName_.clear();
return;
}
}
nweb_ptr->SetPathAllowingUniversalAccess(pathList, moduleName_, errorPath);
}
void WebviewController::ScrollToWithAnime(float x, float y, int32_t duration)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ScrollToWithAnime(x, y, duration);
}
return;
}
void WebviewController::ScrollByWithAnime(float deltaX, float deltaY, int32_t duration)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->ScrollByWithAnime(deltaX, deltaY, duration);
}
return;
}
void WebviewController::SetBackForwardCacheOptions(int32_t size, int32_t timeToLive)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
nweb_ptr->SetBackForwardCacheOptions(size, timeToLive);
}
void WebviewController::GetScrollOffset(float* offset_x, float* offset_y)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->GetScrollOffset(offset_x, offset_y);
}
}
void WebviewController::GetPageOffset(float* offsetX, float* offsetY)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nweb_ptr->GetPageOffset(offsetX, offsetY);
}
}
bool WebviewController::ScrollByWithResult(float deltaX, float deltaY) const
{
bool enabled = false;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
enabled = nweb_ptr->ScrollByWithResult(deltaX, deltaY);
}
return enabled;
}
void WebviewController::SetScrollable(bool enable, int32_t scrollType)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
std::shared_ptr<OHOS::NWeb::NWebPreference> setting = nweb_ptr->GetPreference();
if (!setting) {
return;
}
return setting->SetScrollable(enable, scrollType);
}
void WebviewController::SetSoftKeyboardBehaviorMode(int32_t mode)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
nweb_ptr->SetSoftKeyboardBehaviorMode(static_cast<WebSoftKeyboardBehaviorMode>(mode));
}
void WebMessageExt::SetType(int type)
{
type_ = type;
WebMessageType jsType = static_cast<WebMessageType>(type);
NWebValue::Type nwebType = NWebValue::Type::NONE;
switch (jsType) {
case WebMessageType::STRING: {
nwebType = NWebValue::Type::STRING;
break;
}
case WebMessageType::NUMBER: {
nwebType = NWebValue::Type::DOUBLE;
break;
}
case WebMessageType::BOOLEAN: {
nwebType = NWebValue::Type::BOOLEAN;
break;
}
case WebMessageType::ARRAYBUFFER: {
nwebType = NWebValue::Type::BINARY;
break;
}
case WebMessageType::ARRAY: {
nwebType = NWebValue::Type::STRINGARRAY;
break;
}
case WebMessageType::ERROR: {
nwebType = NWebValue::Type::ERROR;
break;
}
default: {
nwebType = NWebValue::Type::NONE;
break;
}
}
if (data_) {
data_->SetType(nwebType);
}
}
int WebMessageExt::ConvertNwebType2JsType(NWebValue::Type type)
{
WebMessageType jsType = WebMessageType::NOTSUPPORT;
switch (type) {
case NWebValue::Type::STRING: {
jsType = WebMessageType::STRING;
break;
}
case NWebValue::Type::DOUBLE:
case NWebValue::Type::INTEGER: {
jsType = WebMessageType::NUMBER;
break;
}
case NWebValue::Type::BOOLEAN: {
jsType = WebMessageType::BOOLEAN;
break;
}
case NWebValue::Type::STRINGARRAY:
case NWebValue::Type::DOUBLEARRAY:
case NWebValue::Type::INT64ARRAY:
case NWebValue::Type::BOOLEANARRAY: {
jsType = WebMessageType::ARRAY;
break;
}
case NWebValue::Type::BINARY: {
jsType = WebMessageType::ARRAYBUFFER;
break;
}
case NWebValue::Type::ERROR: {
jsType = WebMessageType::ERROR;
break;
}
default: {
jsType = WebMessageType::NOTSUPPORT;
break;
}
}
return static_cast<int>(jsType);
}
std::shared_ptr<HitTestResult> WebviewController::GetLastHitTest()
{
std::shared_ptr<HitTestResult> nwebResult;
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
nwebResult = nweb_ptr->GetLastHitTestResult();
if (nwebResult) {
nwebResult->SetType(ConverToWebHitTestType(nwebResult->GetType()));
}
}
return nwebResult;
}
void WebviewController::OnCreateNativeMediaPlayer(ani_vm* vm, ani_fn_object callback)
{
WVLOG_I("put on_create_native_media_player callback");
if (vm == nullptr) {
WVLOG_E("vm is nullptr");
return;
}
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return;
}
auto callbackImpl = std::make_shared<NWebCreateNativeMediaPlayerCallbackImpl>(nwebId_, vm, callback);
if(!callbackImpl){
return;
}
nweb_ptr->OnCreateNativeMediaPlayer(callbackImpl);
}
int32_t WebviewController::GetNWebId()
{
return nwebId_;
}
ErrCode WebviewController::SetErrorPageEnabled(bool enable)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return INIT_ERROR;
}
nweb_ptr->SetErrorPageEnabled(enable);
return NWebError::NO_ERROR;
}
bool WebviewController::GetErrorPageEnabled()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
return false;
}
return nweb_ptr->GetErrorPageEnabled();
}
int32_t WebviewController::GetBlanklessInfoWithKey(const std::string& key, double* similarity, int32_t* loadingTime)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
return nweb_ptr->GetBlanklessInfoWithKey(key, similarity, loadingTime);
}
return -1;
}
int32_t WebviewController::SetBlanklessLoadingWithKey(const std::string& key, bool isStart)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
return nweb_ptr->SetBlanklessLoadingWithKey(key, isStart);
}
return -1;
}
int32_t WebviewController::SetBlanklessLoadingParams(ani_env* env, const std::string& key,
AniBlanklessLoadingParam& param)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
std::shared_ptr<OHOS::NWeb::AniWebviewBlanklessCallback> callbackImpl = nullptr;
if (!nweb_ptr) {
return -1;
}
if (param.callbackRef) {
callbackImpl = std::make_shared<OHOS::NWeb::AniWebviewBlanklessCallback>(env, param.callbackRef);
}
return nweb_ptr->SetBlanklessLoadingParams(key, param.enable, param.duration, param.expirationTime, callbackImpl);
}
int32_t WebviewController::GetAttachState()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (nweb_ptr) {
return static_cast<int32_t>(attachState_);
}
return static_cast<int32_t>(AttachState::NOT_ATTACHED);
}
void WebviewController::RegisterStateChangeCallback(ani_env *env, const std::string& type, ani_object handler)
{
ani_ref callbackRef;
if (env->GlobalReference_Create(handler, &callbackRef) != ANI_OK) {
WVLOG_E("RegisterStateChangeCallback failed to create reference for callback");
return;
}
WebRegObj regObj(env, callbackRef);
auto iter = attachEventRegisterInfo_.find(type);
if (iter == attachEventRegisterInfo_.end()) {
attachEventRegisterInfo_[type] = std::vector<WebRegObj> { regObj };
WVLOG_D("RegisterStateChangeCallback add new type:%{public}s", type.c_str());
return;
}
bool found = false;
for (auto& regObjInList : iter->second) {
if (env == regObjInList.m_regEnv) {
ani_boolean isEqual = ANI_FALSE;
if (env->Reference_StrictEquals(regObjInList.m_regHandlerRef, handler, &isEqual) != ANI_OK) {
WVLOG_E("RegisterStateChangeCallback failed to compare handlers");
env->GlobalReference_Delete(callbackRef);
return;
}
if (isEqual) {
WVLOG_W("RegisterStateChangeCallback handler function is same");
found = true;
regObjInList.m_isMarked = false;
break;
}
}
}
if (!found) {
iter->second.emplace_back(regObj);
WVLOG_D("RegisterStateChangeCallback add new handler for type:%{public}s", type.c_str());
}
return;
}
void WebviewController::DeleteRegisterObj(ani_env *env, std::vector<WebRegObj>& vecRegObjs, ani_object& handler)
{
for (auto iter = vecRegObjs.begin(); iter != vecRegObjs.end(); ++iter) {
if (!handler) {
WVLOG_E("DeleteRegisterObj handler is null");
break;
}
if (env == iter->m_regEnv && !iter->m_isMarked) {
ani_boolean isEqual = ANI_FALSE;
if (env->Reference_StrictEquals(iter->m_regHandlerRef, handler, &isEqual) != ANI_OK) {
WVLOG_E("DeleteRegisterObj failed to compare handlers");
continue;
}
if (isEqual) {
iter->m_isMarked = true;
WVLOG_I("DeleteRegisterObj mark register object ref delete");
break;
} else {
WVLOG_D("DeleteRegisterObj register handler is not equal to HandlerRef");
}
} else {
WVLOG_D("DeleteRegisterObj unregister event, env(%{private}p) is not equal to m_regEnv(%{private}p)", env,
iter->m_regEnv);
}
}
}
void WebviewController::DeleteAllRegisterObj(ani_env *env, std::vector<WebRegObj>& vecRegObjs)
{
for (auto iter = vecRegObjs.begin(); iter != vecRegObjs.end(); ++iter) {
if (env == iter->m_regEnv && !iter->m_isMarked) {
iter->m_isMarked = true;
WVLOG_D("DeleteAllRegisterObj mark register object ref delete");
} else {
WVLOG_D("DeleteAllRegisterObj unregister all event, env(%{private}p) is not equal to m_regEnv(%{private}p)",
env, iter->m_regEnv);
}
}
}
void WebviewController::UnregisterStateChangeCallback(ani_env *env, const std::string& type, ani_object handler)
{
auto iter = attachEventRegisterInfo_.find(type);
if (iter == attachEventRegisterInfo_.end()) {
WVLOG_W("UnregisterStateChangeCallback unregister type:%{public}s not found", type.c_str());
return;
}
if (handler) {
DeleteRegisterObj(env, iter->second, handler);
} else {
WVLOG_D("UnregisterStateChangeCallback unregister all callback for type:%{public}s", type.c_str());
DeleteAllRegisterObj(env, iter->second);
}
if (iter->second.empty()) {
attachEventRegisterInfo_.erase(iter);
}
return;
}
void WebviewController::WaitForAttachedDeal(ani_env *env, void *data)
{
WaitForAttachParam *param = static_cast<WaitForAttachParam *>(data);
std::unique_lock<std::mutex> attachLock(param->webviewController->attachMtx_);
param->webviewController->attachCond_.wait_for(attachLock, std::chrono::milliseconds(param->timeout), [param] {
return param->webviewController->attachState_ == AttachState::ATTACHED;
});
param->state = static_cast<int32_t>(param->webviewController->attachState_);
WVLOG_D("WaitForAttachedDeal finish wait_for, param->state = %{public}d", param->state);
}
void WebviewController::WaitForAttachedFinish(ani_env *env, arkts::concurrency_helpers::WorkStatus status, void *data)
{
WaitForAttachParam *param = static_cast<WaitForAttachParam *>(data);
ani_env *envUse = nullptr;
if (param->vm->GetEnv(ANI_VERSION_1, &envUse) != ANI_OK || !envUse) {
WVLOG_E("WaitForAttachedFinish get env failed");
delete param;
param = nullptr;
return;
}
ani_size refs = REFERENCES_MAX_NUMBER;
envUse->CreateLocalScope(refs);
if (param->resolver) {
ani_enum enumType;
if (envUse->FindEnum("@ohos.web.webview.webview.ControllerAttachState", &enumType) != ANI_OK) {
WVLOG_E("WaitForAttachedFinish find enumType failed");
}
ani_enum_item result = nullptr;
ani_status rst = ANI_ERROR;
if ((rst = envUse->Enum_GetEnumItemByIndex(enumType, param->state, &result)) != ANI_OK) {
WVLOG_E("WaitForAttachedFinish convert attachState(%{public}d) failed, rst = %{public}d", param->state,
rst);
}
if ((rst = envUse->PromiseResolver_Resolve(param->resolver, result)) != ANI_OK) {
WVLOG_E("WaitForAttachedFinish resolve promise failed, rst = %{public}d", rst);
}
}
envUse->DestroyLocalScope();
DeleteAsyncWork(envUse, param->asyncWork);
delete param;
param = nullptr;
return;
}
void WebviewController::WaitForAttachedInternal(ani_env *env, ani_int timeout, ani_resolver resolver)
{
ani_vm *vm = nullptr;
if (env->GetVM(&vm) != ANI_OK || !vm) {
WVLOG_E("WaitForAttachedInternal get vm failed");
return;
}
WaitForAttachParam *param = new (std::nothrow) WaitForAttachParam {
.asyncWork = nullptr,
.resolver = resolver,
.timeout = timeout,
.webviewController = this,
.state = static_cast<int32_t>(attachState_),
.vm = vm,
};
if (!param) {
WVLOG_E("WaitForAttachedInternal create param failed");
return;
}
auto status = CreateAsyncWork(env, WaitForAttachedDeal, WaitForAttachedFinish, static_cast<void *>(param),
¶m->asyncWork);
if (status != arkts::concurrency_helpers::WorkStatus::OK) {
WVLOG_E("WaitForAttachedInternal create asyncWork failed");
delete param;
param = nullptr;
return;
}
QueueAsyncWork(env, param->asyncWork);
return;
}
void WebviewController::SetUserAgentMetadata(
const std::string& userAgent, std::shared_ptr<NWebUserAgentMetadata> metadata)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("nweb is nullptr");
return;
}
nweb_ptr->SetUserAgentMetadata(userAgent, metadata);
}
std::shared_ptr<NWebUserAgentMetadata> WebviewController::GetUserAgentMetadata(const std::string& userAgent)
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("nweb is nullptr");
return nullptr;
}
return nweb_ptr->GetUserAgentMetadata(userAgent);
}
std::string WebviewController::GetLastPostMessageURL()
{
auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);
if (!nweb_ptr) {
WVLOG_E("nweb is nullptr");
return "";
}
return nweb_ptr->GetLastPostMessageURL();
}
}
}