* Copyright (c) 2024 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 "ohos_nweb/src/capi/arkweb_model.h"
#include <memory>
#include <string>
#include <vector>
#include "arkweb_native_javascript_execute_callback.h"
#include "arkweb_native_object.h"
#include "base/logging.h"
#include "nweb_web_message.h"
#include "nweb_value.h"
#include "nweb_value_callback.h"
#include "arkweb_native_web_message_callback.h"
#include "ohos_nweb/include/nweb_engine.h"
#include "ohos_nweb/include/nweb_errors.h"
#include "cef/libcef/browser/javascript/oh_gin_javascript_bridge_dispatcher_host.h"
#include "third_party/bounds_checking_function/include/securec.h"
#ifdef OHOS_COOKIE
extern "C" {
void* __real_malloc(size_t);
}
#endif
#ifdef __cplusplus
std::function<std::shared_ptr<OHOS::NWeb::NWebValue>(
std::vector<std::vector<uint8_t>>&, std::vector<size_t>&)> CreateProxyCallback(
ArkWeb_OnJavaScriptProxyCallbackWithResult callback, std::string tag, void* data) {
return [cb = callback,
webTag = std::string(tag),
userData = data](
std::vector<std::vector<uint8_t>>& dataList,
std::vector<size_t>& dataSize) ->
std::shared_ptr<OHOS::NWeb::NWebValue> {
if (cb) {
size_t size = dataList.size();
std::vector<ArkWeb_JavaScriptBridgeData> dataVector(size);
for (size_t i = 0; i < size; i++) {
ArkWeb_JavaScriptBridgeData data = {.buffer = dataList[i].data(),
.size = dataSize[i]};
dataVector[i] = data;
}
ArkWeb_JavaScriptValuePtr result =
cb(webTag.c_str(), dataVector.data(), size, userData);
std::shared_ptr<OHOS::NWeb::NWebValue> nwebValue =
std::make_shared<OHOS::NWeb::NWebValue>(OHOS::NWeb::NWebValue::Type::NONE);
if (!result) {
WVLOG_D("native return nullptr");
return nullptr;
}
if (result->type == ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_BOOL) {
WVLOG_D("result is bool type");
bool boolVal = (*(bool*)(result->data));
delete (bool*)(result->data);
delete result;
nwebValue->SetType(OHOS::NWeb::NWebValue::Type::BOOLEAN);
nwebValue->SetBoolean(boolVal);
} else if (result->type == ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_STRING) {
WVLOG_D("result is string type");
std::string strVal = std::string(((char*)(result->data)));
delete[] (char*)(result->data);
delete result;
nwebValue->SetType(OHOS::NWeb::NWebValue::Type::STRING);
nwebValue->SetString(strVal);
} else {
WVLOG_D("native return nullptr");
return nullptr;
}
return nwebValue;
}
WVLOG_D("native return nullptr");
return nullptr;
};
}
extern "C" {
#endif
#define ARKWEB_NDK_EXPORT __attribute__((visibility("default")))
ARKWEB_NDK_EXPORT void OH_ArkWeb_RunJavaScript(
const char* webTag,
const ArkWeb_JavaScriptObject* javascriptObject) {
if (javascriptObject == nullptr || javascriptObject->buffer == nullptr) {
LOG(ERROR) << "NativeArkWeb javascript object or code is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
if (auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr()) {
std::string jsCode{reinterpret_cast<const char*>(javascriptObject->buffer),
javascriptObject->size};
auto javaScriptExecuteCallback = [webTag = std::string(webTag),
cb = javascriptObject->callback,
userData = javascriptObject->userData](
const std::vector<uint8_t>& data) {
ArkWeb_JavaScriptBridgeData jsBridgeData = {data.data(), data.size()};
if (cb) {
cb(webTag.c_str(), &jsBridgeData, userData);
}
};
auto callbackImpl =
std::make_shared<OHOS::NWeb::ArkWebNativeJavaScriptExecuteCallback>(
std::move(javaScriptExecuteCallback));
nwebSharedPtr->ExecuteJavaScript(jsCode, callbackImpl, false);
} else {
LOG(ERROR) << "NativeArkWeb RunJavaScript get nweb null:" << webTag;
}
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_RegisterJavaScriptProxy(
const char* webTag,
const ArkWeb_ProxyObject* proxyObject) {
RegisterJavaScriptProxy(webTag, proxyObject, false, "");
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_DeleteJavaScriptProxy(const char* webTag,
const char* objName) {
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
if (auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr()) {
nwebSharedPtr->UnRegisterNativeArkJSFunction(objName);
} else {
LOG(ERROR)
<< "NativeArkWeb UnregisterJavaScriptProxy get nweb null: %{public}s"
<< webTag;
}
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_Refresh(const char* webTag) {
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
if (auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr()) {
nwebSharedPtr->Reload();
} else {
LOG(ERROR) << "NativeArkWeb Refresh get nweb null: %{public}s" << webTag;
}
}
NO_SANITIZE("cfi-icall") ARKWEB_NDK_EXPORT void OH_ArkWeb_OnControllerAttached(
const char* webTag,
ArkWeb_OnComponentCallback callback,
void* userData) {
if (callback == nullptr) {
LOG(ERROR) << "NativeArkWeb OnControllerAttached callback is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
webObjectPtr->SetValidCallback(
[cb = callback, webTag = std::string(webTag), userData] {
if (!cb) {
LOG(ERROR) << "NativeArkWeb OnControllerAttached callback is nullptr";
return;
}
cb(webTag.c_str(), userData);
});
}
NO_SANITIZE("cfi-icall") ARKWEB_NDK_EXPORT void OH_ArkWeb_OnPageBegin(
const char* webTag,
ArkWeb_OnComponentCallback callback,
void* userData) {
if (callback == nullptr) {
LOG(ERROR) << "NativeArkWeb OnPageBegin callback is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
webObjectPtr->SetLoadStartCallback(
[cb = callback, webTag = std::string(webTag), userData] {
if (!cb) {
LOG(ERROR) << "NativeArkWeb OnPageBegin callback is nullptr";
return;
}
cb(webTag.c_str(), userData);
});
}
NO_SANITIZE("cfi-icall") ARKWEB_NDK_EXPORT void OH_ArkWeb_OnPageEnd(const char* webTag,
ArkWeb_OnComponentCallback callback,
void* userData) {
if (callback == nullptr) {
LOG(ERROR) << "NativeArkWeb OnPageEnd callback is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
webObjectPtr->SetLoadEndCallback(
[cb = callback, webTag = std::string(webTag), userData] {
if (!cb) {
LOG(ERROR) << "NativeArkWeb OnPageEnd callback is nullptr";
return;
}
cb(webTag.c_str(), userData);
});
}
NO_SANITIZE("cfi-icall") ARKWEB_NDK_EXPORT void OH_ArkWeb_OnDestroy(const char* webTag,
ArkWeb_OnComponentCallback callback,
void* userData) {
if (callback == nullptr) {
LOG(ERROR) << "NativeArkWeb OnDestroy callback is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
webObjectPtr->SetDestroyCallback(
[cb = callback, webTag = std::string(webTag), userData] {
if (!cb) {
LOG(ERROR) << "NativeArkWeb OnDestroy callback is nullptr";
return;
}
cb(webTag.c_str(), userData);
});
}
NO_SANITIZE("cfi-icall") ARKWEB_NDK_EXPORT bool OH_ArkWeb_OnScroll(const char* webTag,
ArkWeb_OnScrollCallback callback,
void* userData) {
if (callback == nullptr) {
LOG(ERROR) << "NativeArkWeb OnScroll callback is nullptr";
return false;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return false;
}
webObjectPtr->SetScrollCallback(
[cb = callback, webTag = std::string(webTag), userData](double x, double y) {
if (!cb) {
LOG(ERROR) << "NativeArkWeb OnScroll callback is nullptr";
return;
}
cb(webTag.c_str(), userData, x, y);
});
return true;
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_RegisterAsyncJavaScriptProxy(
const char* webTag,
const ArkWeb_ProxyObject* proxyObject) {
RegisterJavaScriptProxy(webTag, proxyObject, true, "");
}
NO_SANITIZE("cfi-icall") void RegisterJavaScriptProxy(
const char* webTag,
const ArkWeb_ProxyObject* proxyObject,
bool isAsync,
const char* permission) {
if (proxyObject == nullptr) {
LOG(ERROR) << "NativeArkWeb proxy object is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
return;
}
if (auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr()) {
int32_t size = proxyObject->size;
std::vector<std::function<char*(std::vector<std::vector<uint8_t>>&,
std::vector<size_t>&)>>
callbackList(size);
const ArkWeb_ProxyMethod* methodList = proxyObject->methodList;
if (methodList == nullptr) {
LOG(ERROR) << "NativeArkWeb method list is nullptr";
return;
}
std::vector<std::string> methodNameList(size);
for (int32_t i = 0; i < size; i++) {
auto methodNameObject = methodList[i];
methodNameList[i] = methodNameObject.methodName;
auto proxyCallback = [cb = methodNameObject.callback,
webTag = std::string(webTag),
userData = methodNameObject.userData](
std::vector<std::vector<uint8_t>>& dataList,
std::vector<size_t>& dataSize) -> char* {
if (cb) {
size_t size = dataList.size();
std::vector<ArkWeb_JavaScriptBridgeData> dataVector(size);
for (size_t i = 0; i < size; i++) {
ArkWeb_JavaScriptBridgeData data = {.buffer = dataList[i].data(),
.size = dataSize[i]};
dataVector[i] = data;
}
cb(webTag.c_str(), dataVector.data(), size, userData);
}
return nullptr;
};
callbackList[i] = std::move(proxyCallback);
}
if (permission) {
nwebSharedPtr->RegisterNativeArkJSFunction(
proxyObject->objName, methodNameList, std::move(callbackList), isAsync, permission);
} else {
nwebSharedPtr->RegisterNativeArkJSFunction(
proxyObject->objName, methodNameList, std::move(callbackList), isAsync, "");
}
} else {
LOG(ERROR)
<< "NativeArkWeb RegisterJavaScriptProxy get nweb null: %{public}s"
<< webTag;
}
}
bool CreateWebMessagePortsInternal(
const char* webTag,
size_t* size,
std::vector<std::string>& ports,
ArkWeb_WebMessagePortPtr** wPortsResult) {
if (!webTag || !size) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts nullptr error";
return false;
}
if (std::string(webTag).empty()) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts web tag empty";
*size = 0;
return false;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
*size = 0;
return false;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts get nweb null: %{public}s"
<< webTag;
*size = 0;
return false;
}
ports = nwebSharedPtr->CreateWebMessagePorts();
if (ports.size() == 0) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts failed";
*size = 0;
return false;
}
ArkWeb_WebMessagePortPtr* wPorts =
new (std::nothrow) ArkWeb_WebMessagePortPtr[ports.size()];
if (!wPorts) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts malloc failed";
*size = 0;
return false;
}
*wPortsResult = wPorts;
return true;
}
ARKWEB_NDK_EXPORT ArkWeb_WebMessagePortPtr* OH_ArkWeb_CreateWebMessagePorts(
const char* webTag,
size_t* size) {
std::vector<std::string> ports;
ArkWeb_WebMessagePortPtr* wPorts;
if (!CreateWebMessagePortsInternal(webTag, size, ports, &wPorts)) {
return nullptr;
}
auto webObjectPtr = OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
for (unsigned int i = 0; i < ports.size(); i++) {
wPorts[i] = new (std::nothrow) ArkWeb_WebMessagePort();
if (!wPorts[i]) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts malloc failed";
webObjectPtr->GetWebSharedPtr()->ClosePort(std::string(ports[0]));
OH_ArkWeb_DestroyWebMessagePorts(&wPorts, ports.size());
*size = 0;
return nullptr;
}
char* tag = new (std::nothrow) char[std::string(webTag).size() + 1];
if (!tag || memcpy_s(tag, std::string(webTag).size() + 1,
(char*)webTag, std::string(webTag).size() + 1) != EOK) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts malloc or memcpy failed";
if (tag) {
delete[] tag;
}
webObjectPtr->GetWebSharedPtr()->ClosePort(std::string(ports[0]));
OH_ArkWeb_DestroyWebMessagePorts(&wPorts, ports.size());
*size = 0;
return nullptr;
}
wPorts[i]->webTag = tag;
char* portHandle = new (std::nothrow) char[ports[i].size() + 1];
if (!portHandle ||
memcpy_s(portHandle, ports[i].size() + 1, (char*)(ports[i].c_str()), ports[i].size() + 1) != EOK) {
LOG(ERROR) << "NativeArkWeb CreateWebMessagePorts malloc or memcpy failed";
if (portHandle) {
delete[] portHandle;
}
webObjectPtr->GetWebSharedPtr()->ClosePort(std::string(ports[0]));
OH_ArkWeb_DestroyWebMessagePorts(&wPorts, ports.size());
*size = 0;
return nullptr;
}
wPorts[i]->portHandle = portHandle;
}
*size = ports.size();
return wPorts;
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_DestroyWebMessagePorts(
ArkWeb_WebMessagePortPtr** port,
size_t size) {
if (!port || !(*port)) {
LOG(ERROR) << "NativeArkWeb DestroyWebMessagePorts nullptr error";
return;
}
for (unsigned int i = 0; i < size; i++) {
if ((*port)[i] && (*port)[i]->webTag) {
delete[] (*port)[i]->webTag;
(*port)[i]->webTag = nullptr;
}
if ((*port)[i] && (*port)[i]->portHandle) {
delete[] (*port)[i]->portHandle;
(*port)[i]->portHandle = nullptr;
}
if ((*port)[i]) {
delete (*port)[i];
(*port)[i] = nullptr;
}
}
delete[] (*port);
*port = nullptr;
}
ARKWEB_NDK_EXPORT ArkWeb_ErrorCode OH_ArkWeb_PostWebMessage(
const char* webTag,
const char* name,
ArkWeb_WebMessagePortPtr* webMessagePorts,
size_t size,
const char* url) {
if (!webTag || !webMessagePorts || !name || !url) {
LOG(ERROR) << "NativeArkWeb PostWebMessage nullptr error";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
if (std::string(webTag).empty()) {
LOG(ERROR) << "NativeArkWeb PostWebMessage web tag empty";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
if (size < 1) {
LOG(ERROR) << "NativeArkWeb PostWebMessage number error";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "NativeArkWeb PostWebMessage get nweb null: %{public}s"
<< webTag;
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
std::vector<std::string> ports;
for (unsigned int i = 0; i < size; i++) {
if (webMessagePorts[i]->portHandle) {
ports.push_back(std::string(webMessagePorts[i]->portHandle));
}
}
nwebSharedPtr->PostWebMessage(std::string(name), ports,
std::string(url));
return ArkWeb_ErrorCode::ARKWEB_SUCCESS;
}
ARKWEB_NDK_EXPORT ArkWeb_ErrorCode OH_WebMessage_PostMessage(
const ArkWeb_WebMessagePortPtr webMessagePort,
const char* webTag,
const ArkWeb_WebMessagePtr message) {
if (!webTag || !webMessagePort || !message) {
LOG(ERROR) << "NativeArkWeb PostMessage nullptr error";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
if (std::string(webTag).empty()) {
LOG(ERROR) << "NativeArkWeb PostMessage web tag empty";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "NativeArkWeb PostMessage get nweb null: %{public}s"
<< webTag;
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
auto webMsg = std::make_shared<OHOS::NWeb::NWebMessage>(
OHOS::NWeb::NWebValue::Type::NONE);
if (!(webMessagePort->portHandle) ||
std::string(webMessagePort->portHandle).empty()) {
LOG(ERROR) << "can't post message, message port empty";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
if (!(message->data)) {
LOG(ERROR) << "can't post message, message data empty";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
if (message->webMessageType == ArkWeb_WebMessageType::ARKWEB_STRING) {
webMsg->SetType(OHOS::NWeb::NWebValue::Type::STRING);
webMsg->SetString(std::string(((char*)message->data)));
nwebSharedPtr->PostPortMessage(std::string(webMessagePort->portHandle),
webMsg);
} else if (message->webMessageType ==
ArkWeb_WebMessageType::ARKWEB_BUFFER) {
webMsg->SetType(OHOS::NWeb::NWebValue::Type::BINARY);
std::vector<uint8_t> vecData(
(uint8_t*)(message->data),
(uint8_t*)(message->data) + message->dataLength);
webMsg->SetBinary(vecData);
nwebSharedPtr->PostPortMessage(std::string(webMessagePort->portHandle),
webMsg);
} else {
LOG(ERROR) << "NativeArkWeb PostMessage, not support data type";
return ArkWeb_ErrorCode::ARKWEB_INVALID_PARAM;
}
return ArkWeb_ErrorCode::ARKWEB_SUCCESS;
}
ARKWEB_NDK_EXPORT void OH_WebMessage_Close(
const ArkWeb_WebMessagePortPtr webMessagePort,
const char* webTag) {
if (!webTag || !webMessagePort) {
LOG(ERROR) << "NativeArkWeb Close nullptr error";
return;
}
if (std::string(webTag).empty()) {
LOG(ERROR) << "NativeArkWeb Close web tag empty";
return;
}
if (!(webMessagePort->portHandle)) {
LOG(ERROR) << "NativeArkWeb Close nullptr error";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
return;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "NativeArkWeb Close get nweb null: %{public}s"
<< webTag;
return;
}
nwebSharedPtr->ClosePort(std::string(webMessagePort->portHandle));
}
ARKWEB_NDK_EXPORT void OH_WebMessage_SetMessageEventHandler(
const ArkWeb_WebMessagePortPtr webMessagePort,
const char* webTag,
ArkWeb_OnMessageEventHandler messageEventHandler,
void* userData) {
if (!webTag || !webMessagePort || !messageEventHandler) {
LOG(ERROR) << "NativeArkWeb SetMessageEventHandler nullptr error";
return;
}
if (std::string(webTag).empty()) {
LOG(ERROR) << "NativeArkWeb SetMessageEventHandler web tag empty";
return;
}
if (!(webMessagePort->portHandle)) {
LOG(ERROR) << "NativeArkWeb SetMessageEventHandler, nullptr error";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb web object pointer is nullptr";
return;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "NativeArkWeb SetMessageEventHandler get nweb null: %{public}s"
<< webTag;
return;
}
auto webMessageCallback =
[webTag = std::string(webTag), port = webMessagePort,
cb = messageEventHandler,
uData = userData](const ArkWeb_WebMessagePtr message) {
if (cb) {
LOG(DEBUG) << "NativeArkWeb SetMessageEventHandler, run callback";
cb(webTag.c_str(), port, message, uData);
}
};
auto callbackImpl =
std::make_shared<OHOS::NWeb::ArkWebNativeWebMessageCallback>(
std::move(webMessageCallback));
nwebSharedPtr->SetPortMessageCallback(
std::string(webMessagePort->portHandle), callbackImpl);
}
ARKWEB_NDK_EXPORT ArkWeb_WebMessagePtr OH_WebMessage_CreateWebMessage() {
ArkWeb_WebMessagePtr message = new (std::nothrow) ArkWeb_WebMessage();
if (!message) {
LOG(ERROR) << "NativeArkWeb CreateWebMessage malloc failed";
return nullptr;
}
return message;
}
ARKWEB_NDK_EXPORT void OH_WebMessage_DestroyWebMessage(ArkWeb_WebMessagePtr* message) {
if (!message || !(*message)) {
LOG(ERROR) << "NativeArkWeb DestroyWebMessage nullptr error";
return;
}
if ((*message)->data) {
delete[] (char*)((*message)->data);
(*message)->data = nullptr;
}
delete (*message);
*message = nullptr;
}
ARKWEB_NDK_EXPORT void OH_WebMessage_SetType(ArkWeb_WebMessagePtr message,
ArkWeb_WebMessageType type) {
if (!message) {
LOG(ERROR) << "NativeArkWeb SetType nullptr error";
return;
}
message->webMessageType = type;
}
ARKWEB_NDK_EXPORT ArkWeb_WebMessageType OH_WebMessage_GetType(ArkWeb_WebMessagePtr message) {
if (!message) {
LOG(ERROR) << "NativeArkWeb GetType nullptr error";
return ArkWeb_WebMessageType::ARKWEB_NONE;
}
return message->webMessageType;
}
ARKWEB_NDK_EXPORT void OH_WebMessage_SetData(ArkWeb_WebMessagePtr message,
void* data,
size_t dataLength) {
if (!message || !data) {
LOG(ERROR) << "NativeArkWeb SetData nullptr error";
return;
}
if (dataLength == 0) {
LOG(ERROR) << "NativeArkWeb SetData data size error";
return;
}
char* destination = new (std::nothrow) char[dataLength];
if (!destination) {
LOG(ERROR) << "NativeArkWeb SetData malloc failed";
return;
}
if (memcpy_s(destination, dataLength, (char*)data, dataLength) != EOK) {
LOG(ERROR) << "NativeArkWeb SetData memcpy failed";
delete[] destination;
return;
}
message->data = (void*)destination;
message->dataLength = dataLength;
}
ARKWEB_NDK_EXPORT void* OH_WebMessage_GetData(ArkWeb_WebMessagePtr message, size_t* dataLength) {
if (!message || !dataLength) {
LOG(ERROR) << "NativeArkWeb GetData nullptr error";
*dataLength = 0;
return nullptr;
}
*dataLength = message->dataLength;
return message->data;
}
ARKWEB_NDK_EXPORT ArkWeb_ErrorCode OH_CookieManager_FetchCookieSync(
const char* url, bool incognito, bool includeHttpOnly, char** cookie_value) {
auto cookie_manager = OHOS::NWeb::NWebEngine::GetInstance()->GetCookieManager();
if (!cookie_manager) {
LOG(ERROR) << "cookie manager is nullptr";
return ARKWEB_ERROR_UNKNOWN;
}
bool is_valid = true;
std::string cookie_content =
cookie_manager->ReturnCookieWithHttpOnly(std::string(url), is_valid, incognito, includeHttpOnly);
#ifdef OHOS_COOKIE
#if defined(ADDRESS_SANITIZER)
*cookie_value = new char[cookie_content.length() + 1];
#else
*cookie_value = (char*)__real_malloc(cookie_content.length() + 1);
#endif
#endif
strcpy((*cookie_value), cookie_content.c_str());
if (cookie_content == "" && !is_valid) {
return ARKWEB_INVALID_URL;
}
return ARKWEB_SUCCESS;
}
ARKWEB_NDK_EXPORT ArkWeb_ErrorCode OH_CookieManager_ConfigCookieSync(
const char* url, const char* value, bool incognito, bool includeHttpOnly) {
auto cookie_manager = OHOS::NWeb::NWebEngine::GetInstance()->GetCookieManager();
if (!cookie_manager) {
LOG(ERROR) << "cookie manager is nullptr";
return ARKWEB_ERROR_UNKNOWN;
}
int result = cookie_manager->SetCookieWithHttpOnly(std::string(url), std::string(value), incognito, includeHttpOnly);
if (result == OHOS::NWeb::NWebErrNo::NWEB_INVALID_URL) {
return ARKWEB_INVALID_URL;
} else if (result == OHOS::NWeb::NWebErrNo::NWEB_INVALID_COOKIE_VALUE) {
return ARKWEB_INVALID_COOKIE_VALUE;
}
return ARKWEB_SUCCESS;
}
ARKWEB_NDK_EXPORT bool OH_CookieManager_ExistCookies(bool incognito) {
auto cookie_manager = OHOS::NWeb::NWebEngine::GetInstance()->GetCookieManager();
if (!cookie_manager) {
LOG(ERROR) << "cookie manager is nullptr";
return false;
}
return cookie_manager->ExistCookies(incognito);
}
ARKWEB_NDK_EXPORT void OH_CookieManager_ClearAllCookiesSync(bool incognito) {
auto cookie_manager = OHOS::NWeb::NWebEngine::GetInstance()->GetCookieManager();
if (!cookie_manager) {
LOG(ERROR) << "cookie manager is nullptr";
return;
}
cookie_manager->DeleteCookieEntirely(nullptr, incognito);
}
ARKWEB_NDK_EXPORT void OH_CookieManager_ClearSessionCookiesSync() {
auto cookie_manager = OHOS::NWeb::NWebEngine::GetInstance()->GetCookieManager();
if (!cookie_manager) {
LOG(ERROR) << "cookie manager is nullptr";
return;
}
cookie_manager->DeleteSessionCookies(nullptr);
}
ARKWEB_NDK_EXPORT const char* OH_ArkWeb_GetLastJavascriptProxyCallingFrameUrl() {
if (!NWEB::OhGinJavascriptBridgeDispatcherHost::GetLastCallingFrameUrlTLS()) {
return "";
}
return NWEB::OhGinJavascriptBridgeDispatcherHost::GetLastCallingFrameUrlTLS();
}
void RegisterJavaScriptProxyEx(
const char* webTag,
const ArkWeb_ProxyObjectWithResult* proxyObject,
bool isAsync,
const char* permission) {
if (proxyObject == nullptr) {
LOG(ERROR) << "NativeArkWeb proxy object is nullptr";
return;
}
if (proxyObject->objName == nullptr) {
LOG(ERROR) << "NativeArkWeb proxy object name is nullptr";
return;
}
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "NativeArkWeb object pointer is nullptr";
return;
}
if (auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr()) {
int32_t size = proxyObject->size;
std::vector<std::function<std::shared_ptr<OHOS::NWeb::NWebValue>(
std::vector<std::vector<uint8_t>>&, std::vector<size_t>&)>>
callbackList(size);
const ArkWeb_ProxyMethodWithResult* methodList = proxyObject->methodList;
if (methodList == nullptr) {
LOG(ERROR) << "NativeArkWeb method list is nullptr";
return;
}
std::vector<std::string> methodNameList(size);
for (int32_t i = 0; i < size; i++) {
auto methodNameObject = methodList[i];
methodNameList[i] = methodNameObject.methodName;
auto proxyCallback = CreateProxyCallback(
methodNameObject.callback, std::string(webTag), methodNameObject.userData);
callbackList[i] = std::move(proxyCallback);
}
if (permission) {
nwebSharedPtr->RegisterNativeArkJSFunctionWithResult(
proxyObject->objName, methodNameList, std::move(callbackList), isAsync, permission);
} else {
nwebSharedPtr->RegisterNativeArkJSFunctionWithResult(
proxyObject->objName, methodNameList, std::move(callbackList), isAsync, "");
}
} else {
LOG(ERROR)
<< "NativeArkWeb RegisterJavaScriptProxy get nweb null: %{public}s"
<< webTag;
}
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_RegisterJavaScriptProxyEx(
const char* webTag,
const ArkWeb_ProxyObjectWithResult* proxyObject,
const char* permission) {
if (!webTag || !proxyObject) {
return;
}
RegisterJavaScriptProxyEx(webTag, proxyObject, false, permission);
}
ARKWEB_NDK_EXPORT void OH_ArkWeb_RegisterAsyncJavaScriptProxyEx(
const char* webTag,
const ArkWeb_ProxyObject* proxyObject,
const char* permission) {
if (!webTag || !proxyObject) {
return;
}
RegisterJavaScriptProxy(webTag, proxyObject, true, permission);
}
ARKWEB_NDK_EXPORT ArkWeb_JavaScriptValuePtr OH_JavaScript_CreateJavaScriptValue(
ArkWeb_JavaScriptValueType type, void* data, size_t dataLength) {
ArkWeb_JavaScriptValuePtr value = new (std::nothrow) ArkWeb_JavaScriptValue();
if (!value) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue malloc failed";
return nullptr;
}
if (!data) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue nullptr error";
return nullptr;
}
if (dataLength == 0) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue data size error";
return nullptr;
}
if (type == ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_NONE) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue type none";
return nullptr;
}
if (type == ArkWeb_JavaScriptValueType::ARKWEB_JAVASCRIPT_BOOL &&
dataLength != 1) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue type bool length error";
return nullptr;
}
char* destination = new (std::nothrow) char[dataLength];
if (!destination) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue malloc failed";
delete value;
return nullptr;
}
if (memcpy_s(destination, dataLength, (char*)data, dataLength) != EOK) {
LOG(ERROR) << "NativeArkWeb CreateJavaScriptValue memcpy failed";
delete[] destination;
delete value;
return nullptr;
}
value->data = (void*)destination;
value->dataLength = dataLength;
value->type = type;
return value;
}
ARKWEB_NDK_EXPORT ArkWeb_ErrorCode OH_NativeArkWeb_LoadData(const char* webTag,
const char* data,
const char* mimeType,
const char* encoding,
const char* baseUrl,
const char* historyUrl) {
std::string base_url_str(baseUrl ? baseUrl : "");
std::string history_url_str(historyUrl ? historyUrl : "");
auto webObjectPtr =
OHOS::NWeb::ArkWebNativeObject::GetWebInstanceByWebTag(webTag);
if (!webObjectPtr) {
LOG(ERROR) << "OH_NativeArkWeb_LoadData: NativeArkWeb object pointer is nullptr";
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
auto nwebSharedPtr = webObjectPtr->GetWebSharedPtr();
if (!nwebSharedPtr) {
LOG(ERROR) << "OH_NativeArkWeb_LoadData: NativeArkWeb get nweb null for webTag: " << webTag;
return ArkWeb_ErrorCode::ARKWEB_INIT_ERROR;
}
if (base_url_str.empty() && history_url_str.empty()) {
nwebSharedPtr->LoadWithData(data, mimeType, encoding);
} else {
nwebSharedPtr->LoadWithDataAndBaseUrl(
baseUrl, data, mimeType, encoding, historyUrl);
}
return ArkWeb_ErrorCode::ARKWEB_SUCCESS;
}
#ifdef __cplusplus
}
#endif